Uso di millis() per comandare 4 relè in base al tempo trascorso

Salve,
è la prima volta che scrivo in questo forum, però volevo un vostro aiuto riguardo alla programmazione di Arduino MEGA 2560.
Sto realizzando un progetto per l'università che permetta di stirare in maniera automatica.
Però sto trovando difficoltà per la programmazione, ho scritto tutto il codice ma non riesco a trovare il problema, dato che devo fare alcuni passaggi:

  1. Inizio con pulsante;
  2. Aziono 2 relè con ventola e nebulizzatore;
  3. dopo 15 secondi azione lampade ad infrarossi (gli altri due relè);
  4. Faccio funzionare il tutto per 7 minuti;
  5. Ultimi 3 minuti attivo solo le lampade ad infrarossi (solo due relè);
  6. Passati questi 10 minuti spengo tutto (relè).

Posto il codice.
Grazie :slight_smile:

sketch_IronX-v_01.ino (4.25 KB)

Un paio di consigli ...

  1. Indenta come si deve quel programma ... così com'è è illegibile ... l'IDE ti mette a disposizione una apposita funzione per farlo, basta andare su Tools --> Auto Format

  2. Riscrivilo seguendo la logica di una "macchina a stati finiti" ... identifica quindi i tuoi vari "stati" (attesa pulsante, ventole e nebulizzazione, infrarossi, solo infrarossi, fine) e usa millis() solo come tempo per far avanzare la "macchina" da uno stato all'altro.

Vedrai che ti si semplifica notevolmente ed inoltre lo renderai molto più flessibile (se domani dovessi aggiungere nuove funzionalità basterà aggiungere nuovi stati con le loro condizioni di entrata e di uscita).

Guglielmo

@Guglielmo mi ha preceduto.
Qui un esempio (semplice) in italiano di macchina a stati finiti: link

gpb01:
Un paio di consigli ...

  1. Indenta come si deve quel programma ... così com'è è illegibile ... l'IDE ti mette a disposizione una apposita funzione per farlo, basta andare su Tools --> Auto Format

  2. Riscrivilo seguendo la logica di una "macchina a stati finiti" ... identifica quindi i tuoi vari "stati" (attesa pulsante, ventole e nebulizzazione, infrarossi, solo infrarossi, fine) e usa millis() solo come tempo per far avanzare la "macchina" da uno stato all'altro.

Vedrai che ti si semplifica notevolmente ed inoltre lo renderai molto più flessibile (se domani dovessi aggiungere nuove funzionalità basterà aggiungere nuovi stati con le loro condizioni di entrata e di uscita).

Guglielmo

Grazie, ora proverò a fare un diagramma migliore e ... a indentare meglio!

Ah, @Luigi, ERRORONE !!
Attenzione che le variabili che usi per la millis() DEVONO essere "unsigned long" e non semplici int

int current_time quanti millis() può contenere prima di riempirsi?

realmeteo:
int current_time quanti millis() può contenere prima di riempirsi?

In che senso ?

... intanto comunque un "int" NON va bene perché è un valore con segno e quindi, se si volessero usare 16 bit dovrebbe essere un "unsigned int", poi, con tale tipo, si è limitati a 65535 msec ovvero circa un minuto e 5 secondi :slight_smile:

Guglielmo

Quindi devo scrivere 5 case, giusto?

Io comincerei a fare un bel disegno sulla carta della tua "macchina a stati logici" con le varie codizioni di entrata e di uscita dai vari stati, ecc. ecc. così da avere ben chiare le idee, tipo ...

... poi passerei alla codifica :slight_smile:

Guglielmo

Potrebbe andare?

Mi sembra di si :slight_smile:

Ora, con calma, uno step per volta provando che vada ... la codifica :wink:

Guglielmo

Edit: Probabilmente quello che hai messo come stato S3 NON è un vero stato, ma un qualche cosa che fai mentre sei nello stato S2 :wink:

gpb01:
Edit: Probabilmente quello che hai messo come stato S3 NON è un vero stato, ma un qualche cosa che fai mentre sei nello stato S2 :wink:

Infatti è più un if() dentro un while() :wink:
Anche se senza un delay() nella funzione suggerita rischieresti di sentire il tipico suono dei trick e track del relay del nebulizzatore con tutti i problemi del caso...

miky_police:
Infatti è più un if() dentro un while() :wink:
Anche se senza un delay() nella funzione suggerita rischieresti di sentire il tipico suono dei trick e track del relay del nebulizzatore con tutti i problemi del caso...

... in realtà dovrà fare un po' più di un IF (... per introdurre una certa isteresi) e nessun delay() :wink:

Guglielmo

Scusate, ma quelli che scrivo adesso sono pensieri in libertà, non voglio ferire nessuno, ma passatemi il termine, pensare di lato.
Diobono, scusate il francesismo. si tratta di tre timer in sequenza, non ingigantiamo, se dobbiamo gestire una macchina a stato finito per una semplice sequenza di 4 passi, cosa facciamo per una lavatrice? Compriamo i computer usati dalla NASA?
Il progetto si chiama IronX.
Negli anni sessanta alla AT&T stavano sviluppando un sistema operativo, si chiamava MULTICS con un paio di capriole è diventato UNIX.
Non facciamo lo stesso passo all'indietro, non facciamo tante capriole da doverlo poi chiamare IRONICS
secondo me tre timer, si comincia con delay per provare lo hardware, si termina con millis per far bel lavoro, e finito li

Standardoil:
Scusate, ma quelli che scrivo adesso sono pensieri in libertà, non voglio ferire nessuno, ma passatemi il termine, pensare di lato.

Esite sempre un modo di di risolvere le cose, che risolve un singolo problema e non insegna nulla, ed esistono modi che possono apparire più complessi, ma che risolvono più elegantemente e che, oltre ad essere infinitamente più flessibili (basta pensare ad espansioni future), sono anche molto più educatvi.

Chiara la differenza :smiling_imp:

Guglielmo

Chiarissimo

Standardoil:
Chiarissimo

Nora bene ... se una persona ha anni di esperienza, conosce alla perfezione la tecnica, il linguaggio e quant'altro, sono d'accordo che, molto probabilmente, risolverà il problema come dici tu, con quattro statements in croce e via :slight_smile:

Se però uno viene qui sul forum di Arduino e porre certi problemi, sicuramnete NON è della categoria suddetta ed ha bisogni di impare una tecnica generale che possa farlo crescere e che possa servigli anche per altre problematiche che potrà incontrare e allora ... ::slight_smile:

Guglielmo

La questione, dal mio punto di vista è cosi:
Io vedo tutti i giorni una sfilza di ingannieri che parlano una lingua in cui macchina s stati finiti è una delle parole più semplici e capibili, poi ci mettono neologismo è sigle anglo-avioniche che non ci si capisce un acca.
Poi a me tocca far diradare il fumo quando non sono capaci di calcolare l'angolo di accensione di un tiristore.
Ma è un problema di firmware certificato nella CPU del processore dedicato.....
Non sono mai loro ignoranti

KISS Keep It Simple Stupid
Ok, fine dei pensieri in libertà

Standardoil:
... Io vedo tutti i giorni una sfilza di ingannieri che parlano una lingua in cui macchina s stati finiti è una delle parole più semplici e capibili, poi ci mettono neologismo è sigle anglo-avioniche che non ci si capisce un acca. ...

... questo capita perché quelli studiano SOLO la teoria e NON sanno dove sta di casa la pratica :smiley: :smiley: :smiley:

Comunque ... siamo piuttosto OFF-TOPIC ... :drooling_face:

Guglielmo

Ma standardoil, è solo un modo diverso di risolvere il "problema" dal tuo punto di vista. Metti quattro confronti e finisce li... Plausi!!!
Il problema del relè continua a sussistere e fare trick e track... a meno che non si imposti sull'azionamento del nebulizzatore con valore di umidità <= 70 e un disinserimento con valore >=80 e allora il discorso potrebbe cambiare (bisogna vedere dove posizioni il sensore, se è lontano dal nebulizzatore, se è direzionato/vicino allo stesso)... Che il tuo intervento sia costruttivo...si, indubbiamente, ma in linea di massima...
Tanto tra 3 giorni ci sarà un altro topic intitolato "AIUTO CON MILLIS()"... a quel punto che faremo? gli diremo di nuovo che sono due banali confronti da fare con unsigned long e non servono i computer dismessi della nasa?