Go Down

Topic: Irrigazione automatica (Read 3974 times) previous topic - next topic

karnhack

May 23, 2019, 02:22 pm Last Edit: May 23, 2019, 02:26 pm by karnhack
Salve a tutti. E' da un po che copio codici e progetti online e mi scoraggia molto non riuscire a creare da me piccoli progetti come per esempio quest'ultimo che ho in mente, cioè un irrigazione automatica.
Mi rendo conto che ci sono un sacco di progetti online e vi assicuro che li ho visionati quasi tutti ed ho provato a capirci qualcosa ma ognuno di essi è specifico per un certo utilizzo e quando provo a modificarlo per le mie esigenze mi perdo nel codice e non ci capisco nulla. Vi prego dunque di aiutarmi a capire cosa non capisco... grazie.
Vi espongo il mio progetto dunque:

Materiali:
- Arduino uno (o anche mega)
- TinyRTC
- Relay a 4 stadi
- Elettrovalvola (non ancora comprata)
- Pompa (non ancora comprata)
- Sonda troppopieno
- Driver Pololu per movimentare una pompa peristaltica (forse l'utilizzo di un motore stepper è esagerato)

Tralasciando il fatto che un domani vorrei aggiungere funzioni di rilevamento umidità, temperatura e pioggia, ma per ora preferisco non complicarmi la vita...

In pratica, con questo irrigatore vorrei evitare di annaffiare le piante con l'acqua di rete per evitare che il cloro danneggi i microorganismi presenti nella terra. Quindi ho previsto un bidone che verrà riempito alla fine di ogni annaffiatura e che contiene la pompa che porterà l'acqua alle piante.

In poche parole la logica sarebbe questa: dalle ore hh:mm alle ore hh:mm attivo la pompa (relay1) e innaffio dal bidone. Subito dopo aver innaffiato si apre l'elettrovalvola e il bidone viene riempito nuovamente. Un rilevatore di troppopieno arresterà l'elettrovalvola a bidone riempito.

Per complicarmi la vita vorrei inserire una pompa peristaltica che  una volta al mese prima di innaffiare andrà ad aggiungere all'acqua un po concime liquido e lo mescolerà con un agitatore magnetico ricavato da una ventola. Tutto quì, semplice no? :D

Ora, il mio handicap:

Code: [Select]
/**********************************************************
 * Prova irrigazione
/**********************************************************/

#include <Wire.h>
#include <RTClib.h>
   
#define pinPompa 5
   
int Pompa[] = {13,29,13,30};
   
RTC_DS1307 RTC;
   
void setup() {
  Serial.begin(9600);
  Serial.println( "START" );
   
  Wire.begin();
  RTC.begin();
 
/**********************************************************/
// RTC.adjust(DateTime(2019, 05, 23, 12, 53, 00));
 
/* togliere il commento dalla riga sopra quando si vuole impostare l'ora
nel modulo rtc, inserire data e ora attuale, formato: (yyyy,mm,dd,hh,mm,ss).
Una volta impostata l'ora ricommentare la riga e ricaricare lo sketch.  */
/**********************************************************/
 
   
   pinMode( pinPompa,OUTPUT );

   
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
   
   digitalWrite( pinPompa,LOW );

 }
   
void loop() {
  if ( RTC.isrunning()) {
    DateTime now = RTC.now();
   
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
   
    int _hour   = now.hour();
    int _minute = now.minute();
 
    // Avvio Pompa
    if ( Pompa[0] <= _hour && _hour <= Pompa[2] && Pompa[1] <= _minute && _minute <= Pompa[3] ) {
      digitalWrite( pinPompa,HIGH );
    } else { digitalWrite( pinPompa,LOW ); }
    }
}


Ovviamente ho scopiazzato qua e la e tra l'altro non funziona neanche bene perchè funziona al contrario... in pratica dovrebbe accendersi alle 13,29 e spegnersi alle 13,30 mentre in questo lasso di tempo si spegne. Non a caso non sono riuscito a capire la variabile che si occupa dell'accensione:
Code: [Select]
  if ( Pompa[0] <= _hour && _hour <= Pompa[2] && Pompa[1] <= _minute && _minute <= Pompa[3]

Ne uscirò?

karnhack

#1
May 23, 2019, 03:41 pm Last Edit: May 23, 2019, 03:44 pm by karnhack
Per forza di cose visto che non la capivo ho dovuto sostituire l'ultima variabile con questo
Code: [Select]
/**********************************************************
 * Prova irrigazione
/**********************************************************/

#include <Wire.h>
#include <RTClib.h>
   
#define pinPompa 5
   
   
RTC_DS1307 RTC;
   
void setup() {
  Serial.begin(9600);
  Serial.println( "START" );
   
  Wire.begin();
  RTC.begin();
 
/**********************************************************/
// RTC.adjust(DateTime(2019, 05, 23, 12, 53, 00));
 
/* togliere il commento dalla riga sopra quando si vuole impostare l'ora
nel modulo rtc, inserire data e ora attuale, formato: (yyyy,mm,dd,hh,mm,ss).
Una volta impostata l'ora ricommentare la riga e ricaricare lo sketch.  */
/**********************************************************/
   
   pinMode( pinPompa,OUTPUT );
   
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
   
   digitalWrite( pinPompa,HIGH );
   
 }
   
void loop() {
  if ( RTC.isrunning()) {
    DateTime now = RTC.now();
   
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();

    if( now.hour()==15 && now.minute()==36) {
      digitalWrite( pinPompa,LOW );
    } else { digitalWrite( pinPompa,HIGH ); }
    }
}


Ed ho dovuto invertire i pin HIGH con LOW altrimenti funzionava al contrario (probabilmente perchè il relay che uso è normalmente chiuso?). Ora mi rimane di capire se posso impostare una durata in secondi dall'avvio del relay

Claudio_FF

#2
May 23, 2019, 05:29 pm Last Edit: May 24, 2019, 07:25 am by Claudio_FF
Salve a tutti. E' da un po che copio codici e progetti online e mi scoraggia molto non riuscire a creare da me piccoli progetti come per esempio quest'ultimo che ho in mente, cioè un irrigazione automatica.
Bisogna vedere se è una questione di impostazione logica/pianificazione o di poca conoscenza della semantica e della sintassi del linguaggio di programmazione, o del mettere insieme le due cose.

Quote
quando provo a modificarlo per le mie esigenze mi perdo nel codice e non ci capisco nulla.
Il codice è la trascrizione per una macchina di un'idea o modello mentale. Modificare il codice senza aver capito l'idea di chi lo ha pensato raramente porta a qualcosa di funzionante.

Quote
Vi prego dunque di aiutarmi a capire cosa non capisco
Ecco una sfida interessante...


Quote
In pratica, con questo irrigatore vorrei...
Qui hai descritto il dominio del problema in senso astratto, bene, è chiaro.

Quote
In poche parole la logica sarebbe questa: dalle ore hh:mm alle ore hh:mm attivo la pompa (relay1) e innaffio dal bidone. Subito dopo aver innaffiato si apre l'elettrovalvola e il bidone viene riempito nuovamente. Un rilevatore di troppopieno arresterà l'elettrovalvola a bidone riempito.
...vorrei inserire una pompa peristaltica che  una volta al mese prima di innaffiare andrà ad aggiungere all'acqua un po concime liquido e lo mescolerà con un agitatore magnetico ricavato da una ventola.
Qui hai descritto la logica in modo più schematico, benissimo, è già chiara, il modello mentale di cui parlavo parte da qui. Perché si tratta adesso di trovare un modo per "descriverla" usando gli strumenti messi a disposizione dalla macchina (ingressi/uscite hardware, istruzioni usabili ecc)... e non copiando o adattando cose scritte da altri che pensavano a logiche diverse (quello che hanno scritto gli altri va bene per vedere come hanno affrontato un singolo sottoproblema). In particolare è importante riuscire a ragionare per fasi di funzionamento, in tutto quello che hai descritto ne vedo almeno quattro o cinque ben precise... ci si può anche dare un nome, anzi, meglio farlo il prima possibile. Quando avrai identificato le fasi puoi chiederti: "in questa fase a quale evento devo prestare attenzione?", e successivamente: "quando avviene quell'evento quali azioni devo compiere? Ed eventualmente, se è il caso, in quale nuova fase di funzionamento mi dovrò trovare?". Prova a buttare giù uno schema su carta di fasi, eventi, azioni, prima in italiano, poi si vede come tradurlo in arduinese.


Quote
Ovviamente ho scopiazzato qua e la e tra l'altro non funziona neanche bene perchè funziona al contrario... in pratica dovrebbe accendersi alle 13,29 e spegnersi alle 13,30 mentre in questo lasso di tempo si spegne. Non a caso non sono riuscito a capire la variabile che si occupa dell'accensione:
Code: [Select]
 if ( Pompa[0] <= _hour && _hour <= Pompa[2] && Pompa[1] <= _minute && _minute <= Pompa[3]
Non funziona al contrario, porta alta l'uscita nell'intervallo previsto (purché non sia a cavallo tra due ore altrimenti può sbagliare), ma il modulo relè funziona a logica negativa, cioè il relé si attiva quando l'uscita di Arduino (ingresso del modulo) è bassa. Come hai già visto è bastato invertire HIGH con LOW.

Per il resto quale parte non è chiara nell'espressione logica che hai quotato?

Quote
Ne uscirò?
Mah  :)


Per quanto riguarda il controllo dei periodi orari, meglio lavorare con i minuti, in questo modo basta evitare un periodo a cavallo della mezzanotte:
Code: [Select]
int adesso = now.hour()*60 + now.minute();  // tempi da 0 a 1439 minuti
int inizio = Pompa[0]*60 + Pompa[1];
int fine   = Pompa[2]*60 + Pompa[3];

// Comando Pompa, no orari a cavallo della mezzanotte!!!
if ((adesso >= inizio) && (adesso < fine))
{
        digitalWrite(PINPOMPA, RELEACCESO);
}
else
{
        digitalWrite(PINPOMPA, RELESPENTO);
}
Una domanda ben posta è già mezza risposta.

maubarzi

Ottimo il suggerimento di @Claudio_FF che dice di scriverlo prima in italiano.
Aggiungo un suggerimento ulteriore, pensalo per essere interpretato da uno che ti rema contro e che alla minima frase ambigua sceglierà la strada opposta a quella che pensi tu.
Quindi cerca di essere il più preciso possibile e il più chiaro possibile.
A costo di essere super elementare. Ad es. se dici di scrivere una cosa assicurati prima che ci siano il foglio e la penna e che la penna scriva, non so se hai capito cosa intendo...
Se riesci a fare questo, poi si tratterà solo di tradurre il tutto in C++ e puoi farlo un pezzo per volta chiedendo e imparando.
Pensa semplice e vedrai che ne uscirai.
Nessuna buona azione resterà impunita!

Preistoria -> medioevo -> rinascimento -> risorgimento -> rincoglionimento!

karnhack

Ragazzi, innanzitutto grazie perché questo è proprio il tipo di aiuto che cercavo. Seguo con interesse i vostri consigli e stasera cercherò di fare uno schema. Per ora vi ringrazio per l'incoraggiamento.

karnhack

#5
May 24, 2019, 12:39 pm Last Edit: May 24, 2019, 12:44 pm by karnhack
Ho provato a fare uno schema di funzionamento... mentre ragionavo sulla fase 4 mi è venuta in mente la firma di @Claudio_FF  "if non è un ciclo" infatti non so se è corretto come ho fatto io. Che ne dite può andare lo schema logico?



Claudio_FF

#6
May 24, 2019, 05:40 pm Last Edit: May 24, 2019, 08:05 pm by Claudio_FF
'if' non è un ciclo perché è una decisione/ramificazione. I cicli sono 'while' 'do while' e 'for'. È che spesso scrivono qualcosa come "non mi funziona il ciclo if" :) Ma naturalmente non vuol dire che non si possa usare un 'if' in modo ciclico per valutare ripetutamente delle condizioni, anzi, ma la ripetizione è appunto creata con un' istruzione di ciclo come 'while' o 'for' e non con l' 'if' in se stesso.

Detto ciò, direi che la scomposizione in fasi è grosso modo la stessa che avevo pensato. Hai disegnato una via di mezzo tra un diagramma di flusso e un diagramma funzionale sequenziale. Questo è come lo avevo pensato (avevo scomposto la concimazione in due fasi diverse):



Nel tuo diagramma di differente c'è la fase 'input' che non mi è chiara, mentre io davo per scontato un funzionamento ciclico automatico, magari iniziante con la fase riempimento.

Le condizioni di passaggio da una fase all'altra (eventi) che ho scritto in rosso corrispondono ai rombi decisionali (if) del tuo schema. Vuol dire che l'intera sequenza logica si potrebbe gestire con soli sei 'if' principali, ma dipende dalla struttura/codifica che si vuole implementare.

1) Se il programma deve fare solo questo e non anche altre cose "in parallelo", allora può bastare dettagliare meglio ogni singolo blocco sotto forma di diagramma di flusso completo. Se il diagramma prevede solo blocchi di istruzioni sequenziali, ramificazioni 'if' e ripetizioni 'while'/'for' la traduzione in C è in pratica uno a uno, e restano solo i dettagli sintattici. Le varie durate possono essere realizzate con la funzione 'delay'.

2) Se invece si vuole scrivere un programma più "generale", che potrebbe nel frattempo fare anche altre cose, allora servono una struttura e ragionamento diversi, più affini al concetto di ciclo di scansione di un PLC (le operazioni vengono portate avanti in cicli/passaggi successivi e i ritardi sono realizzati con la permanenza in una fase per un certo numero di cicli fino al riconoscimento di un evento).

La prima via sembra più semplice da affrontare perché la sequenza delle istruzioni corrisponde esattamente al pensiero: faccio questo, poi questo e poi quest'altro. La seconda invece è un po' più tecnica e interessante, perché tante cose si riescono a fare solo con questa, ed è più facilmente modificabile per aggiungere o togliere funzionalità senza stravolgere o ripensare tutto.

Comunque direi che la logica c'è, adesso va dettagliata e tradotta in macchinese...
Una domanda ben posta è già mezza risposta.

karnhack

#7
May 24, 2019, 06:20 pm Last Edit: May 24, 2019, 06:23 pm by karnhack
Nel tuo diagramma di differente c'è la fase 'input' che non mi è chiara, mentre io davo per scontato un funzionamento ciclico automatico, magari iniziante con la fase riempimento.
E' che non sapevo da dove iniziare quindi ho pensato di partire dall'inserimento dei dati.
Pensando meglio al progetto mi sono accorto che sarebbe opportuno tenere conto dei mesi non solo per quanto riguarda la concimazione ma anche per avere diversi orari di innaffiatura in base al mese. Per esempio gestendo i "tempi" di innaffiatura mese per mese durante le 4 stagioni (climaticamente parlando), d'estate potrei annaffiare di sera dopo una giornata di sole cocente, mentre d'inverno potrei annaffiare la mattina per evitare gelate notturne.

Mi piace che sei partito dal riempimento, ci avevo pensato ma pensavo di complicarmi le cose, invece dal tuo schema sembra semplice e logico fare così.

Claudio_FF

#8
May 24, 2019, 06:41 pm Last Edit: May 24, 2019, 07:46 pm by Claudio_FF
E' che non sapevo da dove iniziare quindi ho pensato di partire dall'inserimento dei dati.
Che però è una macrofunzione decisamente complessa. Alla fine dovrebbe popolare una matrice di dati mese->ora, che per semplicità si può anche già scrivere a mano nel programma, poi a complicare c'è sempre tempo.

Piuttosto vedrei utili altre funzionalità manuali... che so, scarico del bidone senza riempimento successivo, ciclo di annaffiatura (e/o concimazione) manuale, interruzione dell'operazione in corso... e altro a fantasia. Basta aggiungere fasi ed eventi (e pulsanti :D). Si può anche aggiungere una segnalazione di allarme se il rabbocco va in timeout (guasto al sensore di pieno o mancanza di acqua) ecc.

Come idea, se si indica la fase attualmente attiva con un valore contenuto in una variabile (ad esempio di nome... uhmm... 'fase'), nel loop ad ogni giro si può semplicemente chiamare una funzioncina diversa per ogni fase. Successivamente aggiungere o togliere fasi è immediato e non bisogna stravolgere nessun lungo codice.
Una domanda ben posta è già mezza risposta.

karnhack

#9
May 24, 2019, 07:46 pm Last Edit: May 24, 2019, 07:47 pm by karnhack
Che però è una macrofunzione decisamente complessa. Alla fine dovrebbe popolare una matrice di dati mese->ora, che per semplicità si può anche già scrivere a mano nel programma, poi a complicare c'è sempre tempo.
Sono assolutamente d'accordo a semplificare la cosa, anche perchè altrimenti rischierei di avere solo gli schemi in mano e senza una riga di codice. Anche per quanto riguarda pulsanti,  lcd ed altro per ora eviterei per lo stesso motivo che ho citato sopra.

Si può anche aggiungere una segnalazione di allarme se il rabbocco va in timeout (guasto al sensore di pieno o mancanza di acqua) ecc.
Potrei anche utilizzare una valvola galleggiante (meccanica, tipo quella del wc) sopra al sensore, così nel caso di guasto del sensore comunque non strasborda.

Ora però da dove comincio? mi riferisco all'arduinese...

Maurotec

#10
May 24, 2019, 08:19 pm Last Edit: May 24, 2019, 08:20 pm by Maurotec
Quote
Ora però da dove comincio? mi riferisco all'arduinese...
Hai iniziato bene quando ti sei concentrato a fare accendere o spegnere la pompa, penso che debba continuare da questi dettagli, uno preso in modo isolato.

Ora se sai già che la pompa si dovrà accendere e spegnere in base ad una serie di condizioni potresti pensare di creare una funzione dal nome gestisciPompa (waterPumpManage). All'interno della funzione farai i test con le if (<condizioni>), dove <condizioni> sono variabili globali.

Code: [Select]


void pumpManage() {

    if( now.hour()==15 && now.minute()==36) {

      digitalWrite( pinPompa,LOW );

    } else {

       digitalWrite( pinPompa,HIGH );
    }
}    


Così intanto riduci la quantità di righe di codice all'interno del loop e sai dove andare a guadare quando si presenta un problema con la pompa.

Ciao.

Claudio_FF

#11
May 24, 2019, 09:27 pm Last Edit: May 25, 2019, 10:23 am by Claudio_FF
O ecco, ero giù a prendere pizze... e poi prova te a spiegare a un'amica totalmente non tecnica che non guardi la TV perché passi il tempo libero su questo forum "inutile" :smiley-mr-green:

E torniamo a noio... si, l'idea è di scomporre in piccole funzioni (che alla fine possono corrispondere alle fasi).

Tra l'altro partendo dallo schema delle fasi viene particolarmente naturale/facile procedere top-down lasciando i dettagli alla fine (e l'intero programma può essere scritto quasi tutto in italiano).

Ora... "da dove comincio" dipende anche da cosa si sa.

Come detto prima ci sono vari modi per procedere. Quello focalizzato sulle fasi secondo me è il più generale e adattabile a ogni tipo di progetto, sia single task che multi task.

Ma occorrono delle basi sintattiche...

Io comincerei con lo scrivere le due funzioni obbligatorie vuote. Definirei una variabile globale 'fase' per indicare la fase di funzionamento attuale, e la inizializzerei al valore della prima fase che voglio attiva all'accensione (il valore associato ad ogni fase è naturalmente una convenzione, e se a questi valori diamo dei nomi, ad esempio con define, diventa tutto molto più chiaro).

Poi nel loop scriverei un selettore (if/else if o switch) che in base al valore di questa variabile richiami una funzione o un'altra, e quindi scriverei tutte queste funzioni vuote.

Così c'è già l'ossatura per tutta la logica.

Adesso dentro le funzioni vanno scritte le operazioni da svolgere e i test (controllo eventi) per vedere se è ora di cambiare fase. Per cambiare fase basta semplicemente scrivere nella variabile 'fase' il valore della nuova fase attiva e terminare la funzione tornando al selettore.

Tutto questo è arabo e torniamo indietro, o continuiamo?

Diamo per buono questo schema fasi?

Una domanda ben posta è già mezza risposta.

Maurotec

Quote
Adesso dentro le funzioni vanno scritte le operazioni da svolgere e i test (controllo eventi) per vedere se è ora di cambiare fase. Per cambiare fase basta semplicemente scrivere nella variabile 'fase' il valore della nuova fase attiva e terminare la funzione tornando al selettore.

Tutto questo è arabo e torniamo indietro, o continuiamo?
Tradotto in codice,

Code: [Select]

#define PH_START 0
#define PH_RUN  1
#define NEXT_PHASE( ph ) ph = ph+1
byte currentPhase = PH_START;

void helloPrint() {
    serial.println("Hello Word!");
    NEXT_PHASE(currentPhase);  // passa alla prossima fase
    // currentPhase = PH_RUN;      // fase scelta in modo arbitrario
}

void setup() {
    serial.begin(57600);
}

void loop() {
    switch (currentPhase) {
    case PH_START:
        helloPrint();
        break;
    case PH_RUN:
        // rimane in questa fase fino a che non modifichiamo la il contenuto della variabile
        // currentPhase.
        break;
    }   // end switch currentPhase
}   //end loop



Si tratta solo di un esempio per fare capire cosa intende @claudio con define.

Ciao.

karnhack

Innanzitutto ringrazio tutti e due per il tempo dedicato. Rispondendo a @ Claudio_FF non è arabo ma è Bergamasco (senza offesa ovviamente)  :smiley-sweat:
Da quello che capisco  dall'esempio di @Maurotec si definiscono prima le fasi, nell'esempio PH_START, PH_RUN e NEXT_PHASE e poi con il void loop si avvia il ciclo che passa sequenzialmente da una fase all'altra finchè non viene fermato dalla stringa break;.
Poi ci sono tante piccole cosette che mi sfuggono per esempio

Code: [Select]

#define PH_START 0
#define PH_RUN  1
#define NEXT_PHASE( ph ) ph = ph+1
byte currentPhase = PH_START; // byte (valore da 0 a 255) trasforma currentPhase in PH_START che ha valore 0 ????

void helloPrint() {
    serial.println("Hello Word!");
    NEXT_PHASE(currentPhase);  // qui mi perdo... NEXT_PHASE sarebbe PH_START che è 0 + 1 e dunque stiamo avviando la PH_RUN??
    // currentPhase = PH_RUN;      //invece qui contrariamente alla riga sopra non stiamo usando una logica variabile (passatemi il termine) ma stiamo semplicemente dicendo che la fase attuale è 1
}

void setup() {
    serial.begin(57600);
}

void loop() {
    switch (currentPhase) { // qui si inizia il flusso partendo da currentPhase che è 0
    case PH_START:  // mi pare di capire che qui si descrivono i vari flussi:
        helloPrint(); // flusso 1 stampa Hello Word
        break;        //  blocca il flusso
    case PH_RUN:  // questo è Bergamasco...
        // rimane in questa fase fino a che non modifichiamo la il contenuto della variabile
        // currentPhase.
        break;
    }   // end switch currentPhase
}   //end loop



Ho commentato le stringhe in modo da rendere visibile le lacune o meglio ancora le lagune nella quale sono immerso. Ne usciro?  :smiley-small:

maubarzi

#14
May 25, 2019, 12:01 pm Last Edit: May 25, 2019, 12:04 pm by maubarzi
Cerco di tradurtelo un pelino:

Code: [Select]

#define PH_START 0 // PH_START verrà sostituito con 0 prima della compilazione
#define PH_RUN  1 // PH_RUN verrà sostituito con 1 prima della compilazione
#define NEXT_PHASE( ph ) ph = ph+1 // NEXT_PHASE(ph) verrà sostituito con l'istruzione ph = ph + 1 prima della compilazione;
// Questo:
byte currentPhase = PH_START; // byte (valore da 0 a 255) trasforma currentPhase in PH_START che ha valore 0 ????
//diventa
byte currentPhase = 0; // Che è il valore di partenza all'avvio o al reset di Arduino.

void helloPrint() {
    serial.println("Hello Word!");
    // questo:
    NEXT_PHASE(currentPhase);  // qui mi perdo... NEXT_PHASE sarebbe PH_START che è 0 + 1 e dunque stiamo avviando la PH_RUN??
    // diventa;
    currentPhase = currentPhase + 1;
    // Questo invece è un esempio se si vuole impostare un valore fisso e diventerebbe: currentPhase = 1;
    // currentPhase = PH_RUN;      //invece qui contrariamente alla riga sopra non stiamo usando una logica variabile (passatemi il termine) ma stiamo semplicemente dicendo che la fase attuale è 1
}

void setup() {
    serial.begin(57600);
}

void loop() {
// Lo switch è un test che analizza il valore currentPhase ed esegue il case con lo stesso valore e tutti i successivi fino a quando non trova il break;
    switch (currentPhase) { // qui si inizia il flusso partendo da currentPhase che è 0
    case 0:
        helloPrint(); // flusso 1 stampa Hello Word e aumenta di 1 currentPhase, quindi lo fa diventare uguale a 1 e al prossimo giro di loop verrà eseguito il case 1
        break;        //  blocca il flusso, più precisamente fa uscire dallo switch saltando i case successivi. Se non lo metti esegue anche il case 1
    case 1:
        // rimane in questa fase fino a che non modifichiamo la il contenuto della variabile:
        // currentPhase. esatto!
        break;
    }   // end switch currentPhase
}   //end loop

Ho chiarito un po' di più o aumentato solo la confusione?
Nessuna buona azione resterà impunita!

Preistoria -> medioevo -> rinascimento -> risorgimento -> rincoglionimento!

Go Up