aiuto countdown timer

Salve ragazzi, sono qui a chiedere il vostro preziosissimo aiuto.
Come dicevo nella presentazione al forum, sono un novizio autodidatta, senza alcuna base di teoria elettronica, da qualche settimana alle prese con il fantastico mondo di Arduino, e sto via via imparando dai miei stessi errori e tentativi assorbendo da Internet (forum, siti e PDF) quanto più possibile.

Come era facile aspettarsi, adesso mi sono incagliato in un vortice senza fine che mi sta facendo impazzire.

Vi spiego il progetto: ho una scheda Arduino Uno connessa alla breadboard, alla quale ho collegato un LCD I2C, un paio di pulsanti (blu e rosso) e un paio di led (blu e rosso).

Il pulsante rosso accende il led rosso e spegne il led blu; il pulsante blu accende il led blu e spegne il led rosso.

Vorrei poter gestire un timer countdown (per comodità impostato a 10 minuti), che parta soltanto quando il led rosso è acceso e si fermi quando il led rosso è spento.

Nello sketch che vi propongo si riesce a gestire i led mediante i pulsanti, però il timer sembra partire dal momento in cui la scheda riceve corrente, e non da quando il led rosso si accende.
Ho messo la parte del timer dentro ad un "if", ma non ho ottenuto l'effetto voluto.

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C  lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
const int ledVerde = 3;
const int ledBlu = 4;
const int ledRosso = 5;

const int pulsBlu = 6;
const int pulsRosso = 7;

//variabili di HH MM e SS del timer
int S = 00;
int M = 10;
int H = 00;

unsigned long lastTick;

int lastButtonStateRed = LOW;        // stato precedente del pulsante
int lastButtonStateBlu = LOW;        // stato precedente del pulsante

int ledStateRed = HIGH;
int ledStateBlu = HIGH;

int buttonStateRed = 0;         // stato attuale del pulsante red
int buttonStateBlu = 0;         // stato attuale del pulsante blu

unsigned long buttonPushCounterRed = 0;   
unsigned long buttonPushCounterBlu = 0;   


unsigned long waithingRed = 10;   
unsigned long waithingBlu = 10;   

unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;


void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
  pinMode(ledVerde, OUTPUT);
  pinMode(ledBlu, OUTPUT);
  pinMode(ledRosso, OUTPUT);
  pinMode(pulsBlu, INPUT);
  pinMode(pulsRosso, INPUT);
}



void loop() {

  // sepremo il pulsante rosso si accende il led rosso

  int readingRed = digitalRead(pulsRosso);

  if (readingRed != lastButtonStateRed)
  {
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay)
  {
    if (readingRed != buttonStateRed)
    {
      buttonStateRed = readingRed;

      if ((buttonStateRed == HIGH))
      {
        digitalWrite(ledRosso, HIGH); //accendi il led red
        digitalWrite(ledBlu, LOW); //accendi il led red
      }
    }
  }

  lastButtonStateRed = readingRed;

  // sepremo il pulsante blu si accende il led blu

  int readingBlu = digitalRead(pulsBlu);

  if (readingBlu != lastButtonStateBlu)
  {
    lastDebounceTime = millis();
  }
  if ((millis() - lastDebounceTime) > debounceDelay)
  {
    if (readingBlu != buttonStateBlu)
    {
      buttonStateBlu = readingBlu;

      if ((buttonStateBlu == HIGH))
      {
        digitalWrite(ledBlu, HIGH); //accendi il led red
        digitalWrite(ledRosso, LOW); //accendi il led red
      }
    }
  }

  lastButtonStateBlu = readingBlu;




  // TIMER
  // se si accende il led rosso parte il timer, se si accende il blu si ferma

  lcd.setCursor(6, 1);
  lcd.print(":");
  lcd.setCursor(9, 1);
  lcd.print(":");

  if (digitalRead (ledRosso)) { //a questo punto dovrebbe partire il timer

    unsigned long currentMillis = millis();


    if (currentMillis - lastTick >= 1000) {
      S--;
      lastTick += 1000;
    }


    if (S < 0)
    {
      M--;
      S = 59;
    }

    if (S > 9)
    {
      lcd.setCursor(10, 1);
      lcd.print(S);
    }
    else
    {
      lcd.setCursor(10, 1);
      lcd.print("0");
      lcd.setCursor(11, 1);
      lcd.print(S);

    }

    if (M < 0)
    {
      H--;
      M = 59;
    }

    if (M > 9)
    {
      lcd.setCursor(7, 1);
      lcd.print(M);
    }
    else
    {
      lcd.setCursor(7, 1);
      lcd.print("0");
      lcd.setCursor(8, 1);
      lcd.print(M);

    }


    if (M > 59)
    {
      M = 0;
      H++;
    }


    if (H > 9)
    {
      lcd.setCursor(4, 1);
      lcd.print (H);
    }
    else
    {
      lcd.setCursor(4, 1);
      lcd.print("0");
      lcd.setCursor(5, 1);
      lcd.print(H);
      lcd.setCursor(6, 1);
      lcd.print(":");
    }

    //_____________________________________________________________
    // REGOLA PER LA FINE DEL CONTDOWN:
    // decido che alla fine del countdown il timer si fermi o riparta da un certo valore

    if (H < 0)
    {
      H = 00; //valore da cui voglio che il timer riparta - oppure 0
      M = 00; //valore da cui voglio che il timer riparta - oppure 0
      S = 00; //valore da cui voglio che il timer riparta - oppure 0
    }
  }
}

Potreste aiutarmi?

Per ora non ho tempo di provare il tuo codice, però qualche consiglio "generico" intanto vorrei dartelo.

Primo, indenta bene. Come si dice sempre, non è una questione "estetica" ma aiuta sia chi (come noi) deve leggere un codice scritto da altri, sia chi scrive il codice anche a fare più agevolmente debug.
Apri lo sketch nell'IDE e premi i tasti Ctrl-T (l'editor ci pensa a riformattarti il codice automaticamente) poi salva. E posta QUELLO.

Secondo, usa le funzioni. Per visualizzare le due cifre di ore, minuti e secondi tu ripeti sempre lo stesso pezzo di codice. Inoltre ci sono alcune "if()" evitabili e qualche setCursor() altrettanto superfluo.
Se ad esempio ti fai una funzione del tipo:

void mostraCifre(int riga, int col, int valore) {
 lcd.setCursor(col,riga);
 if(valore<10)
   lcd.print("0"); 
 lcd.print (H);
 }

puoi visualizzare il valore con un ben più leggibile:

  mostraCifre(4, 1, H);
  lcd.print(":");
  mostraCifre(7, 1, M);
  lcd.print(":");
  mostraCifre(10, 1, S);

Per il resto, stasera provo a vedere ma se tu riuscissi intanto a "rivedere" il tuo sketch con queste indicazioni ed a postare quello "migliore", sarebbe l'ideale...

grazie mille per i suggerimenti, appena possibile sistemo lo sketch seguendo le tue dritte.

mah se cè' uno sketch fatto strafatto e rifatto infinite volte, è qualche timer countdown

non so nemmeno quanti timer bromografi ci siano in giro (1 milione forse)

l 'acqua calda c'è gia

elrospo:
mah se cè' uno sketch fatto strafatto e rifatto infinite volte, è qualche timer countdown

Insomma, se uno copia e incolla codice non va bene perché così non impara niente, se cerca di farselo da sé non va bene perché già esiste codice fatto e strafatto. Decidetevi. :slight_smile:

Scherzi a parte, lui dice che è un autodidatta, e si sta impegnando per cercare di fare quello che ha in mente, per cui è al contrario apprezzabile e va aiutato non credi?

In realtà ho già risolto il mio problema usando la libreria Countimer, semplicissima da gestire e davvero comoda.

Vorrei solo capire come superare questo scoglio per migliorarmi, per comprendere meglio come usare Millis e fare un passo in più nel mio piccolo.