Io nel frattempo cerco di proseguire, in sostanza il codice sopra era una bozza per ragionare, sto ottimizzando tutto il codice al fine di non inviare comandi o evitare controlli la dove non serva, quindi se le condizioni non cambiano, sto fermo e passo avanti.
Ho inserito in fondo al codice delle Funzioni richiamabili, che altrimenti richiedevano codice ridondato.
Sono consapevole che leggere codice di altri, oltretutto poco pratici, sia complicato… se volete dare contributo benvenga io sto studiando ugualmente.
#include "TimedAction.h" // LIBRERIA PER LOOP TIMER LENTI
#include "Countimer.h" // LIBRERIA PER IL COUNTTIMER (START/STOP/RESTART...)
#include "DHT.h" // LIBRERIA SENSORE UMIDIT'/TEMPERATURA
#define DHT1_PIN 2 // Digital pin connected to the DHT sensor
#define DHT2_PIN 3 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
#define RISC1_PIN 7 // PIN RISCALDATORE PRINCIPALE(SSR DC-AC)
#define RISC2_PIN 8 // PIN RISCALDATORE AUSILIARIO(SSR DC-AC)
#define RISC_RAFFR_PIN 9 // PIN SELEZIONE RISCALD./RAFFREEDDAM.
#define RAFFR_PIN 10 // PIN COMPRESSORE FRIGORIFERO(SSR DC-AC)
#define UM_PIN 11 // PIN UMIDIFICATORE(SSR DC-AC)
#define UM_DEUM_PIN 12 // PIN SELEZIONE UMIDIFIC./DEUMIDIFICATORE
#define DEUM_PIN 13 // PIN DEUMIDIFICATORE(Estrattore)
#define LUCE_PIN 23 // PIN LAMPADA
#define ALLARME_PIN 25 // PIN ALLARME ACUSTICO
#define VENTOLA_PIN 27 // PIN VENTILILAZIONE
#define RAMPA_T 51 // PIN BLINK IN RAMPA Temperatura
#define RAMPA_H 53 // PIN BLINK IN RAMPA Umidità
// Definizione delle costanti di STATO
#define RISCALDA 1
#define RAFFREDDA 0
#define UMIDIFICA 1
#define DEUMIDIFICA 0
#define ATTIVA 1
#define NONATTIVA 0
#define AUTO 0
#define MAN 1
#define PORTA_AP HIGH // Porta aperta
#define PORTA_CH LOW // Porta chiusa
/* ----------------------------------------------------------------------------------
ANALOG VARIABLE
----------------------------------------------------------------------------------
*/
float tcamera=20.0; // Sensore PT100 in cella
float tambiente=20.0; // Sensore PT100 Ambiente
float t1=20.0; // T da Sensore DHT22(1)
float t2=20.0; // T da Sensore DHT22(2)
float tavg=20.0; // Tavg=(T1+T2)/2
float h1=60.0; // T da Sensore DHT22(2)
float h2=60.0; // T da Sensore DHT22(2)
float havg=60.0; // RHavg=(T1+T2)/2
float TSp2Offset= 1.5; // Offset tra SP Principale e Ausiliario
float TInput=22.0; // Temperatura letta (0÷50°C)
float THysOut=0.2; // Isteresi Temperatura per ON-OFF
float THysMode=1.0; // Isteresi per RISCALDAMENTO<-->RAFFREDDMANTO
float THysAlm=2.5; // Isteresi per Allarme Alta/Bassa Temepratura
float TSp1=27.0; // SetPoint Riscaldatore Principale(RISC1)
float TSp2; // SetPoint Riscaldatore Ausiliario(RISC2)
float RhInput=60.0; // Umidità letta (0÷100%)
float RhHysOut=0.5; // Isteresi interna (De)Umidificatore ON/OFF
float RhHysMode=2.5; // Isteresi per MODO UMIDIFCATORE<-->DEUMIDIFCATORE
float RhHysAlm=4.0; // Isteresi per Allarme Alta/Bassa Umidità
float RhSp=67.0; // SetPoint Di default dell'umidità
/* ----------------------------------------------------------------------------------
BOOLEAN VARIABLE STATUS
----------------------------------------------------------------------------------
*/
bool Timer_A_M=MAN; // Programmatore Profilo AUTO-MAN
bool Risc_Raff_S=RISCALDA; // Comando Relay Riscaldamento-Raffreddamento
bool Risc1_S = 0; // Comando Relay riscaldatore principale
bool Risc2_S = 0; // Comando Relay riscaldatore ausiliario
bool Raffr_S=0; // Comando Relay Raffreddamento
bool Um_Deum_S=UMIDIFICA; // Comando Relay Umidificatore-DeUmidificatore
bool Um_S=0; // Comando Relay Umidificatore
bool Deum_S=0; // Comando Relay DeUmidificatore
bool Ventola_S=0; // Comando Relay Ventola
bool Luce_S=0; // Comando Relay Lampada
int8_t Allarme_S=0; // Comando Relay Allarme
int8_t AllarmeT_S=0; // Comando Relay Allarme
int8_t AllarmeRh_S=0; // Comando Relay Allarme
/* ----------------------------------------------------------------------------------
INPUT STATUS
----------------------------------------------------------------------------------
*/
bool LivelloAcqua=0; // Stato Ingresso Livellostato Acqua (NA)
bool PortaFC=PORTA_CH; // Stato Ingresso Fine Corsa Porta Aperta (NA)
/* ----------------------------------------------------------------------------------
ABILITAZIONE RELAIS DI USCITA
----------------------------------------------------------------------------------
*/
bool AllarmEN=1; // ABILITA ALLARMI
bool Risc1EN=1; // ABILITA RISCALDATORE 1
bool Risc2EN=1; // ABILITA RISCALDATORE 2
bool UmEN=1; // ABILITA UMIDIFICATORE
bool DeUumEN=1; // ABILITA DEUMIDIFICATORE
bool VentolaEN=1; // ABILITA VENTOLA
bool RaffrrEN=1; // ABILITA RAFFREDDAMENTO
bool LuceEN=1; // ABILITA LUCE
/* ----------------------------------------------------------------------------------
MODALITA' DI CONTROLLO T e Rh AUTO/MAN
----------------------------------------------------------------------------------
*/
enum eControlMode {AUTO_ALL, AUTO_H, AUTO_C};
eControlMode Tctrlmode=AUTO_ALL;
eControlMode Hctrlmode=AUTO_ALL;
/*----------------------------------------------------------------------------------
STRUTTURA PROFILO TEMPERATURE
----------------------------------------------------------------------------------
*/
enum eRampaProfilo {R_SALITA, R_DISCESA, R_STASI};
enum eProfilo {CURVA1, CURVA2, CURVA3};
constexpr uint8_t NUM_FASI = 3; // Numero di Passi del profilo
constexpr uint8_t NUM_CURVE = 3; // Numero di profili
uint8_t ContaFasi=0; // Contatore passi del Profilo
uint8_t ProfiloAttivo=CURVA1; // Profilo selezionato
uint8_t DirRampaT=R_STASI; // Attivazione Rampa profilo
uint8_t DirRampaH=R_STASI; // Attivazione Rampa profilo
bool TRampa_S; // Stato di Rampa T, usato per BLINK
bool HRampa_S; // Stato di Rampa H, usato per BLINK
uint32_t totmills=0; // Totalizzatore Millisecondi
char _TimerHHMMSS[10]; // Conversione Millisec in CHAR
float prossTSp; // SetPoint Temperatura nella Fase da attivare
float prossHSp; // SetPoint Umidità nella Fase da attivare
float dtTinc=0.0; // Valore incremento Temperatura in rampa
float dtHinc=0.0; // Valore incremento Umidità in rampa
uint16_t CicloVentola[2]={30000, 60000};
struct Profilo {
uint32_t durata; // Tempo della Fase
float tsp; // Valore SetPoint di Temperatura della fase
float hsp; // Valore SetPoint di Umidità della fase
};
Profilo CntSteps[NUM_CURVE][NUM_FASI] = {
{{18000, 28.5, 68.0}, {15000, 25.0, 70.0}, {12000, 29.5, 65.0}},
{{14400000, 28.0, 68.0}, {7200000, 26.0, 68.0}, {28800000, 25.5, 65.0}},
{{28800000, 28.0, 68.0}, {14400000, 26.0, 68.0}, {7200000, 25.5, 65.0}}
};
/*----------------------------------------------------------------------------------
END STRUTTURA PROFILO TEMPERATURE
----------------------------------------------------------------------------------
*/
/*----------------------------------------------------------------------------------
STRUTTURA GESTIONE ALLARMI
----------------------------------------------------------------------------------
*/
struct dataAlarm
{
uint8_t idx;
bool Stato;
bool Acq;
char Desc[20];
bool Mostrato;
bool Rientrato;
};
constexpr uint8_t NUM_ALLARM=8;
dataAlarm data[NUM_ALLARM] = // Aggiunta del segno di uguale per l'inizializzazione corretta
{
{0, 0, 0, "BASSO LIV. VASCA"},
{1, 0, 0, "TEMPO SCADUTO"},
{2, 0, 0, "PORTA APERTA"},
{3, 0, 0, "BASSA TEMP. CAMERA"},
{4, 0, 0, "ALTA TEMP. CAMERA"},
{5, 0, 0, "BASSA UMID. CAMERA"},
{6, 0, 0, "ALTA UMID. CAMERA"},
{7, 0, 0, "FAULT SENSORI"}
};
/* ----------------------------------------------------------------------------------
CLASS OBJECT DECLARATION
----------------------------------------------------------------------------------
*/
Countimer tCounter; // OGGETTO COUNTER
DHT dht1(DHT1_PIN, DHTTYPE); // OGGETTO DHT SENSORE 1
DHT dht2(DHT2_PIN, DHTTYPE); // OGGETTO DHT SENSORE 2
TimedAction taskLenta = TimedAction(1000,&Task1000); // Task SLOW (1 secondo)
TimedAction taskVeloce = TimedAction(100,&Task200); // Task FAST (200 mills)
TimedAction taskVentola = TimedAction(30000,&TaskFAN); // Task VENTOLA (su condizione)
TimedAction taskLuce = TimedAction(60000,&TaskLIGHT); // Task LUCE (su condizione) AUTOSPEGNIMENTO 60sec.
/*----------------------------------------------------------------------------------
END CLASS OBJECT DECLARATION
----------------------------------------------------------------------------------
*/
void setup() {
pinMode(LUCE_PIN, OUTPUT); // LUCE
pinMode(ALLARME_PIN, OUTPUT); // ALLARME
pinMode(RISC1_PIN, OUTPUT); // RISCALDATORE PRINCIPALE
pinMode(RISC2_PIN, OUTPUT); // RISCALDATORE AUSILIARIO
pinMode(RISC_RAFFR_PIN, OUTPUT); // RISCALDAMENTO-RAFFRESCAMENTO
pinMode(RAFFR_PIN, OUTPUT); // RAFFREDDAMENTO
pinMode(UM_DEUM_PIN, OUTPUT); // UMIFICATORE-DEUMIFICATORE
pinMode(UM_PIN, OUTPUT); // UMIFICATORE
pinMode(DEUM_PIN, OUTPUT); // DEUMIDIFICATORE
pinMode(VENTOLA_PIN, OUTPUT); // VENTOLA
pinMode(51, OUTPUT); // BLINK RAMPA T
pinMode(53, OUTPUT); // BLINK RAMPA H
pinMode(A0, INPUT_PULLUP); // TEMPERATURA
pinMode(A1, INPUT_PULLUP); // UMIDITA'
pinMode(A2, INPUT_PULLUP); // FINE CORSA PORTA CHIUSA
pinMode(A3, INPUT_PULLUP); // LIVELLOSTATO ACQUA
// -------------- DA RIMUOVERE CON IL DISPLAY ---------------
pinMode(A5, INPUT_PULLUP); // TIMER STEPS (AUTO/MAN)
pinMode(A6, INPUT_PULLUP); // START TIMER
pinMode(A7, INPUT_PULLUP); // STOP/RESET TIMER
// --------------------- DA RIMUOVERE -----------------------
/*----------------------------------------------------------------------------------
DHT22 inizializzazione CLASSE
----------------------------------------------------------------------------------
*/
dht1.begin(); // SENSORE 1 DHT22
dht2.begin(); // SENSORE 2 DHT22
taskLuce.disable();
setTcontrolmode(AUTO_ALL);
setHcontrolmode(AUTO_ALL);
Timer_A_M=MAN;
tCounter.setCounter(0, 0, 10, tCounter.COUNT_UP, tCounterComplete);
tCounter.setInterval(tCounterRunning, 1000);
//AggiornaSPT(TSp1);
ProfiloAttivo=CURVA1;
digitalWrite(DEUM_PIN,HIGH);
Serial.begin(9600);
}
void loop() {
taskVeloce.check(); //200ms
taskLenta.check(); //1sec
taskVentola.check(); //Ciclico
taskLuce.check(); //su richiesta
tCounter.run();
}
void Task200(){
/*
Inserire quì la lettura della seriale Display
*/
bool _PortaFC = (analogRead(A2) < 512) ? LOW : HIGH;
bool _LivelloAcqua = (analogRead(A3) < 512) ? LOW : HIGH;
/*---------------------------------------------------------
Da Eliminare quandosi connette il Display TOUCH
---------------------------------------------------------
*/
bool analogA5 = analogRead(A5) < 512;
bool analogA6 = analogRead(A6) < 512;
bool analogA7 = analogRead(A7) < 512;
if (LivelloAcqua != _LivelloAcqua) {
LivelloAcqua = _LivelloAcqua;
setUm(Um_S);
setAllarme(0, LivelloAcqua);
verificaAllarme();
}
// USO ANALOGICO COME DIGITALE PER LO SW PORTA
if (PortaFC!=_PortaFC) {
PortaFC=_PortaFC;
if (PortaFC == PORTA_AP) {
// PORTA APERTA
taskLuce.disable();
setLuce(HIGH);
}
else if (PortaFC == PORTA_CH) {
// PORTA CHIUSA
Serial.println("DOOR is Close Light TURN-OFF In few seconds");
if (Luce_S==1) {
taskLuce.enable();
taskLuce.reset();
}
}
set_Risc_Raffr(Risc_Raff_S);
setRisc1(Risc1_S);
setRisc2(Risc2_S);
setRaffr(Raffr_S);
setAllarme(2, PortaFC);
verificaAllarme();
}
/* ---------------------------------------------------------------------------
------------------------ GESTIONE PULSANTI TIMER --------------------------
---------------------------------------------------------------------------
*/
if (analogA5) {
Timer_A_M = (Timer_A_M == MAN) ? AUTO : MAN;
Serial.println((Timer_A_M == MAN) ? "MANUALTIMER" : "AUTOTIMERSTEPS");
}
if (analogA6) {
if (Timer_A_M == MAN) {
if (!tCounter.isCounterRunning()) {
tCounter.start();
Serial.println("Counter START");
} else if (!tCounter.isStopped() && tCounter.isStarted()) {
tCounter.pause();
Serial.println("Counter PAUSA");
}
} else if (Timer_A_M == AUTO) {
EseguiProfilo(0);
}
}
if (analogA7) {
if (!tCounter.isCounterCompleted()) {
tCounter.stop();
Serial.println("Counter STOP");
}
}
}
void Task1000() {
/*
h1 = dht1.readHumidity(); // read Umidity 1
t1 = dht1.readTemperature(); // read temperature 1
h2 = dht2.readHumidity(); // read Umidity 2
t2 = dht2.readTemperature(); // read temperature 2
// Check if any reads failed and exit early (to try again).
_SensorState= isnan(h1) || isnan(t1) || isnan(h2) || isnan(t2)
if (SensorState != _SensorState) {
SensorState=_SensorState;
SetAlarm(7,SensorState);
CheckAlarm();
}
if (SensorState==0) {
tavg=(t1+t2)/2;
havg=(h1+h2)/2;
InputT = tavg;
InputRh = havg;
}
*/
// Lettura dei sensori esterni e scalatura
//tcamera=mapFloat(analogRead(A0) , 0, 1023, 0.0, 50.0);
//tambiente=mapFloat(analogRead(A1) , 0, 1023, 0.0, 50.0);
TInput = mapFloat(analogRead(A0), 0, 1023, 0.0, 50.0);
RhInput = mapFloat(analogRead(A1), 0, 1023, 0.0, 100.0);
if (Tctrlmode !=AUTO_C) {
// DETERMINA SE MODO RISCALDAMENTO/RAFFREDDAMENTO
if (hysControl(TInput,TSp1,THysMode,&Risc_Raff_S)) {
set_Risc_Raffr(Risc_Raff_S);
}
// DETERMINA SE ATTIVARE UTENZA RISC1/RAFFR
if (hysControl(TInput,TSp1,THysOut,&Risc1_S)) {
setRisc1(Risc1_S);
setRaffr(!Risc1_S);
}
// DETERMINA SE ATTIVARE UTENZA AUSILIARIA RISC2
if (hysControl(TInput,TSp2,THysOut,&Risc2_S)) {
setRisc2(Risc2_S);
}
if (AlmControl(TInput,TSp1,THysAlm,&AllarmeT_S)) {
switch (AllarmeT_S) {
case -1: setAllarme(3, 1);
break;
case 1: setAllarme(4, 1);
break;
case 0: setAllarme(3, 0);setAllarme(4, 0);
break;
}
verificaAllarme();
}
}
if (Hctrlmode !=AUTO_H) {
if (hysControl(RhInput,RhSp,RhHysMode,&Um_Deum_S)) {
setUm_Deum(Um_Deum_S);
}
if (hysControl(RhInput,RhSp,RhHysOut,&Um_S)) {
setUm(Um_S);
setDeum(!Um_S);
}
if (AlmControl(RhInput,RhSp,RhHysAlm,&AllarmeRh_S)) {
switch (AllarmeRh_S) {
case -1: setAllarme(5, 1);
break;
case 1: setAllarme(6, 1);
break;
case 0: setAllarme(5, 0);setAllarme(6, 0);
break;
}
verificaAllarme();
}
}
if (!tCounter.isCounterRunning()) {
Serial.print("SpT:" + String(TSp1, 1) + " T:" + String(TInput, 1));
Serial.println("|SpRh:" + String(RhSp, 1) + " Rh:" + String(RhInput, 1));
}
}
void TaskLIGHT(){
setLuce(LOW);
}
void TaskFAN(){
bool bFan=!Ventola_S;
taskVentola.setInterval(CicloVentola[bFan]);
setVentola(bFan);
}
void tCounterRunning()
{
float newT=TSp1;
float newH=RhSp;
if (Timer_A_M==AUTO) {
newT=newT+dtTinc;
newH=newH+dtHinc;
switch (DirRampaT) {
case R_SALITA:
TRampa_S=!TRampa_S; // LAMPEGGIO
if (newT>prossTSp) {DirRampaT=R_STASI;newT=prossTSp;}
break;
case R_DISCESA:
TRampa_S=!TRampa_S; // LAMPEGGIO
if (newT<prossTSp) {DirRampaT=R_STASI;newT=prossTSp;}
break;
case R_STASI:
TRampa_S=0; // STOP LAMPEGGIO
newT=prossTSp;
break;
}
digitalWrite(RAMPA_T, TRampa_S); // BLINK RAMPA T
switch (DirRampaH) {
case R_SALITA:
HRampa_S=!HRampa_S; // LAMPEGGIO
if (newH>prossHSp) {DirRampaH=R_STASI;newH=prossHSp;}
break;
case R_DISCESA:
HRampa_S=!HRampa_S; // LAMPEGGIO
if (newH<prossHSp) {DirRampaH=R_STASI;newH=prossHSp;}
break;
case R_STASI:
HRampa_S=0; // STOP LAMPEGGIO
newH=prossHSp;
break;
}
digitalWrite(RAMPA_H, HRampa_S); // BLINK RAMPA H
SPLimiter(&TSp1,newT,4,35);
SPLimiter(&RhSp,newH,50,90);
// AGGIORNA TIMER+STEP SE IN AUTOCOUNTER
Serial.print(timetoHHMMSS(totmills+tCounter.getCurrentMills()));
Serial.print(" [" + String(ContaFasi) + "] ");
Serial.print("SpT:" + String(TSp1,1)+ " T:" + String(TInput,1));
Serial.print("|");
Serial.print("SpH:" + String(RhSp,1)+ " H:" + String(RhInput,1));
Serial.print("|");
Serial.print(tCounter.getCurrentTimeLeft());
Serial.print("-");
Serial.println(tCounter.getCurrentTime());
}
else {
// AGGIORNA TIMER SE PASSATO IN MANUALE
if (ContaFasi==NUM_FASI) {
SPLimiter(&TSp1,prossTSp,4,35);
SPLimiter(&RhSp,prossHSp,50,90);
Serial.print("Over (");
Serial.print(timetoHHMMSS(totmills+tCounter.getCurrentMills()));
Serial.print(") ");
}
Serial.print("Sp:" + String(TSp1,1)+ " T:" + String(TInput,1) );
Serial.print(tCounter.getCurrentTimeLeft());
Serial.print("-");
Serial.println(tCounter.getCurrentTime());
}
}
void tCounterComplete() {
if (Timer_A_M==AUTO) {
totmills+=CntSteps[ProfiloAttivo][ContaFasi].durata;
ContaFasi++;
if (ContaFasi<NUM_FASI){
EseguiProfilo(ContaFasi);
// AGGIORNAMENTO DISPLAY
// ...
}
else {
//FINITO I 3 STEPS AUTOMATICI
Timer_A_M=MAN;
tCounter.setCounter(0,0,10); // TIMER MANUALE EXTRATEMPO SE L'ULTIMO STEP AUTO NON FOSSE SUFFICIENTE
tCounter.start(); // FA RIPARTIRE IL TIMER SE SCADUTO ULTIMO STEP
}
}
else if (Timer_A_M==MAN)
{
// TIMEOUT
}
}
void EseguiProfilo(uint8_t FaseCorrete) {
uint32_t _tempofase;
if (FaseCorrete == 0) {
totmills = 0;
ContaFasi = 0;
TSp1 = 24.0; //Primo Step uso Temperatura Ambiente come Inizio per la rampa
RhSp=60.0; //Primo Step uso Umidità ambiente come Inizio per la rampa
} else {
SPLimiter(&TSp1,CntSteps[ProfiloAttivo][FaseCorrete - 1].tsp,4,35);
SPLimiter(&RhSp,CntSteps[ProfiloAttivo][FaseCorrete - 1].hsp,50,90);
}
if (FaseCorrete < NUM_FASI) {
prossTSp = CntSteps[ProfiloAttivo][FaseCorrete].tsp;
prossHSp = CntSteps[ProfiloAttivo][FaseCorrete].hsp;
_tempofase=CntSteps[ProfiloAttivo][FaseCorrete].durata;
dtTinc=CalcoloRaccordo(TSp1, prossTSp, _tempofase, &DirRampaT);
dtHinc=CalcoloRaccordo(RhSp, prossHSp, _tempofase, &DirRampaH);
Serial.print("Fase:[");
Serial.print(FaseCorrete);
Serial.print("] rmpT:");
Serial.print(DirRampaT);
Serial.print("| dtT:");
Serial.print(dtTinc);
Serial.print("| TSp1:");
Serial.print(TSp1);
Serial.print("->");
Serial.print(prossTSp);
Serial.print("| rmpH:");
Serial.print(DirRampaH);
Serial.print("| dtH: ");
Serial.print(dtHinc);
Serial.print("| HSp: ");
Serial.print(RhSp);
Serial.print("->");
Serial.print(prossHSp);
Serial.print("| Durata: ");
Serial.println(timetoHHMMSS(_tempofase));
tCounter.setCounter(_tempofase);
// Update display
// ...
if (!tCounter.isCounterRunning()) {
tCounter.start();
}
} else {
// Handle error: FaseCorrete exceeds maximum steps
Serial.println("Error: Step index exceeds maximum steps.");
}
}
void setTcontrolmode(eControlMode value) {
if (Tctrlmode!=value) {
Tctrlmode=value;
switch (value)
{
case AUTO_ALL:
Risc_Raff_S = RISCALDA;
break;
case AUTO_H:
Risc_Raff_S = RISCALDA;
break;
case AUTO_C:
Risc_Raff_S = RAFFREDDA;
break;
default: break;
}
// SET ICON ON DISPLAY
// ....
}
}
void setHcontrolmode(eControlMode value) {
if (Hctrlmode!=value) {
Hctrlmode=value;
switch (value)
{
case AUTO_ALL:
Um_Deum_S = UMIDIFICA;
break;
case AUTO_H:
Um_Deum_S = UMIDIFICA;
break;
case AUTO_C:
Um_Deum_S = DEUMIDIFICA;
break;
default: break;
}
// SET ICON ON DISPLAY
// ....
}
}
void set_Risc_Raffr(bool value) {
Risc_Raff_S = value;
digitalWrite(RISC_RAFFR_PIN, Risc_Raff_S==RAFFREDDA && (PortaFC==PORTA_CH));
setRisc1(Risc1_S);
setRaffr(!Risc1_S);
// SET ICON ON DISPLAY
// ....
}
void setRisc1(bool value) {
Risc1_S=value && RaffrrEN && (Risc_Raff_S == RISCALDA);
digitalWrite(RISC1_PIN, Risc1_S && (PortaFC==PORTA_CH));
// SET ICON ON DISPLAY
// ....
}
void setRisc2(bool value) {
Risc2_S = value && Risc2EN && (Risc_Raff_S == RISCALDA);
digitalWrite(RISC2_PIN, Risc2_S && (PortaFC==PORTA_CH));
// SET ICON ON DISPLAY
// ....
}
void setRaffr(bool value) {
Raffr_S=value && RaffrrEN && (Risc_Raff_S == RAFFREDDA);
digitalWrite(RAFFR_PIN, Raffr_S && (PortaFC==PORTA_CH));
// SET ICON ON DISPLAY
// ....
}
void setUm_Deum(bool value) {
Um_Deum_S = value;
digitalWrite(UM_DEUM_PIN, (Um_Deum_S==DEUMIDIFICA) && (PortaFC==PORTA_CH));
// SET ICON ON DISPLAY
// ....
setUm(Um_S);
setDeum(!Um_S);
}
void setUm(bool value) {
Um_S = value && UmEN && (Um_Deum_S == UMIDIFICA);
digitalWrite(UM_PIN, Um_S && (PortaFC==PORTA_CH) && !LivelloAcqua);
// SET ICON ON DISPLAY
// ....
}
void setDeum(bool value) {
Deum_S = value && DeUumEN && (Um_Deum_S == DEUMIDIFICA);
digitalWrite(DEUM_PIN, Deum_S && (PortaFC==PORTA_CH));
// SET ICON ON DISPLAY
// ....
}
/* ---------------------------------------------------------------------------
-------------------------------- FAN START -------------------------------
---------------------------------------------------------------------------
*/
void setVentola(bool value) {
Ventola_S=value && VentolaEN ;
digitalWrite(VENTOLA_PIN, Ventola_S && (PortaFC==PORTA_CH));
// SET ICON ON DISPLAY
// ....
}
/* ---------------------------------------------------------------------------
------------------------------- LIGHT START ------------------------------
---------------------------------------------------------------------------
*/
void setLuce(bool value) {
if ((Luce_S=!value) && Luce_S) {taskLuce.disable();}
Luce_S=value && LuceEN;
digitalWrite(LUCE_PIN, Luce_S || PortaFC==PORTA_AP);
// SET ICON ON DISPLAY
// ....
}
void setAllarmeSonoro(bool value) {
if (Allarme_S!=value ) {
Allarme_S=value && AllarmEN;
digitalWrite(ALLARME_PIN, Allarme_S);
// SET ICON ON DISPLAY
// ....
}
}
float mapFloat(float value, float fromLow, float fromHigh, float toLow, float toHigh) {
return (value - fromLow) * (toHigh - toLow) / (fromHigh - fromLow) + toLow;
}
char* timetoHHMMSS(uint32_t millisec) {
uint16_t allSeconds = millisec / 1000; // convert millisecondi in secondi
uint16_t hours = allSeconds / 3600; // calcola le ore correttamente
uint16_t secondsRemaining = allSeconds % 3600; // secondi rimanenti
uint8_t minutes = secondsRemaining / 60; // converti i secondi rimanenti in minuti
uint8_t seconds = secondsRemaining % 60; // secondi rimanenti
sprintf(_TimerHHMMSS, "%02d:%02d:%02d", hours, minutes, seconds);
return _TimerHHMMSS;
}
/* ---------------------------------------------------------------------------
------------------------------- ALARM START ------------------------------
---------------------------------------------------------------------------
*/
void setAllarme(uint8_t idx, bool value){
// se l'allarme è RN e riuscito lo ri-visualizzo
if (data[idx].Stato!=value) {
data[idx].Stato=value;
if (value==1) {
data[idx].Acq=1;
data[idx].Rientrato=0;
}
else {
data[idx].Rientrato=1;
}
data[idx].Mostrato=0;
}
// SET ICON ON DISPLAY
// ....
}
void verificaAllarme(){
bool _AlarmOut_S=0;
if (AllarmEN) {
for (uint8_t i = 0; i < NUM_ALLARM; i = i + 1) {
_AlarmOut_S=_AlarmOut_S || data[i].Stato || data[i].Acq;
if (data[i].Stato && data[i].Acq && !data[i].Mostrato) {
Serial.println(data[i].Desc);
data[i].Mostrato=1;
}
else if (data[i].Rientrato && !data[i].Mostrato) {
Serial.print(data[i].Desc);
Serial.println(" [RN]");
data[i].Mostrato=1;
}
}
setAllarmeSonoro(_AlarmOut_S);
}
// SET ICON ON DISPLAY
// ....
}
void AcqAllarmi(){
for (byte i = 0; i < NUM_ALLARM; i = i + 1) {
if (data[i].Acq){
data[i].Acq=0;
if (data[i].Stato==0) {
data[i].Mostrato=0;
data[i].Rientrato=0;
}
}
}
setAllarmeSonoro(0);
/* BUZZER
SET ICON ON DISPLAY
....
*/
}
float CalcoloRaccordo(float sp_Y0, float sp_Y1, uint32_t tempo, uint8_t *Direzione){
// Calcolo coefficiente angolare della rampa considerando di esaurirla in 10min
// Sapendo che aggiorno a 1secondo...., divido per 600
float dy=(sp_Y1 - sp_Y0)/600;
if (sp_Y0 < sp_Y1) {
*Direzione = R_SALITA;
}
else if (sp_Y0 > sp_Y1) {
*Direzione = R_DISCESA;
}
else {
*Direzione = R_STASI;
dy = 0.0;
}
return dy;
}
void SPLimiter(float *setpoint,float valore, float minimo, float massimo) {
float valorecompresso=valore;
if (valorecompresso<minimo){
valorecompresso=minimo;
}
if (valorecompresso>massimo){
valorecompresso=massimo;
}
*setpoint=valorecompresso;
}
bool hysControl(float input, float setpoint, float hysteresis,bool *state) {
bool oldstate=*state;
if (input <= (setpoint - hysteresis)) {
*state = true;
} else if (input >= (setpoint + hysteresis)) {
*state = false;
}
return *state != oldstate;
}
bool AlmControl(float input, float setpoint, float hysteresis, uint8_t *state) {
uint8_t oldstate=*state;
if (input <= (setpoint - hysteresis)) {
*state = -1;
} else if (input >= (setpoint + hysteresis)) {
*state = 1;
} else if (abs(input - setpoint) < hysteresis) {
*state = 0;
}
return *state != oldstate;
}