ATtiny2313 + DS18B20 терморегулятор (Arduino IDE)

Ранее на странице — 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 (выбрать в менеджере плат)

Добавить комментарий

Войти с помощью: