Тема: Терморегулятор с тремя реле
Разработка
D2 вход 18b20
Датчик уровня воды замкнут если погружен в воду, датчик перегрева KSD301 замкнут пока температура ниже 95 гр.
Цельсия.
Если на главном экране появится надпись ERR, то сработал датчик уровня воды или датчик перегрева, все реле при этом отключаются.
#include <LiquidCrystal_I2C.h> // http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1
#include <OneWire.h> // http://rcl-radio.ru/wp-content/uploads/2018/07/OneWire.zip
#include <Wire.h>
#include <Encoder.h> // http://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip
#include <EEPROM.h>
#include <MsTimer2.h> // http://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip
LiquidCrystal_I2C lcd(0x27,16,2);
Encoder myEnc(8, 9);// DT, CLK
OneWire ds(2); // Вход датчика 18b20
byte v1[8] = {0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07};
byte v2[8] = {0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00};
byte v3[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F};
byte v4[8] = {0x1F,0x1F,0x00,0x00,0x00,0x00,0x1F,0x1F};
byte v5[8] = {0x1C,0x1C,0x00,0x00,0x00,0x00,0x1C,0x1C};
byte v6[8] = {0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C};
byte v7[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07};
byte v8[8] = {0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00};
byte d1,d2,d3,d4,d5,d6,e1,e2,e3;
int a[6],x,menu,t_ds;
int reg_t1,reg_t2,reg_t3,gis;
unsigned long times,times1,oldPosition = -999,newPosition;
bool w,nagrev1,nagrev2,nagrev3,err;
void setup(){
Wire.begin();lcd.init();lcd.backlight();Serial.begin(9600);
MsTimer2::set(1, to_Timer);MsTimer2::start();
if(EEPROM.read(100)!=0){for(int i=0;i<101;i++){EEPROM.update(i,0);}}// очистка памяти при первом включении
lcd.createChar(1, v1);lcd.createChar(2, v2);lcd.createChar(3, v3);lcd.createChar(4, v4);
lcd.createChar(5, v5);lcd.createChar(6, v6);lcd.createChar(7, v7);lcd.createChar(8, v8);
pinMode(10,INPUT); // кнопка SW ENCODER
pinMode(3,INPUT_PULLUP); // KSD301 (второй вывод KSD301 на GND)
pinMode(4,INPUT_PULLUP); // геркон (второй вывод геркона на GND)
pinMode(5,OUTPUT); // выход реле 1
pinMode(6,OUTPUT); // выход реле 2
pinMode(7,OUTPUT); // выход реле 3
reg_t1 = EEPROM.read(0);reg_t2 = EEPROM.read(1);reg_t3 = EEPROM.read(2);gis = EEPROM.read(3);
digitalWrite(5,LOW);digitalWrite(6,LOW);digitalWrite(7,LOW);
}
void loop(){
///////// BUTTON ////////////////////////
if(digitalRead(10)==LOW){menu++;if(menu>4){menu=0;}times1=millis();w=1;lcd.clear();delay(300);}
///////// READ TEMP /////////////////////////////////////////////
if(millis()-times>1000){times=millis();t_ds = dsRead(0)*10;}// Измерять температуру 1 раз в секунду
///////// LCD BIG ///////////////////////////////////////////////
if(menu==0){
a[0]=t_ds/1000;
a[1]=t_ds/100%10;
a[2]=t_ds/10%10;
a[3]=t_ds%10;
if(t_ds<1000){a[0]=10;}
if(t_ds<100){a[1]=10;}
for(x=0;x<4;x++){
switch(x){
case 0: e1=0;e2=0,e3=1;break;
case 1: e1=2,e2=3,e3=4;break;
case 2: e1=5,e2=6,e3=7;break;
case 3: e1=9,e2=10,e3=11;break;
}digit();}
lcd.setCursor(8,1);lcd.print(".");
lcd.setCursor(12,1);lcd.print(char(223)); lcd.print("C");
if(err==0){
if(nagrev1==1){lcd.setCursor(13,0);lcd.print("H");}else{lcd.setCursor(13,0);lcd.print("L");}
if(nagrev2==1){lcd.setCursor(14,0);lcd.print("H");}else{lcd.setCursor(14,0);lcd.print("L");}
if(nagrev3==1){lcd.setCursor(15,0);lcd.print("H");}else{lcd.setCursor(15,0);lcd.print("L");}
}else{lcd.setCursor(13,0);lcd.print("ERR");}
}
/////// MENU 1 ////////////////////////////////////////////////////////////
if(menu==1){
if(newPosition != oldPosition){oldPosition = newPosition;reg_t1=reg_t1+newPosition;myEnc.write(0);
newPosition=0;times1=millis();;w=1;if(reg_t1>125){reg_t1=125;}if(reg_t1<0){reg_t1=0;}}
a[0]=reg_t1/100;
a[1]=reg_t1/10%10;
a[2]=reg_t1%10;
if(reg_t1<100){a[0]=10;}
if(reg_t1<10){a[1]=10;}
for(x=0;x<3;x++){
switch(x){
case 0: e1=0;e2=1,e3=2;break;
case 1: e1=3,e2=4,e3=5;break;
case 2: e1=6,e2=7,e3=8;break;
}digit();}
lcd.setCursor(12,0);lcd.print("T_1");
lcd.setCursor(9,1);lcd.print(char(223)); lcd.print("C");
}
/////// MENU 2 ////////////////////////////////////////////////////////////
if(menu==2){
if(newPosition != oldPosition){oldPosition = newPosition;reg_t2=reg_t2+newPosition;myEnc.write(0);
newPosition=0;times1=millis();;w=1;if(reg_t2>125){reg_t2=125;}if(reg_t2<0){reg_t2=0;}}
a[0]=reg_t2/100;
a[1]=reg_t2/10%10;
a[2]=reg_t2%10;
if(reg_t2<100){a[0]=10;}
if(reg_t2<10){a[1]=10;}
for(x=0;x<3;x++){
switch(x){
case 0: e1=0;e2=1,e3=2;break;
case 1: e1=3,e2=4,e3=5;break;
case 2: e1=6,e2=7,e3=8;break;
}digit();}
lcd.setCursor(12,0);lcd.print("T_2");
lcd.setCursor(9,1);lcd.print(char(223)); lcd.print("C");
}
/////// MENU 3 ////////////////////////////////////////////////////////////
if(menu==3){
if(newPosition != oldPosition){oldPosition = newPosition;reg_t3=reg_t3+newPosition;myEnc.write(0);
newPosition=0;times1=millis();;w=1;if(reg_t3>125){reg_t3=125;}if(reg_t3<0){reg_t3=0;}}
a[0]=reg_t3/100;
a[1]=reg_t3/10%10;
a[2]=reg_t3%10;
if(reg_t3<100){a[0]=10;}
if(reg_t3<10){a[1]=10;}
for(x=0;x<3;x++){
switch(x){
case 0: e1=0;e2=1,e3=2;break;
case 1: e1=3,e2=4,e3=5;break;
case 2: e1=6,e2=7,e3=8;break;
}digit();}
lcd.setCursor(12,0);lcd.print("T_3");
lcd.setCursor(9,1);lcd.print(char(223)); lcd.print("C");
}
///////////// hysteresis ///////////////////////////////
if(menu==4){
if(newPosition != oldPosition){oldPosition = newPosition;gis=gis+newPosition;myEnc.write(0);
newPosition=0;times1=millis();w=1;if(gis<0){gis=0;}if(gis>30){gis=30;}}
lcd.setCursor(3,0);lcd.print("hysteresis ");
lcd.setCursor(5,1);lcd.print((float)gis/10,1);
lcd.print(char(223)); lcd.print("C");
}
///////// EEPROM ////////////////////////////////////////////////
if(millis()-times1>10000 && w==1){
EEPROM.update(0,reg_t1);EEPROM.update(1,reg_t2);EEPROM.update(2,reg_t3);EEPROM.update(3,gis);
menu=0;w=0;lcd.clear();}
///////////////////////////////////////////////////////////////////
if(digitalRead(4)==LOW&&digitalRead(3)==LOW){
err=0;
if(reg_t1*10 >= t_ds + gis){digitalWrite(5,HIGH);nagrev1=1;}
if(reg_t1*10 <= t_ds - gis){digitalWrite(5,LOW);nagrev1=0;}
if(reg_t2*10 >= t_ds + gis){digitalWrite(6,HIGH);nagrev2=1;}
if(reg_t2*10 <= t_ds - gis){digitalWrite(6,LOW);nagrev2=0;}
if(reg_t3*10 >= t_ds + gis){digitalWrite(7,HIGH);nagrev3=1;}
if(reg_t3*10 <= t_ds - gis){digitalWrite(7,LOW);nagrev3=0;}
}
else{digitalWrite(5,LOW);digitalWrite(6,LOW);digitalWrite(7,LOW);err=1;}
Serial.print(reg_t1*10); Serial.print(" "); Serial.print(t_ds); Serial.print(" "); Serial.print(gis); Serial.print(" "); Serial.println(err);
}// end loop
void digit(){
switch(a[x]){
case 0: d1=1,d2=8,d3=6,d4=1,d5=3,d6=6;break;
case 1: d1=32,d2=2,d3=6,d4=32,d5=32,d6=6;break;
case 2: d1=2,d2=8,d3=6,d4=1,d5=4,d6=5;break;
case 3: d1=2,d2=4,d3=6,d4=7,d5=3,d6=6;break;
case 4: d1=1,d2=3,d3=6,d4=32,d5=32,d6=6;break;
case 5: d1=1,d2=4,d3=5,d4=7,d5=3,d6=6;break;
case 6: d1=1,d2=4,d3=5,d4=1,d5=3,d6=6;break;
case 7: d1=1,d2=8,d3=6,d4=32,d5=32,d6=6;break;
case 8: d1=1,d2=4,d3=6,d4=1,d5=3,d6=6;break;
case 9: d1=1,d2=4,d3=6,d4=7,d5=3,d6=6;break;
case 10:d1=150,d2=150,d3=150,d4=150,d5=150,d6=150;break;
}
if(x>0){lcd.setCursor(e1,0);lcd.write((uint8_t)d1);}
lcd.setCursor(e2,0);lcd.write((uint8_t)d2);lcd.setCursor(e3,0);lcd.write((uint8_t)d3);lcd.setCursor(e1,1);
lcd.write((uint8_t)d4);lcd.setCursor(e2,1);lcd.write((uint8_t)d5);lcd.setCursor(e3,1);lcd.write((uint8_t)d6);}
float dsRead(byte x) {
byte data[2], addr[8][8], kol = 0;
while (ds.search(addr[kol])) { // поиск датчиков, определение адреса и кол-ва датчиков
kol++;
}
ds.reset_search(); // Сброс поиска датчика
ds.reset(); // Инициализация, выполняется сброс шины
ds.select(addr[x]); // Обращение к датчику по адресу
ds.write(0x44, 0); // Измерение температуры с переносом данных в память
ds.reset(); // Инициализация, выполняется сброс шины
ds.select(addr[x]); // Обращение к датчику по адресу
ds.write(0xBE); // Обращение памяти
data[0] = ds.read();// Чтение памяти byte low
data[1] = ds.read();// Чтение памяти byte high
float value = ((data[1] << 8) | data[0]) / 16.0; return (float)value; // Расчет температуры и вывод
}
void to_Timer(){newPosition = myEnc.read()/4;}