Терморегулятор DS18B20 + TM1637 + энкодер ky-040 (Arduino)

На рисунке показана схема простого и очень удобного в использовании терморегулятора, в качестве датчика используется DS18B20, а управление регулятором осуществляется при помощи энкодера ky-040.

Интегральный датчик температуры DS18B20 имеет диапазон измерения температуры от -55 до + 125 °C, показания температуры выводятся на четырех разрядный семисегментный индикатор на базе драйвера TM1637 (модуль TM1637), вращая ручку энкодера можно изменять температуру регулирования, так же используется гистерезис в 0,5 °C, которой можно изменить в скетче.

В режиме измерения температуры на индикаторе будут показания температуры, для изменения температуры регулирования достаточно начать вращать ручку энкодера, при этом будет высвечиваться показания температуры регулирования, если не вращать ручку энкодера в течении 2 секунд, снова появятся показания температуры. Для сохранения в энергонезависимую память температуры регулирования необходимо нажать кнопку энкодера, при сохранении данных на индикаторе появится надпись «S_rG».

Если Вы используете в качестве датчика температуры модуль DS18B20, то резистор R2 из схемы необходимо исключить. Цифровой выход 13 используется для управления нагрузкой.

#include <OneWire.h>
#include <TM1637Display.h>
#include <EEPROM.h>//#include <EEPROMex.h>
#include <DallasTemperature.h>
#include <Encoder.h>
#include <MsTimer2.h>
 
TM1637Display display(2, 3);// CLK,DIO
Encoder myEnc(5, 4);// CLK, DT
OneWire oneWire(A1);// вход датчика 18b20
DallasTemperature t(&oneWire);
 
int oldPosition  = -999,newPosition,rom,k;
unsigned long time;
byte minus_reg,reg;
float gis = 0.5;// гистерезис
uint8_t data[]{0,0,0,0};
uint8_t data1[]{0x6d,0x08,0x50,0x3d};
 
void setup(){
  t.begin(); 
  t.setResolution(11);//11 бит 
  pinMode(10,INPUT);  // кнопка энкодера
  pinMode(13,OUTPUT); // выход для управления нагрузкой
  rom = EEPROM.read(0); 
  minus_reg = EEPROM.read(1);
  if(minus_reg==1){rom=rom-2*rom;}
  display.setBrightness(0);// яркость TM1637 0-7
  MsTimer2::set(3, to_Timer);MsTimer2::start();
}
 
void loop(){
 
  if (newPosition != oldPosition) {
    oldPosition = newPosition;
    time=millis();
    reg=1;
  }
  else if(millis()-time>2000){
    t.requestTemperatures();
    time=millis();
    reg=0;
  }
 
  if(digitalRead(10)==LOW){
    EEPROM.update(0,abs(newPosition));
    EEPROM.update(1,minus_reg);
    display.setSegments(data1); 
    delay(1000);
  }
 
  if(newPosition<0){minus_reg=1;}
  else{minus_reg=0;}
  if(newPosition<-55){newPosition=-55;}
  if(newPosition>125){newPosition=125;}
 
  if(reg==1){k=newPosition;}
  else{k = t.getTempCByIndex(0);}
  if(reg==1){data[0]=0x50;}
  else{data[0] = 0x78;}// r / t
  if(k > 99){data[1] = display.encodeDigit((k/100)%10);}
  else{data[1] = 0x00;}
  if(k < 0){k=abs(k);data[1] = 0x40;}
  data[2] =  display.encodeDigit((k/10)%10);
  data[3] =  display.encodeDigit((k%10)%10);
  display.setSegments(data);
 
   if(newPosition >= t.getTempCByIndex(0) + gis){digitalWrite(13,HIGH);}
   if(newPosition <= t.getTempCByIndex(0) - gis){digitalWrite(13,LOW);}
}
 
void to_Timer(){newPosition = myEnc.read()/4+rom;}

DallasTemperature.h

OneWire.h

Encoder.h

TM1637Display.h

MsTimer2.zip

Comments

    1. При регулировке температуры регулировании ее значение сохраняется в энергонезависимой памяти и при подачи питания считывается с нее.

  1. У меня также некорректно работало без подтягивающего резистора 10к на кнопке энкодера( сразу не заметил что стоит только 2).В целом неплохой проект, спасибо. Подскажите можно ли что то сделать что бы при переходе через граничную температуру -55 или 125 при последующей регулировке отсчет начинался с температуры уставки, например если после 125 покрутить энкодер на 2 оборота, то для того чтобы понизить например до 124 — нужно в обратную сторону прокрутить все тех же 2 оборота, на индикаторе при этом будет показывать 125

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

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