svm
10.Январь.2023 12:30:14
1
Понадобился термометр до 500 градусов. Ничего лучше термопары и MAX6675 не нашел. Но габариты модуля и ардуинки не устраивали. Решил делать на Attiny13. Работа с шиной I2C, взята с форума. //ATtiny13A 101 применение | Аппаратная платформа Arduino Скетч занимает 444 Байта. Получился компактный термометр. В скетче есть ссылки на исходные коды. Если кому нужны более широкие возможности, можно посмотреть первоисточники. Для пояснений выложил небольшой ролик:
https://youtu.be/8VEJq8mRu34
Схема:
Скетч:
#define _NOP() asm volatile("nop")
//массив знакогенератора 7 сегментного индикатора
byte simv[11]={
B00111111, //0
B00000110, //1
B01011011, //2 cоответствие разрядов и сегментов
B01001111, //3
B01100110, //4 _1_
B01101101, //5 6 | | 2
B01111101, //6 |_7_|
B00000111, //7 5 | | 3
B01111111, //8 |_4_|
B01101111, //9
B00000000, //пустота
};
// delay() для тиньки и свой нормальный, а delayMicroseconds() дурной
//а вот глобального такого дефайна может и не быть, как ни странно, так для страховки завел
//#define F_CPU 4800000UL
#define LOOP_CYCLES 8
#define us(num) (num/(LOOP_CYCLES*(1/(F_CPU/1000000.0))))
inline __attribute__((gnu_inline)) void asm_delay(uint16_t delay){
uint16_t u=us(delay);
do _NOP(); while(delay--);
}
#define wdelay_us(x) asm_delay(us(x))
#define wdelay(x) delay(x)
/*****************************************************/
//дальше мелкий вариант i2c на любых ногах
#define IICR 1
#define IICW 0
#define I2CDelay() wdelay_us(4) // на 100КГц примерно по 4 мкс нужно держать уровни SCL
#define miso 0 // - со скоростью сами экспериментируйте
#define cs 1
#define clk 2
#define SDA_Pin 3
#define SCL_Pin 4
#define miso_In() (PINB & 0B00000001)
#define SDA_In() (PINB & 0B00001000)
#define SCL_In() (PINB & 0B00010000)
inline void SDA_Hi() { PORTB |= 0B00001000; DDRB &= 0B11110111;}
inline void SDA_Lo() { PORTB &= 0B11110111; DDRB |= 0B00001000;}
inline void SCL_Hi() { PORTB |= 0B00010000; DDRB &= 0B11101111;}
inline void SCL_Lo() { PORTB &= 0B11101111; DDRB |= 0B00010000;}
void I2CInit (void)
{
SDA_Hi();
SCL_Hi();
}
void I2CStart (void)
{
SCL_Hi();
while (!SCL_In());
I2CDelay();
SDA_Lo();
SCL_Lo();
}
void I2CStop (void)
{
I2CDelay();
SCL_Hi();
I2CDelay();
SDA_Hi();
I2CDelay();
}
boolean I2CWrite(byte b)
{
byte i = 1<<7;
boolean ack=0;
while(i)
{
I2CDelay();
if (b & i) SDA_Hi(); else SDA_Lo();
I2CDelay();
SCL_Hi();
I2CDelay();
SCL_Lo();
i>>=1;
}
SDA_Hi();
I2CDelay();
SCL_Hi();
if ( SDA_In()==0 ) ack = 1;
I2CDelay();
SCL_Lo();
SDA_Lo();
return ack;
}
byte I2CRead(boolean ack)
{
byte i=8;
byte b=0;
while(i--)
{
I2CDelay();
SCL_Hi();
if (SDA_In()) b |= 1;
b <<= 1;
I2CDelay();
SCL_Lo();
}
if (ack) SDA_Lo();
else SDA_Hi();
I2CDelay();
SCL_Hi();
I2CDelay();
SCL_Lo();
SDA_Lo();
return b;
}
/*************************************/
void setup() {
// Инициализация дисплея TM1650,Подробнее https://arduino.ru/forum/programmirovanie/kontroller-led-i-klaviatury-fd650v-kak-im-upravlyat#comment-232263
I2CStart();
I2CWrite(0x27<<1);
I2CWrite(B00010001);
I2CStop();
wdelay(500);
}
void loop() {
int t= spiRead();//Читаем данные из модуля термопары MAX6675
byte ks=0;
byte kd=0;
while(t>=100){t-=100;ks++;} ;
while(t>=10){t-=10;kd++;}
//************ выводим число на индикатор *******************
if (ks==0)ks=10;
//СОТНИ
I2CStart();
I2CWrite(0x34<<1); //выставляем номер разряда индикатора
I2CWrite(simv[ks]); //пишем в него символ
I2CStop();
//ДЕСЯТКИ
I2CStart();
I2CWrite(0x35<<1);
I2CWrite(simv[kd]);
I2CStop();
//ЕДИНИЦЫ
I2CStart();
I2CWrite(0x36<<1);
I2CWrite(simv[t]);
I2CStop();
//************ выводим на индикатор знак градуса *******************
I2CStart();
I2CWrite(0x37<<1);
I2CWrite(B01100011);
I2CStop ();
wdelay(500);
}
// ******************** Чтение данных из модуля термопары MAX6675 ******************************
//https://arduinodiy.wordpress.com/2019/12/06/using-a-max6675-temperature-sensor-without-a-library/
int spiRead() {
DDRB = DDRB | 0B00000110;
int rawTmp = 0;
PORTB &= ~(1<<cs); // cs,LOW
wdelay(2); // задержка 2 миллисекунды
PORTB |= (1<<cs); // cs,HIGH
wdelay(200); // задержка 200 миллисекунд
PORTB &= ~(1<<cs); // cs,LOW Опускаем CS для старта преобразования
//Считываем 11 из 14 бит из MAX6675 (больше мне не нужно)и сохраняем в rawTmp
for (int i=10; i>=0; i--) {
PORTB |= (1<<clk); //clk,HIGH
byte r=0;if(PINB & (1<<miso))r=1;//Чтение пина MISO
rawTmp +=r << i;
PORTB &= ~(1<<clk); // clk,LOW
}
//rawTmp=327;
return rawTmp;
}
2 лайка
Ой! Какой знакомы код для И2Ц! Нужно роялти пЫвом собирать! ;))
Шутка. На самом деле я рад, что моя поделка приносит пользу. Сам я давно про нее забыл, так как Тинька13 выпала из сферы моих интересов.
svm
10.Январь.2023 12:47:09
4
Сверху скетча, есть ссылка на Ваш код. А насчет тиньки, просто у меня десяток осталось. А что-то более солидное на такой девайс ставить религия не позволяет. Да и конструкция минималистичная получилась.
b707
10.Январь.2023 12:54:38
5
где?
Или вы про это:
не охотв придираться, но раз уж зашел разговор, то этого недостаточно. По-хорошему полагается вставлять ссылку на конкретную ветку, откуда код и с указанием автора, если это не коллективное творчество.
Например так, как у вас сделано для кода термопары:
Хотя если я сослепу не разглядел и такая ссылка есть - прошу прощения.
svm
10.Январь.2023 13:03:22
6
Все верно, в скетче ссылки нет. Хотя её видно при редактировании поста и при скачивании или просто копировании. Какой-то глюк. Исправился, вставил в текст сообщения. Спасибо за код и критику.
nik182
10.Январь.2023 13:28:54
7
А что такое ТМ650? Гугл ничего не даёт понятного на эти символы .
svm
10.Январь.2023 13:32:54
8
Ошибка. TM1650, исправил.
svm:
TM1650
А ссылка на индикатор AliExpress есть? чтоб купить.
ua6em
10.Январь.2023 14:01:55
10
Еще бы и тэг поправить с I2S на I2C…чтобы поисковики отрабатывали правильно
svm
10.Январь.2023 14:06:17
11
Микросхемы есть, а модулей не видел. Я когда-то помогал одной конторе с ремонтом приставок “Элект” и у меня скопилось несколько десятков, не подлежащих ремонту. Из них болгаркой и вырезаю микросхему с индикатором. В принципе там любой аналогичный модуль с I2C можно использовать, только адреса поменять. Или купить отдельную микросхему за 16 руб. и припаять к ней 4 индикатора. Бонусом будет еще и клавиатура. Кажется 8х8, и тоже по I2C.
svm
10.Январь.2023 14:07:55
12
А это где? Я на новом форуме пишу в первый раз. Еще не адаптировался.
svm
10.Январь.2023 14:20:25
14
I2C не дает вставить. Пишет нет совпадений. Предлагает только I2s, но удалить дал.
svm
11.Январь.2023 10:21:41
17
Ввиду того, что у многих проблемы с TM1650, сделал вариант для TM1637. Схема та-же. Должна работать и на тиньке13 и на UNO и подобных. На тиньке занимает 432 байта на УНО 574. Проверить не смог т.к. нет MAX6675, а подпаиваться к мелкой платке программатором лень.
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#define miso PB0 //MAX6675
#define cs PB1 //--
#define clk PB2 //--
//#define clk PB3 //TM1637
//#define DIO PB4 //--
#define miso_In() (PINB & 0B00000001)
#define DIO_H() (PORTB |= _BV(PB4))
#define DIO_L() (PORTB &= ~_BV(PB4))
#define DIO_OUT() (DDRB |= _BV(PB4))
#define DIO_IN() (DDRB &= ~_BV(PB4))
#define DIO_RD() (((PINB & _BV(PB4)) > 0) ? 1 : 0)
#define CLK_H() (PORTB |= _BV(PB3))
#define CLK_L() (PORTB &= ~_BV(PB3))
PROGMEM const uint8_t _digit2segments[] =
{
0x3F, // 0
0x06, // 1
0x5B, // 2
0x4F, // 3
0x66, // 4
0x6D, // 5
0x7D, // 6
0x07, // 7
0x7F, // 8
0x6F, // 9
0x00, // пусто
0x63 // градус
};
//********************************************************************************************************
int main(void) {
/* setup */
// Serial.begin(9600);
TM1637_init();
_delay_ms(300);
//********************************************************************************************************
while(1) {
int t= spiRead();//Читаем данные из модуля термопары MAX6675
byte ks=0;
byte kd=0;
while(t>=100){t-=100;ks++;} ;
while(t>=10){t-=10;kd++;}
//************ выводим число на индикатор *******************
if (ks==0)ks=10;
//СОТНИ
TM1637_dig (0, ks);
//ДЕСЯТКИ
TM1637_dig (1, kd);
//ЕДИНИЦЫ
TM1637_dig (2, t);
//знак градуса
TM1637_dig (3, 11);//градус
_delay_ms(500);
}
}
// ******************** Чтение данных из модуля термопары MAX6675 ******************************
//https://arduinodiy.wordpress.com/2019/12/06/using-a-max6675-temperature-sensor-without-a-library/
int spiRead() {
DDRB = DDRB | 0B00000110;
int rawTmp = 0;
PORTB &= ~(1<<cs); // cs,LOW
_delay_ms(2); // задержка 2 миллисекунды
PORTB |= (1<<cs); // cs,HIGH
_delay_ms(200); // задержка 200 миллисекунд
PORTB &= ~(1<<cs); // cs,LOW Опускаем CS для старта преобразования
//Считываем 11 из 14 бит из MAX6675 (больше мне не нужно)и сохраняем в rawTmp
for (int i=10; i>=0; i--) {
PORTB |= (1<<clk); //clk,HIGH
byte r=0;if(PINB & (1<<miso))r=1;//Чтение пина MISO
rawTmp +=r << i;
PORTB &= ~(1<<clk); // clk,LOW
}
//rawTmp=24;
return rawTmp;
}
//***********************************************************************************
void
TM1637_dig(const uint8_t position, const uint8_t digit)
{ uint8_t segments = (digit < 12 ? pgm_read_byte_near((uint8_t *)&_digit2segments + digit) : 0x00);
TM1637_display_segments(position, segments);}
void
TM1637_display_segments(const uint8_t position, const uint8_t segments)
{ send_cmd(0x40 | 0x04);
TM1637_start();
TM1637_write_byte(0xC0 | (position & (4 - 1)));
TM1637_write_byte(segments);
TM1637_stop();}
// Serial.println((0x80 | _config),HEX);
uint8_t TM1637_write_byte(uint8_t value)
{ uint8_t i, ack;
for (i = 0; i < 8; ++i, value >>= 1) {
CLK_L(); _delay_us(5);
if (value & 0x01) {DIO_H();}
else {DIO_L();}
CLK_H(); _delay_us(5);}
CLK_L();
DIO_IN();
DIO_H(); _delay_us(5);
ack = DIO_RD();
if (ack) { DIO_OUT();DIO_L();} _delay_us(5);
CLK_H(); _delay_us(5);
CLK_L(); _delay_us(5);
DIO_OUT();
return ack;}
void send_cmd(const uint8_t value)
{ TM1637_start(); TM1637_write_byte(value); TM1637_stop();}
void TM1637_start()
{ DIO_H();CLK_H(); _delay_us(5); DIO_L();}
void TM1637_stop()
{ CLK_L(); _delay_us(5); DIO_L(); _delay_us(5); CLK_H(); _delay_us(5); DIO_H();}
void
TM1637_init()
{ DDRB |= (_BV(PB4)|_BV(PB3));
PORTB &= ~(_BV(PB4)|_BV(PB3));
send_cmd(0x8B);}
1 лайк
ua6em
11.Январь.2023 10:43:43
18
видимо так надо (строка 142)
svm
11.Январь.2023 11:10:38
19
Косяк при вставке, пардон. Возможность проверить есть? Если раскомменгировать 89 строку, то и на тиньке и на уно показывает верно, а вот работает-ли МАКС неясно.
ua6em
11.Январь.2023 11:41:25
20
теоретически да, но только на тиньке 85, но это не сегодня
svm
14.Январь.2023 16:26:23
21
Сегодня закончил сборку цифровой станции для жал T12. И проверил этим термометром соответствие показаний на пяти жалах с Али. Разница показаний от 5 до 40 градусов. Правда цена жал около 100 руб. За это можно многое простить. Видео мини паяльной станции: https://youtu.be/uiCsJtg9zPE