//https://create.arduino.cc/projecthub/electropeak/using-1602-lcd-keypad-shield-w-arduino-w-examples-e02d95
#include <Arduino.h>
#include <Adafruit_Sensor.h>
#include <LiquidCrystal.h>
#include <DHT.h>
#include <Streaming.h>
#define ALLAPOT Serial<<" >T(3) : "<<termoszJel<<" CS(7) : " <<digitalRead(CSIGA)<< " VENTI : \n"
const uint8_t PARAM_SZAM = 16; // paraméterek száma
const uint8_t TERMOSZT = 2; // láb a termosztáthoz
const uint32_t SOHA =4294967295; // végtelen idő. Ha egy időpont nem érdekes, ezt kapja,
#define SOHA 4294967295 // végtelen idő. Ha egy időpont nem érdekes, ezt kapja,
#define VENTI_KESES 400 // Ne csigával egyszerre induljon
#define CSIGABE 1 //A csiga erre indul el [0/1]
#define CSIGAKI !CSIGABE //A CSIGABE ellentettje
#define TERMOSZBE 0 // A termosz fűtést kér
#define TERMOSZKI !TERMOSZBE // Termosz kikapcsolást kér
uint8_t termoszJel ; //A Termoszláb értéke (0/1);
uint8_t termoszMult =255; //A Termoszláb előző értéke ;
uint32_t ventiGyorsLesz =0; //be/kikapcsolási időpontok (millis)
uint32_t ventiLassuLesz =SOHA;
uint32_t csigaBeLesz =0; //időpont Millis()
uint32_t csigaKiLesz =0; //Időpont Millis
uint32_t most; //aktuális idő (millis)
uint32_t csigamegy; //Menetidő TATRTAMA [ms]
uint32_t csigaszunet;
String melegit_e;
uint32_t kov_Olvas=0; // legközelebbi adatolvasási időpont
volatile uint32_t nyomva =SOHA; //mikor nyomták meg a gombot?
bool kepzar=false;
//LCD lábak
const int pin_RS = 8;
const int pin_EN = 9;
const int pin_d4 = 4;
const int pin_d5 = 5;
const int pin_d6 = 6;
const int pin_d7 = 7;
const int pin_BL = 10;
LiquidCrystal lcd( pin_RS, pin_EN, pin_d4, pin_d5, pin_d6, pin_d7);
enum gombok {ENTER,LEFT,DOWN,UP,RIGHT};
enum szint {FOKEP,MENU,ALLITO};
szint menu_Szint=FOKEP;
typedef struct {
uint8_t oszl; //oszlop a főképen
uint8_t sor; //sor a főképen
uint8_t lab; //Mikrokontroller láb száma
int16_t oszto; //kiírás nagyságrendje
uint8_t irhato_e; //fix-vagy írható?
char txt[17]; //megnevezés
char egyseg[4]; //Mértékegység
} param;
// 12334567890123456 KezdőképAlapállapot
//╔════════════════╗ Jelmagyarázat:
//║79°45%12s 40 198║ |előre:79°|ventifűt:45%pwm||adagszünet_Füt:12|adagidő:0,4 mp|Kémény:198°
//║61 28%30 65 -10║ |visszaág:61°|VEntitart28%pwm||adagszünet_tart:30 Szivattyú be:65°|Külső:-10° |
//╚════════════════╝
char kepsor[4][17]= //Az LCD kép mintája
{ "00 00%00s 00\"000", //Sor0
"00 00 00 00 000", //Sor1
"Ld 000 SzivKi 00", //Sor2 Egyelőre nincs használva
"000 p-re_megy00", //Sor3
};
// x, érték, oszl, sor, lab,oszto, irhato, txt , egység
const param X[PARAM_SZAM]= // 0123456789012345
{ {/* 78,*/ 4, 0, 10, 1, 1, "PWM % futes:" ,"%" },//PWM% Fűtéskor
{/* 35,*/ 4, 1, 10, 1, 1, "PWM % Tuz.tart:","%" },//PWM% Tűztartáskor
{/*11000,*/ 7, 0, 13, 1000, 1, "Cs.szunet fut:" ,"ms"},//msec csigaszünet Fűtéskor
{/*30000,*/ 7, 1, 13, 1000, 1, "Cs.szunet tart:","ms"},//msec csigaszünet tűztartáskor
{/* 450,*/ 11, 0, 13, 10, 1, "Csigamenetido:" ,"ms"},//msec Csiga menetidő
{/* 65,*/ 11, 1, 12, 1, 1, "Sziv bekapcs :" ,"C" },//C° Szivattyú bekapcsolási hő.
{/* 55,*/ 12, 2, 12, 1, 1, "Sziv kikapcs :" ,"C" },//C° Sziv kikapcsolási hőmérséklet
{/* 65,*/ 2, 3, 12, 1, 1, "Tisztitaskoz" ,"min"},//perc Időköz nagyadag tisztításkor
{/* 65,*/ 15, 3, 12, 1, 1, "Tisztitas ido" ,"sec"},//ms Menetidő nagyadag tisztításkor
{/* 90,*/ 0, 0, A3, 1, 1, "Vesz homers." ,"C" },//C° Túlmelegedési küszöb
{/* 76,*/ 1, 0, A3, 1, 0, "" ,"C" },//c° Előremenő víz
{/* 53,*/ 1, 1, A4, 1, 0, "" ,"C" },//C° Viszzajövő
{/* 198,*/ 15, 0, A2, 1, 0, "" ,"C" },//C° Kémény hőmérséklet
{/* 125,*/ 15, 1, A5, 1, 0, "Lambda" ,"Lam"},// Lambda érték
{/* 2,*/ 15, 2, A1, 1, 0, "" ,"C" },//C° Külső hőmérséklet
{/* 1,*/ 3, 0, 2, 1, 0, "*" ,"" },//B/K Termosztat
};
int16_t Y[]={78,35,11000,30000,450,65,55,65,65,90,76,53,198,125,-2};
enum param_t {venti_Fut, venti_Tart, csigaSz_Fut, csigaSz_Tart, csiga_Megy, t_SzivBe, \
t_SzivKi, tiszt_Koz, tiszt_Tartam, t_Vesz, t_Elore , t_Vissza, t_Kemeny, Lambda,\
t_Kinti, termosztat };
/*void xprintx(char* cel, const int32_t valtozo, uint8_t m )
{ uint8_t x=0;
if ( valtozo < 0) x++;
if (abs(valtozo)<10) ;
else (abs(valtozo)<100) ? x++ : x +=2;
memccopy(&cel,&puff,x);
lcd.setCursor(oszl,sor);
lcd.print(valtozo);
}
void printx(int16_t valtozo, uint8_t oszl, uint8_t sor )
{ if (valtozo<0) oszl--;
if (abs(valtozo)<10) ;
else (abs(valtozo)<100) ? oszl-- : oszl -=2;
lcd.setCursor(oszl,sor);
lcd.print(valtozo);
}
*/
void beilleszt(const uint8_t i)
{ char tar[]=" ";
itoa(Y[i]/X[i].oszto, tar, DEC);
uint8_t hossz=strlen(tar);
memcpy(&kepsor[X[i].sor][X[i].oszl-hossz+1], tar, hossz);
}
void fkep()
{ if (menu_Szint!=FOKEP) return;
for( uint8_t i=venti_Fut ; i<t_Kinti ; i++ ) beilleszt(i);
lcd.setCursor(0, 0); lcd.print(kepsor[0]);
lcd.setCursor(0, 1); lcd.print(kepsor[1]);
}
void nyomas(void)
{ nyomva=millis()+50;
}
void akcio_Menu(gombok gomb)
{ static uint8_t aktiv_Sor;
switch (menu_Szint)
{ case FOKEP: //////////////////// Főkép
aktiv_Sor=0;
if (gomb==ENTER || gomb==RIGHT)
{ menu_Szint=MENU;
lcd.clear();
lcd.noCursor();
lcd.print(X[venti_Fut].txt);
lcd.setCursor(0,1);
lcd << Y[venti_Fut] << " " << X[venti_Fut].egyseg<<" ";
}
break;
case MENU: ////////////////// Menü
switch (gomb)
{ case RIGHT:
case ENTER:
menu_Szint=ALLITO;
lcd.setCursor(1,1);lcd.cursor(); lcd.blink();
break;
case LEFT:
menu_Szint=FOKEP;
fkep();
break;
case UP:
if (aktiv_Sor>0)
{ aktiv_Sor--;
lcd.clear();
lcd.print(X[aktiv_Sor].txt);
lcd.setCursor(0,1);lcd.noBlink();
lcd<<Y[aktiv_Sor]<<" "<<X[aktiv_Sor].egyseg<<" ";
}
break;
case DOWN:
if (aktiv_Sor<t_Vesz)
{ aktiv_Sor++;
lcd.clear();
lcd.print(X[aktiv_Sor].txt);
lcd.setCursor(0,1);lcd.noBlink();
lcd<<(Y[aktiv_Sor])<<" "<<X[aktiv_Sor].egyseg<<" ";
}
break;
}
break;
case ALLITO:
int8_t elojel=1;
switch (gomb)
{ case RIGHT:
case LEFT:
case ENTER:
menu_Szint=MENU;
lcd.noBlink();lcd.noCursor();
break;
case DOWN:
elojel=-1;
case UP:
(aktiv_Sor!=csiga_Megy) ? Y[aktiv_Sor] += X[aktiv_Sor].oszto*elojel : Y[aktiv_Sor] += 25*elojel ;
lcd.setCursor(0,1);
lcd<<(Y[aktiv_Sor]/X[aktiv_Sor].oszto)<<" "<<X[aktiv_Sor].egyseg<<" ";
lcd.setCursor(1,1);
break;
}
break;
}
}
gombok gomb_Olvas()
{ uint16_t x = analogRead (A0);
if (x < 160) return ENTER;
else if (x < 400) return LEFT;
else if (x < 650) return DOWN;
else if (x < 850) return UP;
return RIGHT;
}
int16_t ntc_Olvas(uint8_t lab){ float x=(float)(1/(log(1 / (1023. / analogRead(lab) - 1)) / 3950 + 1.0 / 298.15) - 273.15); return (int16_t)round(x);}
param_t jelolvas(uint32_t most)
{ const uint32_t olvasas_Koz=1000; //[s] olvasas közti idő
if (kov_Olvas< most )
{ Y[t_Elore] =ntc_Olvas(X[t_Elore].lab) ;
Y[t_Vissza] =ntc_Olvas(X[t_Vissza].lab) ;
Y[t_Kemeny] =ntc_Olvas(X[t_Kemeny].lab) ;
Y[t_Kinti] =ntc_Olvas(X[t_Kinti].lab) ;
kov_Olvas=most+olvasas_Koz;
if (Y[t_Elore]<105 && Y[t_Elore]>5) {beilleszt(t_Elore) ;}
else return t_Elore;
if (Y[t_Vissza]<95 && Y[t_Vissza]>5) beilleszt(t_Vissza) ;
else return t_Vissza;
if (Y[t_Kemeny]<250 && Y[t_Kemeny]>5) {beilleszt(t_Kemeny);}
else return t_Kemeny;
if (Y[t_Kinti]<45 && Y[t_Kinti]>-25) {beilleszt(t_Kinti) ;}
else return t_Kinti;
if (Y[t_Elore]+3< Y[t_Vissza]) return 253;
fkep();
//Serial<<kepsor[0]<<" "<<kepsor[1]<<"\n";
}
return 0;
}
// 12334567890123456 KezdőképAlapállapot
//╔════════════════╗ Jelmagyarázat:
//║79°45%12s 40 198║ |előre:79°|ventifűt:45%pwm||adagszünet_Füt:30|adagidő:0,4 mp|Kémény:198°
//║61 28%30 65 -10║ |visszaág:61°|VEntitart28%pwm||adagszünet_tart:30 Szivattyú be:65°|Külső:-10° |
//╚════════════════╝
//================================================================================
/*void frekivalt(int32_t freq, uint8_t PWM )
//[Hz], [%]
{ //Timer 2, 16 bit 16mhz 3 és 11-es lábak. 3-as=OCR2B 11-es = OCR2A/
pinMode(X[venti_Fut].lab, OUTPUT); //PIN11
TCCR2A = _BV(COM2A0) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20); //GYORS_PWM mód
TCCR2B = _BV(WGM22) | _BV(CS22);
TCCR2B = TCCR2B & (B11111000 | B00000100); int32_t divisor=64; //timer 2 divisor to 64 (The DEFAULT)
//TCCR2B = TCCR2B & B11111000 | B00000001; int32_t divisor=1; //timer 2 divisor to 1
//TCCR2B = TCCR2B & B11111000 | B00000010; int32_t divisor=8; //timer 2 divisor to 8
//TCCR2B = TCCR2B & B11111000 | B00000011; int32_t divisor=32; //timer 2 divisor to 32
//TCCR2B = TCCR2B & B11111000 | B00000101; int32_t divisor=128; //timer 2 divisor to 128
//TCCR2B = TCCR2B & B11111000 | B00000110; int32_t divisor=256; //timer 2 divisor to 256
//TCCR2B = TCCR2B & B11111000 | B00000111; int32_t divisor=1024; //timer 2 divisor to 1024
OCR2A = F_CPU/divisor/freq-1; //frekvencia a 3 lábon =16000000/divisor/(OCR2A+1)
OCR2B = (uint8_t)OCR2A*100/PWM+PWM/2; //láb 3 PWM%
}
*/
void setup()
{ Serial.begin(9600); //Serial<<"Vezérlés indul...\n";
pinMode(TERMOSZT, INPUT);
pinMode(X[csiga_Megy].lab, OUTPUT);
pinMode(X[venti_Fut].lab, OUTPUT);
TCCR1B = TCCR1B & (B11111000 | B00000101); // 9-10 Láb PWM frequency : 30.64 Hz;
//TCCR2B = TCCR2B & B11111000 | B00000111; // 3és 11 Láb PWM frequency : 30.64 Hz
//https://www.etechnophiles.com/change-frequency-pwm-pins-arduino-uno/
attachInterrupt(digitalPinToInterrupt(3), nyomas, RISING);
lcd.begin(16, 2);
fkep();
}
void loop()
{ String jelentes;
most = millis();
param_t ellenor;
if (nyomva < most)
{ gombok nyomott_Gomb=gomb_Olvas();
akcio_Menu(nyomott_Gomb);
most=millis();
//Serial<< nyomott_Gomb<<endl;
nyomva=SOHA;
}
ellenor=jelolvas(most);
termoszJel = (!digitalRead(TERMOSZT));
Serial<< termoszJel<<endl;
if(termoszJel!=termoszMult) //Váltás volt. Átállítjuk a paramétereket:
{ if(termoszJel==TERMOSZBE) //--------- Fűtésre váltott --------------------
{ csigamegy=Y[csiga_Megy]; // CSIGAMEGY_FUT;
csigaszunet=Y[csigaSz_Fut]; // CSIGASZ_FUT;
csigaBeLesz=most;
csigaKiLesz=SOHA;
analogWrite(X[venti_Fut].lab, Y[venti_Fut]*100/255);
delay(VENTI_KESES);
melegit_e=" ------ Fűt ------- Venti GYORS >";
}else //--------- Tűztartás --------
{ csigamegy=Y[csiga_Megy]; // CSIGAMEGY_TART;
csigaszunet=Y[csigaSz_Tart]; // CSIGASZ_TART;
csigaKiLesz=most;
csigaBeLesz=SOHA;
analogWrite(X[venti_Tart].lab, Y[venti_Tart]*255/100);
melegit_e=" -----Tűztartás------- Venti LASSÚ >";
}
termoszMult = termoszJel;
}
//--------A paramétereknek megfelelően frissíti az állapotokat
if(csigaBeLesz < most) //Eljött a bekapcsolás ideje
{ digitalWrite(X[csiga_Megy].lab,CSIGABE); //csiga indul
csigaKiLesz = most+csigamegy; //Majd ekkor áll le.
jelentes="CSiga [BE] van Tjel: "+String(termoszJel);
Serial.println(jelentes+melegit_e);
}
if(csigaKiLesz < most) //Eljött a kikapcsolás ideje
{ digitalWrite(X[csigaSz_Tart].lab ,CSIGAKI); //Csiga leáll.
csigaBeLesz=most+csigaszunet; //Ekkor indul újra.
csigaKiLesz=SOHA; //Még egyszer ne állítsa le.
jelentes="CSiga [KI]van Tjel: "+String(termoszJel);
Serial.println(jelentes+melegit_e);
}
}