Go Down

Topic: Nuovo problema con i timers (Read 889 times) previous topic - next topic

ziopippo

May 22, 2018, 11:33 am Last Edit: May 22, 2018, 11:36 am by ziopippo
Dovrei programmare una Nano in modo che im faccia partire una prima ventola ogni ora per soli 6 secondi ed una seconda ventola mezz'ora dopo la prima sempre per soli 6 secondi; Il tutto per tutta la giornata per un totale di 24 partenze.
Ho tentato di usare la libreria TimeAlarms ma non riesco ad ottenere ciò che voglio.
Questo è lo sketch (non fate caso alle tempistiche perchè le ho ridotte per non attendere un'ora e mezz'ora igni volta).


Code: [Select]
#include <TimeLib.h>
#include <TimeAlarms.h>

int rele1 = 5;  // dichiaro il pin D5
int rele2 = 7; // dichiaro il pin D7


void setup() {
  // put your setup code here, to run once:

  pinMode (rele1, OUTPUT );
  digitalWrite(rele1, HIGH );
  pinMode (rele2, OUTPUT );
  digitalWrite( rele2, HIGH );
  Serial.begin(57600);
  Alarm.timerRepeat(360, motore1);           // timer for every 3600 seconds}

  Serial.println("Avvio programma");

  motore1();
  delay(3000);
  motore2();
}
void loop() {
  Alarm.delay(0); // wait one second between clock display

}


void motore1()
{
  digitalWrite( rele1, LOW );
  Serial.println("Accendo la prima ventola");
  Alarm.timerOnce(0, 0, 6, EndFunction1); // tra quanto tempo in ore, minuti, secondi intervenire
  Alarm.timerRepeat(180, motore2);           // timer for every 1800 seconds}
}

void EndFunction1()
{
  digitalWrite( rele1, HIGH );
  Serial.println("Spengo la prima ventola");
}

void motore2()
{
  digitalWrite( rele2, LOW );
  Serial.println("Accendo la seconda ventola");
  Alarm.timerOnce(0, 0, 6, EndFunction2); // tra quanto tempo in ore, minuti, secondi intervenire
}

void EndFunction2()
{
  digitalWrite( rele2, HIGH );
  Serial.println("Spengo la seconda ventola");
  Serial.println("==============================================");
}
[/code

Silente

Ho un paio di osservazioni da fare:
1)Così come postato il codice dovrebbe dare errore, visto che manca la loop()
2)Perché per spegnere un relè imposti un uscita alta?
3)Personalmente (ma è questione di stile) avrei fatto due funzioni, e non quattro, una Inizia (byte indice) e una Finisci (byte indice), si che, ponendo i relè in un array si aveva la scalabilità de progetto con meno funzioni di quelle attuali. Ripeto che è solo questione di stile, non dovrei sindacare.
4)Ammetto la mia ignoranza in merito all'uso delle librerie utilizzate per il timer, che cercherò e andrò a studiare. Mi domando solo una cosa: sono veramente necessarie? Non sarebbe meno dispendioso in termini di spazio memoria e tempo di studio codice usare la funzione millis() in via diretta?(ed ovviamente tutto il corollario per creare un timer basato su essa)
Dove va un numero va una variabile, una funzione e/o  un test.
Per ottenere devi spiegare

Strumenti/Formattazione automatica fino alla morte!
Cristianesimo:bibbia='C':K&R

Silente

Dove va un numero va una variabile, una funzione e/o  un test.
Per ottenere devi spiegare

Strumenti/Formattazione automatica fino alla morte!
Cristianesimo:bibbia='C':K&R

ziopippo

Grazie per la risposta.
Per spegnere uso l'uscita alta perché purtroppo ho saldato al contrario.
Nulla toglie che posso cambiare la piedinatura.
Per il punto 3 non ho le competenze per realizzarlo.
Per l'uso di millis ho pensato che l'uso della libreria sia più comoda e veloce. Se sai indicarmi una strada (Con esempio possibilmente) più facile te ne sarei più che grato. ;)

Silente

Se il problema è che non hai le conoscenze puoi comprarti o scaricarti un buon manuale dici dove tutte queste cose sono scritte. Puoi anche andare a cercare in internet esempi di funzioni scritte da qualcuno oppure librerie e leggerti come sono strutturate o anche come si accende un LED senza usare delay().
Chiaramente il posto dove meglio si possono trovare queste informazioni è il sito di Arduino forum incluso, dove se ne parla parecchio, soprattutto di Millis. Personalmente sconsiglio altre fonti in quanto non esiste un controllo effettivo che funzionano realmente, e spesso si trovano programmi che non funzionano.
Quanto alla parte funzioni con argomento non è al momento importante da sapere, In quanto come ho detto si può anche evitare, Soprattutto se si conoscono le esatte dimensioni di quello che sarà il progetto.
Per quanto riguarda, invece, millis(), ti basta cercare in una pagina qualunque del forum lato software o generale e troverai uno o più topic in cui il nostro fantastico moderatore Guglielmo posta una serie molto lunga di link relativi al suo utilizzo.
Dove va un numero va una variabile, una funzione e/o  un test.
Per ottenere devi spiegare

Strumenti/Formattazione automatica fino alla morte!
Cristianesimo:bibbia='C':K&R

fabpolli

L'inversione della piedinatura non è un problema, anche alcune schede relé in commercio si comportanto con uscita a LOW per attivare il relé e HIGH per disattivarlo quindi puoi lasciare il tutto così com'è.
Tralasciando i discorsi di stile, uso o non uso di una libreria piuttosto che millis ti dico subito che visto i tempi lunghi a cui fai riferiento (ore/giorni) con librerie o millis non vai da nessuna parte poiché ogni giorno perderai alcuni secondi che alla fine di fanno spostare le ore di accensione di molto tempo. Se questo non è un problema allora puoi andare avanti su questa strada, se invece la temporizzazione è importante dovrai dotare il tuo progetto di un RTC (Real time clock) trovi tonnellate di esempi di uso sul forum e su interne e anche li librerie già pronte, invece per capire le basi con cui si usa millis() consiglio prima la lettura di QUESTO post esplicativo, dopo di che lo studio di come si usa la funzione millis(), prima QUI, poi QUI e QUI e QUI e tutti gli articoli che sono in QUESTA pagina ... alla fine il tutto dovrebbe essere più chiaro :)

ziopippo

Allora giusto per chiarire, millis l'ho già usato per altri progetti però ho pensato che forse avere una libreria che faceva al caso mio piuttosto che impazzire con millis sarebbe stato più facile ;)
Per la perdita del tempo a me interessa che i motori si accendono 24 volte al giorno ciascuno e a distanza di 30 minuti l'uno dall'altro.
Tutto qui.

fabpolli

Se il tempo inteso come ore/minuti precisi di accensione non ti interessa allora l'RTC potrebbe non servire, la libreria in questione purtroppo non la conosco e non posso aiutarti in modo più efficace, magari prova a descrivere ciò che succede con il codice che hai postato magari ci si arriva per deduzione, es. dopo 10 secondi si accente ma non si spegne dopo il tempo impostato, oppure si dovrebbe accendere la seconda ventola ma non si accende ecc.

Claudio_FF

#8
May 22, 2018, 07:47 pm Last Edit: May 22, 2018, 07:54 pm by Claudio_FF
Se la precisione non serve (quindi i circa 2 .. 5 minuti di errore all'ora sono ininfluenti) e nello stesso tempo la nano non deve fare nessun'altra operazione, mi sembra che il buon vecchio delay sia la soluzione più semplice.

ventola 1 accesa
attendi 6 sec
ventola 1 spenta
attendi  1794 secondi
ventola 2 accesa
attendi 6 secondi
ventola 2 spenta
attendi 1794 secondi
ripeti all'infinito

La sequenza di 24 accensioni potrebbe durare da 22 a 26 ore, se serve più precisione (salvo ritoccare i delay a occhio) occorre un riferimento diverso dall'oscillatore interno non quarzato, quindi un RTC (anche non regolato, tanto basta contare il cambio dei secondi, anche letti con un pin digitale dall'uscita SQW dell'RTC) o una frequenza esterna come i 50Hz di rete ecc.
* * * * Una domanda ben posta è già mezza risposta * * * *

Standardoil

Io voto per la libreria, più lineare e più generalizzabile
comunque, un consiglio
non incasinarti con funzioni che armano alarmtimer che chiamano funzioni che armano timer che.....

per accendere una ventola nella setup metti solo
Code: [Select]

Alarm.timerRepeat(3600, motore1);           // un ora

e accendi la prima
giustamente all'accensione della prima devi prenotare il suo spegnimento
Code: [Select]

Alarm.timerOnce(30, EndFunction1); // tra quanto tempo in secondi spegnere

il problema è far partire sfalsata la seconda
e qui ci vuole un trucco: nella setup metti
Code: [Select]

Alarm.timerOnce(1800, sfalsamezzora); // mezzora

che tra mezzora esegue una cosa del genere
Code: [Select]

Alarm.timerRepeat(3600, motore2);           // un ora

come vedi esegui una sola volta una inizializzazione di un timer ripetuto
Non presurrò più la buona fede di chi:
NON indenta, USA la classe String o NON esegue le ricerche
E di chi non risponde alle domande Tante volte è stato segnalato che è sbagliato, quindi NON sono in buona fede
Non bado a studenti, che copino altrove

Standardoil

Per ClaudioFF
vedo adesso la tua firma
posso usarla anch'io?
è una meraviglia...
Non presurrò più la buona fede di chi:
NON indenta, USA la classe String o NON esegue le ricerche
E di chi non risponde alle domande Tante volte è stato segnalato che è sbagliato, quindi NON sono in buona fede
Non bado a studenti, che copino altrove

ziopippo

Io voto per la libreria, più lineare e più generalizzabile
comunque, un consiglio
non incasinarti con funzioni che armano alarmtimer che chiamano funzioni che armano timer che.....

per accendere una ventola nella setup metti solo
Code: [Select]

Alarm.timerRepeat(3600, motore1);           // un ora

e accendi la prima
giustamente all'accensione della prima devi prenotare il suo spegnimento
Code: [Select]

Alarm.timerOnce(30, EndFunction1); // tra quanto tempo in secondi spegnere

il problema è far partire sfalsata la seconda
e qui ci vuole un trucco: nella setup metti
Code: [Select]

Alarm.timerOnce(1800, sfalsamezzora); // mezzora

che tra mezzora esegue una cosa del genere
Code: [Select]

Alarm.timerRepeat(3600, motore2);           // un ora

come vedi esegui una sola volta una inizializzazione di un timer ripetuto
Hai colto nel segno.
Il mio problema infatti non era accendere 1 ventola e spegnerla dopo 6 secondo e ripetere all'infinito il ciclo ma, riuscire a far partire la seconda senza che facesse casini (così come mi capita)
Grazie provo e ti aggiorno

ziopippo

Per ClaudioFF
vedo adesso la tua firma
posso usarla anch'io?
è una meraviglia...
L'ho notata anche io giorni fa ed è piaciuta tanto anche a me ma, credo che si farà pagare caro i copyright...  :)  :)

Patrick_M

ma dopo tutte le pagine scritte su timerOnce e timerRepeat...... :( :(
per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)

Standardoil

OK, ammetto i miei limiti, se ci sono soluzioni migliori le ascolto molto volentieri,
questa della alarm.timer è un po' un punto di ombra per me....
Non presurrò più la buona fede di chi:
NON indenta, USA la classe String o NON esegue le ricerche
E di chi non risponde alle domande Tante volte è stato segnalato che è sbagliato, quindi NON sono in buona fede
Non bado a studenti, che copino altrove

Go Up