Ранее на странице — http://rcl-radio.ru/?p=94173 рассматривался вопрос создания простого цифрового термометра на базе ATtiny2313 с использованием датчика DS18B20. На этой странице аналогичный проект, но с добавлением регулятора температуры.
В качестве индикатора терморегулятора используется модуль TM1637 который представляет собой 4-х разрядный семисегментный дисплей на базе драйвера TM1637. Дисплей имеет десятичные точки в разрядах.
DS18B20 — датчик температуры с цифровым последовательным интерфейсом 1-Wire.
Основные характеристики датчика:
- Погрешность измерения не больше 0,5 °С (для температур от -10 °С до +85 °С)
- Температурный диапазон измерений от -55 С до +125 °С
- Датчик питается напряжением от 3,3 В до 5 В.
- Разрешающая способность от 9 до 12 бит
- Каждый датчик обладает своим уникальным серийным кодом (адрес)
- Не требуются дополнительные внешние элементы.
- Можно подключить сразу до 127 датчиков к одной линии связи.
- Информация передается по протоколу 1-Wire.
Схема подключения
При использовании модуля устанавливать подтягивающий резистор не нужно, он уже установлен на плате модуля.
Схема терморегулятора
Управление терморегулятором осуществляется при помощи 3-х кнопок, при нажатии кнопки SET на индикаторе отображается установленная температура регулирования, а при удержании кнопки SET и последующем нажатии кнопок REG++ или REG— можно изменить температуру регулирования, шаг изменения температуры регулирования 0,5 °С. Температуру регулирования можно менять в диапазоне от 0 до 125 °С. Так же по умолчанию в терморегуляторе применен гистерезис, который равен 0,5 °С. Для управления нагревательным элементом служит выход PB3. Установленная температура регулирования сохраняется в энергонезависимой памяти.
Перед загрузкой скетча рекомендую ознакомится со статьей — ATtiny2313 + Arduino IDE
int t_reg,t_dig; void setup(){ DDRD &= ~(1 << 2) | (1 << 3) | (1 << 4); PORTD |= (1 << 2) | (1 << 3) | (1 << 4); DDRB |= (1 << 3); t_reg = EEPROM_read(0)*10 + EEPROM_read(1); } void loop() { if(((PIND >> 2) & 1) == 0 && ((PIND >> 4) & 1) == 0){t_reg+=5; if(t_reg>1250){t_reg = 1250;} eeprom_w();} if(((PIND >> 3) & 1) == 0 && ((PIND >> 4) & 1) == 0){t_reg-=5; if(t_reg<0){t_reg = 0;} eeprom_w();} t_dig = read_temp(); if(t_reg >= t_dig + 5){PORTB |= (1 << 3);} if(t_reg <= t_dig - 5){PORTB &= ~(1 << 3);} if(((PIND >> 4) & 1) == 1){if(t_dig<0){print_time(abs(t_dig),1,7,1);}else{print_time(t_dig,1,7,0);}} if(((PIND >> 4) & 1) == 0){print_time(t_reg,1,7,0);} } void tm_dec(byte dig){ for(int i = 0; i < 8; i++) { DDRB |= (1 << 0);del(); if (dig & 0x01) DDRB &= ~(1 << 1); else DDRB |= (1 << 1);del(); DDRB &= ~(1 << 0);del(); dig = dig >> 1; } DDRB |= (1 << 0); DDRB &= ~(1 << 1);del(); DDRB &= ~(1 << 0);del(); if (((PINB >> 1) & 1) == 0) DDRB |= (1 << 1);del(); DDRB |= (1 << 0);del(); } void tm_stop(){ DDRB |= (1 << 1);del(); DDRB &= ~(1 << 0);del(); DDRB &= ~(1 << 1);del(); } void tm_start(){ DDRB |= (1 << 1);del(); } void print_time(int t, byte pd_t, int br,bool mn){ tm_start();tm_dec(0b10001000 + br);//tm_stop();tm_start(); tm_dec(0x40);tm_stop();tm_start(); int data0; if(mn==1){data0 = 11;} else{data0 = 10;} int data1 = t / 100 % 10; int data2 = t / 10 % 10; int data3 = t % 10; for(byte n = 0; n < 4; n++){ int data; switch(n){ case 0: data = data0;break; case 1: data = data1;break; case 2: data = data2;break; case 3: data = data3;break; } switch(data){ // XGFEDCBA case 0: data = 0b00111111;break; // 0 case 1: data = 0b00000110;break; // 1 case 2: data = 0b01011011;break; // 2 case 3: data = 0b01001111;break; // 3 case 4: data = 0b01100110;break; // 4 case 5: data = 0b01101101;break; // 5 case 6: data = 0b01111101;break; // 6 case 7: data = 0b00000111;break; // 7 case 8: data = 0b01111111;break; // 8 case 9: data = 0b01101111;break; // 9 case 10: data = 0b00000000;break; // пусто case 11: data = 0b01000000;break; // - } if(n == 0){data0 = data;} if(n == 1){data1 = data;} if(n == 2){data2 = data;} if(n == 3){data3 = data;} } switch(pd_t){ case 1 : data2 = data2+0b10000000;break; case 2 : data1 = data1+0b10000000;break; case 3 : data0 = data0+0b10000000;break; } tm_dec(0xC0);tm_dec(data0);tm_dec(data1);tm_dec(data2);tm_dec(data3);tm_stop(); } void del(){delayMicroseconds(200);} // reset uint8_t therm_reset(){ uint8_t i; PORTB &= ~(1 << 2); DDRB |= (1 << 2); delayMicroseconds(480); DDRB &= ~(1 << 2); delayMicroseconds(60); i=((PINB >> 2) & 1); delayMicroseconds(420); return i; } // write bit void therm_write_bit(uint8_t bit){ PORTB &= ~(1 << 2); DDRB |= (1 << PB2); delayMicroseconds(1); if(bit) DDRB &= ~(1 << PB2); delayMicroseconds(60); DDRB &= ~(1 << PB2); } // read bit uint8_t therm_read_bit(void){ uint8_t bit=0; PORTB &= ~(1 << PB2); DDRB |= (1 << PB2); delayMicroseconds(1); DDRB &= ~(1 << PB2); delayMicroseconds(14); if(PINB & (1 << 2)) bit=1; delayMicroseconds(45); return bit; } // read byte uint8_t therm_read_byte(void){ uint8_t i=8, n=0; while(i--){n>>=1;n|=(therm_read_bit()<<7);} return n; } // write byte void therm_write_byte(uint8_t byte){ uint8_t i=8; while(i--){therm_write_bit(byte&1);byte >>= 1; } } // read temp int read_temp(){ uint8_t temperature[2]; float temper; therm_reset(); therm_write_byte(0xCC); therm_write_byte(0x44); while(!therm_read_bit()); therm_reset(); therm_write_byte(0xCC); therm_write_byte(0xBE); temperature[0]=therm_read_byte(); temperature[1]=therm_read_byte(); therm_reset(); temper = (temperature[1] << 8 | temperature[0])/1.60; return (int)temper; } unsigned char EEPROM_read(unsigned int uiAddress){ while(EECR & (1<<EEPE)); EEAR = uiAddress; EECR |= (1<<EERE); return EEDR; } void EEPROM_write(unsigned int uiAddress, unsigned char ucData){ while(EECR & (1<<EEPE)); EEAR = uiAddress; EEDR = ucData; EECR |= (1<<EEMPE); EECR |= (1<<EEPE); } void eeprom_w(){EEPROM_write(0,t_reg/10);EEPROM_write(1,t_reg%10);}
Скетч использует 2006 байт (97%) памяти устройства. Всего доступно 2048 байт.
Глобальные переменные используют 13 байт (10%) динамической памяти, оставляя 115 байт для локальных переменных. Максимум: 128 байтArduino IDE 1.8.9 | Плата для прошивки версии 1.2.5 (выбрать в менеджере плат)