Buongiorno a tutti, è la prima volta che provo ad usare la funzione millis() ma ho un problema...
Non mi fustigate, so che sarà una cavolata assurda ma il mio cervello si è bloccato...
Devo fare la seguente cosa:
Pompa peristaltica che mi dosa una certa quantità di prodotto ogni 7 giorni.
Ho ragionato nel seguente modo:
Contatore sulle ore che viene incrementato ogni volta che passa 1 ora, quando raggiunge le le 24 ore incrementa il giorno e resetta le ore.
Quando i giorni arrivano a 7 eroga e resetta i giorni e ricomincia il tutto.
Ora probabilmente ho sbagliato ad usare millis() ma non capisco dove...
Per velocizzare il debug ho calcolato 1 ora = 30secondi:
Il comportamento che mi fa è il seguente:
-prima iterazione: diff=-300000 che va a scendere e quando arriva a 0 mi incrementa correttamente il contatore dell'ora
-seconda iterazione: ora=1, diff=-300000 che scende correttamente e incrementa le ore a 2
-terza iterazione: ora=2, diff=-600000
-quarta iterazione: ora=3, diff=-1200000
e cosi via....raddoppia sempre...non mi spiego il perchè....
so che sarà una stupidaggine....mi date una mano?
long attesa = 30000; //1 ora 3600000
int ora = 0; //contatore ore
int day = 0; //contatore giorni
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(2, OUTPUT);
digitalWrite(2, HIGH);
}
void loop() {
long diff = millis() - attesa;;
Serial.print("diff= ");
Serial.println(diff);
if ((diff >= 0) && (ora < 24)) {
ora++;
Serial.print("ore= ");
Serial.println(ora);
attesa = attesa + millis();
}
if (ora == 24) {
day++;
Serial.print("giorno ");
Serial.println(day);
ora = 0;
}
if (day == 7) {
digitalWrite(2, LOW);
delay(13500);
digitalWrite(2, HIGH);
day = 0;
}
}
Da una rapida occhiata direi che il problema è che ogni volta sommi il valore di millis() al precedente di "attesa", col risultato che attendi sempre più tempo. In ogni caso non capisco bene perché tu abbia progettato la cosa in "logica inversa" ossia cercare un valore negativo (costringendoti ad usare una variabile "signed") invece di contare il tempo trascorso a partire dal precedente istante di conteggio ore.
Intendo una cosa di questo tipo:
const unsigned long ATTESA = 3600000; //1 ora 3600000
unsigned long prevMillis = 0; // Valore di millis() dell'ora precedente
int ora = 0; //contatore ore
int day = 0; //contatore giorni
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(2, OUTPUT);
digitalWrite(2, HIGH);
prevMillis= millis();
}
void loop() {
unsigned long diff = millis() - prevMillis;
Serial.print("diff= ");
Serial.println(diff);
if ((diff >= ATTESA) && (ora < 24)) {
ora++;
Serial.print("ore= ");
Serial.println(ora);
prevMillis= millis();
if (ora == 24) {
day++;
Serial.print("giorno ");
Serial.println(day);
ora = 0;
if (day == 7) {
digitalWrite(2, LOW);
delay(13500);
digitalWrite(2, HIGH);
day = 0;
}
}
}
PS: comunque millis() non è preciso, meglio affidarsi ad un RTC...
Grazie mille a tutti;) @speedyant so che vado a perdere sempre qualcosa ma per quello che serve a me va più che bene, in realtà ho anche acquistato il modulo rtc perchè vorrei gestire la mancanza di corrente (anche se la probabilità è remota nella mia città) ma devo ancora studiarmi come funziona, non ne ho la minima idea;) Quindi diciamo l'idea finale (parliamo di gestione di un acquario) completa è quella di una pompa che mi gestisca la fertilizzazione e di un altra che mi gestisca il rabocco. Sicuramente mi sposterò sul modulo rtc ma me lo devo studiare....
@Standardoil non lo so usare....questo era il mio codice per gestire la settimana con millis()
@docdoc In logica inversa mi è venuto spontaneamente, non so il perchè...cmq ti ringrazio, il tuo funziona perfettamente, me lo vado un attimo a studiare;)
Il valore restituito da millis su un normale Arduino con risonatore ceramico sbaglia di circa 2 minuti al giorno, circa un quarto d'ora a settimana, è accettabile?
Questa non la sapevo, nel senso sapevo si perdesse qualcosa ma non così tanto. Diciamo che di base se volessi fare una cosa "accroccata" andrebbe anche bene, fertilizzare sempre alla medesima ora non mi serve, mi serve sia più o meno ogni 7 giorni. Di sicuro cmq ci metterò il modulo per fare una cosa più precisa, devo solo studiarmelo un attimo;)
Mi sembra (ma non sono sicuro) che con il quarzo puoi perdere o guadagnare, dipende dall'errore e dalla qualita' del quarzo, da 2 a 4 secondi al giorno (nel peggiore dei casi, un minuto ogni 15 giorni circa)
Sera a tutti, un curiosità...oggi era il grande giorno della fertilizzazione che doveva avvenire intorno alle 19. Ma non sono riuscito a capire se sarebbe avenuta....vi spiego il perchè, ho attaccato ora il cavo usb per vedere che cosa stampava a video (arduino è alimentato da un alimentatore 12v con stepdown a 9v), ho aperto il monitor e il conteggio era partito da zero...dico che coincidenza, stacco e riattacco e riparte da zero...è normale che ogni volta che attacchi il cavo il conteggio riparta?? Penso di no...perchè mi fa così? Ora ho fertilizzato a mano e il prog se non riattacco usb dovrebbe irrigare sabato prossimo intorno alle 18....
Ogni volta che si apre la porta seriale, Arduino si autoresetta. È un comportamento voluto per semplificare la programmazione. Ma diventa non voluto in questi casi. Per eliminare l'autoreset di solito basta collegare un condensatore da 10 µF tra reset e GND.