Aiuto per ritardo azione

Devo creare un ritardo piuttosto lungo senza che però si fermi tutto il programma ma non riesco a capire come fare. Mi spiego con altre parole: devo far accendere una ventola per 5minuti ogni ora.

ventola ON-> uscita arduino LOW ventola OFF->uscita arduino HIGH

Il delay non posso utilizzarlo perchè mi fermerebbe il programma per troppo tempo e quindi ho provato ad utilizzare millis ma anche così non riesco ad ottenere ciò che voglio.

int time=millis(); int letturaventolainterna_time_ON=millis(); int letturaventolainterna_time_OFF=millis();

time=millis(); if(time>letturaventolainterna_time_ON+10000){ ventolainterna(0); letturaventolainterna_time_ON=millis(); }

if(time>letturaventolainterna_time_OFF+20000){ ventolainterna(1); letturaventolainterna_time_OFF=millis(); }

p.s: per testare lo sketch ho utilizzato dei tempi brevi (10 e 20 secondi).

Se usi gli int di sicuro non funzionerà mai comunque ... millis() è un "unsigned long" !!!

Guglielmo

Ho sostituito int con long ma non funziona comunque. La ventola si accende e si spegne ma con tempi sballati.

teo94: Ho sostituito int con long ma non funziona comunque.

... unsigned long !!! ]:D

E comunque ... ... imposta il loop in cui c'è un primo IF che verifica il passare di ogni ORA ed allo scadere, reimposta il suo orario per la prossima scadenza oraria ed imposta anche l'ora di inizio del secondo che invece scade dopo 5 minuti ;)

Occorre entrare nella logica di come funziona millis() e del IF ( (millis() - tempoInizio) > durata ) ... una volta assimilato bene è piuttosto semplice ...

Guglielmo

Ho modificato così ma fa i tempi che vuole lui.
Resta spenta per circa 2secondi e rimane accesa per circa 30 secondi.

long time;
long letturaventolainterna_time_ON;
long letturaventolainterna_time_OFF;

nel setup:

time = millis();
letturaventolainterna_time_ON = millis();
letturaventolainterna_time_OFF = millis();

nel loop:
time=millis();

if(time>letturaventolainterna_time_OFF+20000){
ventolainterna(1);
letturaventolainterna_time_OFF=millis();
}

if(time>letturaventolainterna_time_ON+30000){
ventolainterna(0);
letturaventolainterna_time_ON=millis();
}

Le leggi le cose che scrivo o neanche le guardi ??? Perché altrimenti lascio perdere ...

E' la TERZA volta che ti dico che devi usare "unsigned long" NON int e NON long !!! La sai la differenza tra un signed ed un unsigned ??? ]:D ]:D ]:D

Finché non sistemi questa cosa non vado avanti ...

Guglielmo

P.S. : ... e [u]ristudiati[/u] i link su millis() perchè vedo che ancora NON hai le idee chiare QUESTO, QUESTO e QUESTO !

c'é un errore concettuale:

time=millis();
        if(time>letturaventolainterna_time_ON+10000){
        ventolainterna(0);
        letturaventolainterna_time_ON=millis();
        }
        
        if(time>letturaventolainterna_time_OFF+20000){
        ventolainterna(1);
        letturaventolainterna_time_OFF=millis();
        }

questo codice: spegne la ventola a intervalli di 10 secondi (ogni 10 secondi) e la accende ad intervalli ci 20 secondi (ogni 20 secondi) nel senso: secondi azione 10 spegne 20 spegene e poi accende 30 spegne 40 spegene e poi accende 50 spegne 60 spegene e poi accende

Una cosa simile vale per lo sketch che hai mandato nella Tua ultima risposta.

Ciao Uwe

Uwe, quel tuo esempio può soffrire del problema del "overflow" di millis() e, anche se non errato, è comunque da sconsigliare,

Infatti hai usato l'IF nel modo di confronto diretto invece che di differenza :

if( time > letturaventolainterna_time_ON+10000 ) {

e ci sarà un momento in cui la cosa non funzionerà più !!!

Il modo corretto per fare questi confronti è, tenendo contro che millis() è un "unsigned long" e dichiarando allo stesso modo le variabili :

if ( (time - letturaventolainterna_time_ON) > 10000) {

Guglielmo

Guglielmo, quel "esempio" é quello che teo94 ha pubblicato all inizio. Oltre a quello del problema nel overflow che segnali c'é il problema della non corretta impostazione dei intervalli che si acavallano.

Ciao Uwe

Oooppppssss :blush: :blush: :blush:

Pardon ... mi sembrava che TU stessi facendo un esempio ... non mi ero accorto che era il SUO codice ... "mea culpa" XD

Guglielmo

P.S. : ... a mia parziale discolpa c'è che ... se guardi l'ora ... m'ero appena alzato e ancora non ero del tutto sveglio :grin: :grin: :grin:

non preoccuoparti, non avevo notato quel problema che hai segnalato. Ciao Uwe

Se ti può interessare, ho scritto un articolo su come far eseguire dei compiti ad intervalli prestabilit usando millis.

Inoltre ho scritto una libreria che conta i secondi, la secTimer, puoi usarla come millis() applicando gli stessi principi del precedente articolo, con la differenza che, rispetto a millis, puoi contare intervalli fino a 136 anni ;)

leo72: Se ti può interessare, ho scritto un articolo su come far eseguire dei compiti ad intervalli prestabilit usando millis.

Già messo il link Leo ... pochi post più su ... :grin:

Guglielmo

ah, fate gara, come sta il punteggio? ;) ;) Ciao UWe

2 a 0 per me perché il link è stato messo 2 volte :stuck_out_tongue_closed_eyes:

Ho provato così ma ancora niente.

unsigned long previousMillis1 = 0; //will store last time LED was updated unsigned long interval1 = 10000; //interval at which to blink (milliseconds) unsigned long previousMillis2 = 0; unsigned long interval2 = 20000;

unsigned long time=millis(); unsigned long currentMillis = millis(); if (currentMillis - previousMillis1 > interval1) { previousMillis1 = currentMillis; //save the last time I blinked the LED ventolaesterna(1); } currentMillis = millis(); if (currentMillis - previousMillis2 > interval2) { previousMillis2 = currentMillis; //save the last time I printed on the serial ventolaesterna(0); }

Intanto mi scuso con gpb01 per l'incomprensione dell'unsigned. Il fatto è che sono ancora alle prime armi con arduino e quindi vi chiedo di portare pazienza.

Siccome quel codice lo hai preso dal mio articolo, ti posso garantire che è perfettamente funzionante. Quindi il problema deve risiedere in altro. Si può vedere l'intero sketch?

E’ nell’allegato.

AM2302_3_2_ino.ino (9.73 KB)

Senza offesa ma lo sketch o lo metti negli appositi tag [ code ] oppure, se molto lungo, lo alleghi al post. Poi non è neanche indentato bene, non si capiscono i blocchi di codice. Usate da IDE "Strumenti/Formattazione automatica". Le variabili si dichiarano ad inizio blocco, è più logico, altrimenti si fa confusione.

Sul perché non faccia non so, ancora non ho dato un'occhiata a tutto (sono a lavoro)

Guarda, se ho ben capito ciò che vuoi, per farlo bastano quattro righe in croce ... ... questo, ogni "periodo" secondi, accende per "durata" secondi il LED :

const byte pinLED = 13;               // pin del LED

const unsigned long periodo = 10000;  // periodo di 10 secondi
const unsigned long durata  =  3000;  // durata  di  3 secondi

unsigned long inizioPeriodo;
unsigned long inizioDurata;


void setup() {
   pinMode(pinLED, OUTPUT);
   digitalWrite(pinLED, HIGH);
   inizioPeriodo = millis();
   inizioDurata  = inizioPeriodo;
}

void loop() {
   if ( (millis() - inizioPeriodo) > periodo) {
      inizioPeriodo = millis();
      inizioDurata  = inizioPeriodo;
      digitalWrite(pinLED, HIGH);
   }
   //
   if ( (millis() - inizioDurata) > durata) {
     digitalWrite(pinLED, LOW);
   }
}

... testato e funzionante ! STUDIATELO !!!

Guglielmo