ATtiny2313 + DS18B20 (Arduino IDE)

На ATtiny2313 с использованием цифрового датчика температуры DS18B20 можно собрать простой электронный термометр. В качестве индикатора электронного термометра используется модуль TM1637 который представляет собой 4-х разрядный семисегментный дисплей на базе драйвера TM1637. Дисплей имеет десятичные точки в разрядах.

DS18B20 это датчик температуры с цифровым последовательным интерфейсом 1-Wire.

Основные характеристики датчика:

  • Погрешность измерения не больше 0,5 °С (для температур от -10 °С до +85 °С)
  • Температурный диапазон измерений от -55 С до +125 °С
  • Датчик питается напряжением от 3,3 В до 5 В.
  • Разрешающая способность от 9 до 12 бит
  • Каждый датчик обладает своим уникальным серийным кодом (адрес)
  • Не требуются дополнительные внешние элементы.
  • Можно подключить сразу до 127 датчиков к одной линии связи.
  • Информация передается по протоколу 1-Wire.

Схема подключения

При использовании модуля устанавливать подтягивающий резистор не нужно, он уже установлен на плате модуля.

Схема электронного термометра

Электронный термометр может измерять отрицательную температуру, старший разряд индикатора рассчитан на индикацию знака «-«.

Перед загрузкой скетча рекомендую ознакомится со статьей — ATtiny2313 + Arduino IDE

 
void setup(){}  
 
void loop() {
 if(read_temp()<0){print_time(abs(read_temp()),1,7,1);}
  else{print_time(read_temp(),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;
}

Comments

  1. Здравствуйте. А для ардуино скетч термометра на данном индикаторе можете выложить. В сети полно примеров, но они без минуса. А сам разобраться не могу(

  2. Спасибо, заработало)
    Только у меня дисплей с двоеточием, и показывает как на фото. Где выключить младший разряд, или в идеале сделать знак градуса?

  3. int data3 = t % 10;
    замените на:
    int data3 = 12;

    после строчки:
    case 11: data = 0b01000000;break;
    добавьте строчку:
    case 12: data = 0b00000000;break;
    и составьте из байта 0b00000000 знак градуса

  4. Огромное спасибо!
    Теперь термометр с градусом.
    Подскажите, где встроить задержку секунд на 5, дабы исключить самонагрев датчика от частого опроса.
    Пробовал добавить delayMicroseconds(5000); перед последней фигурной скобкой, разницы в работе не заметил

  5. Ага, я понял свою ошибку. Использовал не тот оператор в не том месте)))
    Теперь работает идеально!
    Я вам премного благодарен!
    Осталось корпус напечатать, и установить на место)
    Ps: как бы научится так в программировании разбираться? С ардуинками давно знаком, а дальше правки чужих кодов не могу(

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

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