problemi con mills

Salve a tutti, sto riscontrando un problema che non riesco proprio a capire e naturalmente a risolvere…

controllo tramite arduino uno un PCB dove vi sono svariate cose implementate tra cui

Mediante I2C controllo:

  • nr 1 LCD 16x2
  • Mediante MCP23008 una serie di relè
  • MEdiante MCP23008 una serie di ingressi digitali
  • nr 3 Motori DC

poi ho un encoder rotativo, una sonda NTC una sonda K controllata da un modulo MAX6675

Ho iniziato a programmare il tutto (in modo non molto professionale) tutto bene, nel senso che come potete vedere mediante le varie librerie riesco a controllare il tutto…

ho impostato una variabile di nome STATO con la quale controllo a che punto sono e impostandola manualmente riesco a saltare parti del programma già funzionanti come ad esempio il reset dei vari motori DC e a fargli fare certe cose nel loop solo quando ne ho bisogno.

Vengo al dunque… a un certo punto del programma (stato==11) mediante l’encoder rotativo posso variare il valore di una variabile di nome timerA, mediante un pulsante la confermo e passo oltre…
dopo altri passaggi di messaggi su lcd oppure di variazione di variabili si passa allo stato==20

Qui succede l’inghippo… dovrebbe partire un timer con mills della durata impostata dalla variabile
timerA ma quando parte non inizia dall’inizio ma ha già “consumato” molti secondi ho notato che dipende dal tempo che ci metto a confermare l’avvio dallo stato==14 allo stato==20…

ho provato a disabilitare varie cose esempio cancello il codice delle sonda K , metto sotto if il void dell’encoder ma nulla… lo stato==20 dove c’è l’istruzione currentmills parte sempre con molti secondi mangiati.

Perchè parte il timer già consumato?

allego il file .ino perchè è un pò lungo il codice da implementare nel messaggio
grazie a tutti

programmazione3.ino (8.87 KB)

Se ho capito il tuo programma, timerA è solo il valore limite, intervallo di tempo che deve superare millis() corrente con millis precedente. Ma tu quando in stato==11 imposti timerA devi impostare anche previousMillis=millis() altrimenti quando arrivi a stato==20 quel previous vale zero mentre comunque in tutto quel tempo millis() è andato avanti.
Oppure in quel stato==20 se previous è 0 allora lo setti a millis() (perchè comunque tra stato 11 e stato 20 passa del tempo)

Poi, se il confronto dell'if è sulla differenza tra current e previous (giusto), perchè stampi timerA.current ?
Serial.println("TIME: " + String(timerA - currentMillis) );
if (currentMillis - previousMillisA > timerA) {

P.S. quella stampa è molto dispendiosa, obblighi a conversioni tra variabili a oggetto String (molto pesante) quando basta spezzare la riga in due:
Serial.print("TIME: "); Serial.println(timerA - currentMillis);

Intanto usa di più l'istruzione if else, in modo che ad ogni loop il processore non debba fare tutte quelle IF: una volta trovata la IF giusta salta tutte le altre.
Poi la dichiarazione della variabile per millis falla all'inizio, in modo da non dichiararla continuamente nel loop.
Poi millis parte quando accendi Arduino e quando tu la vai a leggerla può avere qualsiasi valore che è sicuramente maggiore di ZERO.

Ringrazio tutti e due per le spiegazioni ma il mio cervello con millis() è andato in folle anzi in retro(succede con molte cose) comunque ho semplificato il codice in modo che lo posso postare ho sostituito premere un pulsante con un delay… ho fatto tutto quello che mi avete detto (non è sicuramente vero ma io ci credo) ho provato a mettere unsigned long currentMillis = millis(); in tutte le posizioni ma a me non funziona e non capisco perchè…

PS: per gli If… so di ripetere tutto molto ma volevo finire tutto il programma che funzionasse poi mi sarei messo a ottimizzare il codice…

#include <Wire.h>
int stato = 10; /////////////////// variabile che registra la cronologia degli eventi
////// TIMER 1
unsigned long timer = 200000; // Set value timer in milliseconds
unsigned long previousMillis = 0;
void setup() {
  Serial.begin(9600);
}
void loop() {

  if (stato == 10) {
    Serial.println("Ready to start");
    delay(5000);
    stato = 11;
  }
  if (stato == 11) {
    Serial.println("set timer: ");
    delay(5000);
    stato = 12;
  }
  if (stato == 12) {
    Serial.println("messaggio 1");
    delay(5000);
    stato = 13;
  }
  if (stato == 13) {
    Serial.println("messaggio 2 ");
    delay(5000);
    stato = 14;
  }
  if (stato == 14) {
    Serial.println("Press to start");
    Serial.println(timer);
    delay(5000);
    stato = 20;
  }
  if (stato == 20) {
    unsigned long currentMillis = millis();
    if (previousMillis == 0) {
      previousMillis = millis();
    }
    Serial.print("TIME: "); Serial.println(timer - currentMillis);
    if (currentMillis - previousMillis > timer) {
      previousMillis = currentMillis;
    }
  }
}

opppssss scusate ora funziona ho modificato la riga di output con questa riga:

Serial.print("TIME: "); Serial.println((timerA/1000) - ((currentMillis - previousMillisA)/1000));

Che Arduino usi?

int encoderPin1 = 7;
int encoderPin2 = 2;
...
pinMode(encoderPin1, INPUT_PULLUP);
pinMode(encoderPin2, INPUT_PULLUP);
attachInterrupt(0, updateEncoder, CHANGE);
attachInterrupt(1, updateEncoder, CHANGE);

Il pin 7 È un entrata Interupt?

Ciao Uwe

Il mio consiglio è di mettere l'istruzione

previousMillis = millis();

appena dopo l'istruzione

stato = 20;

In questo modo "inizializzi" il contatore nell'istante in cui fai partire il passo in cui viene usato.

Se fai come hai fatto :wink: di testare che il previous sia zero per "inizializzarlo", ti funziona solo una volta e non puoi ripetere il giro completo altre volte a meno di non rimetterlo a zero (operazione un po' anti-intuitiva) al termine del passo 20.

ciao, effettivamente avevo già spostato l'istruzione previousMillis = millis(); dopo lo stato=20

uso arduino uno, non so il pin7 cosè... ho trovato il codice esempio dell'encoder in qualche sito...
funzionava allora copio e incollo...

ora ho un altro problema non funziona la lettura della temperatura con la sonda K non fa loop legge solo una volta e non aggiorna... ma questo forse sarà un'altro post... prima vorrei arrivarci da solo.... :slight_smile: :slight_smile:

buon weekend a tutti