Macchina a stati finiti

Ciao a tutti,
per il momento è solo una cosa esplorativa, con l'intenzione di eventuale ulteriore ottimizzazione del codice...

nel mio caso avrei 4 situazione da gestire e dei sensori da controllare in maniera continua.

quindi nel loop metto il controllo dei sensori che continuamente verificano la situazione.

poi creo quattro casi:

tende in chiusura quindi caso 0 (ad esempio perchè comincia a piovere)
tende chiuse quandi caso 1
tende in riapertura quindi caso 2
tende aperte quindi caso 3

il dubbio sta nel fatto che avendo 3 tende, due con dei paramentri di chiusura più bassi rispetto ad una terza che ha paramentri di intensità maggiore. ad esempio per la pioggia, le prime due sia chiudono con una pioggia normale(per cosi dire...) la terza si chiude con pioggia forte.... come risolvere questa cosa?

girovagando in rete non ho trovato nulla che mi abbia risposto a questa domanda...

grazie come sempre

All'inizio leggi tutti i sensori/ingressi. Poi ogni tenda è controllata da una macchina diversa in cui scrivi le condizioni specifiche che ti interessa testare (timeout / soglie ecc).

I codice per una macchina (controllata da 'fase1' e dai segnali 'open1' 'close1') potrebbe essere qualcosa del genere:

open1 =  ...espressione/condizione per apertura...
close1 = ...espressione/condizione per chiusura...

if (fase1 != fase1Prec) { fase1Prec = fase1;  t1 = millis();  trascorso1 = 0; }
else                    { trascorso1 = millis() - t1;                         }

if      (CHIUSO == fase1    &&  open1)            { fase1 = APERTURA; }
else if (APERTURA == fase1  &&  trascorso1 > ...) { fase1 = APERTO;   }
else if (APERTO == fase1    &&  close1)           { fase1 = CHIUSURA; }
else if (CHIUSURA == fase1  &&  trascorso1 > ...) { fase1 = CHIUSO;   }

digitalWrite(RELE_APERTURA_1, (APERTURA == fase1) ? ONLEVEL : OFFLEVEL);
digitalWrite(RELE_CHIUSURA_1, (CHIUSURA == fase1) ? ONLEVEL : OFFLEVEL);

Il tuo programma deve prevedere 3 macchine a stati, ciascuna relativa a ogni tenda, con 4 stati differenti: aperto, chiuso, inChiusura, inApertura.

Definisci le tende: tendaUno, tendaDue, tendaTre, e gli stati relativi: apertoUno, apertoDue, apertoTre; chiusoUno, … etc. Per ciascuna tenda ci saranno i pulsanti, i sensori e i motori dedicati, oltre a un sensore vento comune a tutte e tre.

Inizialmente in base alla lettura dei sensori stabilisci lo stato di ciascuna tenda (che sarà apertoUno/chiusoUno; apertoDue/chiusoDue; … etc.).

Il programma sarà un insieme di switch - case. Questo può essere un esempio di principio

SWITCH tenda
 CASE tendaUno
   SWITCH statoUno
     CASE apertoUno
       SE sensoreVento > ventoUno O pulsanteChiudiUno attivo
         chiudi tendaUno
         statoUno = inChiusuraUno
         break
     CASE inChiusuraUno
       SE finecorsaChiusoUno attivo
         ferma motoreUno
         statoUno = chiusoUno
         break
     CASE chiusoUno
       SE pulsanteApriUno attivo E sensoreVento < ventoUno
         apri tendaUno
         statoUno = inAperturaUno
         break
     CASE inAperturaUno
       SE finecorsaApertoUno attivo
         ferma motoreUno
         statoUno = apertoUno
         break
 CASE tendaDue
   .  .  .

Ciao,
P:

il dubbio sta nel fatto che avendo 3 tende, due con dei paramentri di chiusura più bassi rispetto ad una terza che ha paramentri di intensità maggiore. ad esempio per la pioggia, le prime due sia chiudono con una pioggia normale(per cosi dire...) la terza si chiude con pioggia forte.... come risolvere questa cosa?

Se le macchine a stati hanno qualcosa di più in comune sarebbe da sondare la possibilità di creare una sola macchina a stati che prende in ingresso una variabile di tipo struct. La macchina a stati sarà una sola funzione che prende come argomenti la variabile di tipo struct. Ovviamente dovrai creare 3 variabili di questo tipo.

Prima di passare a questa soluzione dovresti lavorare per scrivere la macchina a stati funzionante ed evidenziare i dati in base alla quale la macchina a stati deve comportarsi in modo differente.

Quindi sempre un passo per volta. Aiutati con codice di test per singoli obbiettivi, nel senso che puoi anche creare 2, 3, 5, 10 scketch dove in ognuno affronti i singoli obbiettivi. Un altro scketch sarà quello in cui provi ad integrare ciò che hai fatto con gli altri sketch.

Ciao.

simosere:
nel mio caso avrei 4 situazione da gestire e dei sensori da controllare in maniera continua.

Hm, capiti a fagiolo, vedi QUI se trovi qualche spunto, è una libreria che ho scritto io e proprio oggi ho rilasciato in versione 2.0. :wink:

poi creo quattro casi:
tende in chiusura quindi caso 0 (ad esempio perchè comincia a piovere)
tende chiuse quandi caso 1
tende in riapertura quindi caso 2
tende aperte quindi caso 3

Se vuoi usare la libreria FiniteState, una macchina per la singola tenda la tradurrei così:

...
  fsm.Write(S_START, C_PIOVE, A_CHIUDI, 0, S_CHIUSURA);
  fsm.Write(S_CHIUSURA, C_CHIUSA, A_NONE, 0, S_CHIUSA);
  fsm.Write(S_CHIUSA, C_APERTURA, A_APRI, 0, S_APERTURA);
  fsm.Write(S_APERTURA, C_APERTA, A_NONE, 0, S_START);
  fsm.Set(S_START);
...

La condizione "C_PIOVE" avviene quando leggi la presenza di pioggia, "C_CHIUSA" si ha quando la tenda è chiusa (hai un sensore di fine corsa?), poi "C_APERTURA" immagino sia comandato da un qualche tuo comando o pulsante, e "C_APERTA" è la tenda totalmente aperta (anche qui, potrebbe essere con un sensore di apertura completata).

Se le tende si devono aprire con condizioni differenti dovrai creare un oggetto FiniteState per ogni tenda, e gestire quindi tre funzioni di controllo condizioni e di azione. Ovviamente alcune cose che ti sto dicendo fanno riferimento alla libreria, quindi se vuoi provarci, leggi quel post che ti ho indicato nel link, e vedi se ti può essere utile.

grazie a tutti!!!

approfondisco la cosa e valuto il da farsi...