Migliorare Timer Progetto

E' da un po' che non utilizzo un display lcd ma da quel che mi ricordo setCursor lo devi fare per indicare le coordinate del primo carattere che stampi, se gli altri seguono dopo non devi indicarne per ognuno la coordinata in modo progressivo

     lcd.setCursor(7, 0);
      lcd.print(".");
      delay(1000);
      lcd.setCursor(8, 0);
      lcd.print(".");
      delay(1000);
      lcd.setCursor(9, 0);
      lcd.print(".");
      delay(1000);
      lcd.setCursor(10, 0);
      lcd.print(".");
      delay(1000);
      lcd.setCursor(11, 0);
      lcd.print(".");

lo puoi scrivere direttamente così:

     lcd.setCursor(7, 0);
      lcd.print(".");
      delay(1000);
      lcd.print(".");
      delay(1000);
      lcd.print(".");
      delay(1000);
      lcd.print(".");
      delay(1000);
      lcd.print(".");

meglio ancora scriverlo così:

      lcd.setCursor(7, 0);      
      for (int i=0; i <= 5; i++)
      {
            lcd.print(".");
            delay(1000);
      }

Per gestire il countdown ti consiglio di dare un occhiata alla libreria timer che ti permette di settare un data/ora in modo abbastanza semplice.
Quello che posso dirti sul tuo codice è che non mi piace per nulla il sistema adottato per resettare il tutto, capisco che funziona ma non è proprio quello che di solito si consiglia di fare.
Ti consiglio di cercare sul forum "macchina a stati finiti" e gestire con quel metodo tutto all'interno del loop (alla fine è semplicissimo, una variabile di stato e un case).
Per l'inserimento del tempo la libreria dell'lcd ha il metodo blink() e noBlink() che ti fanno lampeggiare il cursore, quando sei in attesa del tempo ti basta posizionare il cursore e attvare il blick, ad ogni settaggio sposti il cursore e alla fine chiami la noBlink

fabpolli:
Per gestire il countdown ti consiglio di dare un occhiata alla libreria timer che ti permette di settare un data/ora in modo abbastanza semplice.
Quello che posso dirti sul tuo codice è che non mi piace per nulla il sistema adottato per resettare il tutto, capisco che funziona ma non è proprio quello che di solito si consiglia di fare.
Ti consiglio di cercare sul forum "macchina a stati finiti" e gestire con quel metodo tutto all'interno del loop (alla fine è semplicissimo, una variabile di stato e un case).
Per l'inserimento del tempo la libreria dell'lcd ha il metodo blink() e noBlink() che ti fanno lampeggiare il cursore, quando sei in attesa del tempo ti basta posizionare il cursore e attvare il blick, ad ogni settaggio sposti il cursore e alla fine chiami la noBlink

Ciao ho provato a dare una lettura a quello che mi hai consigliato... Piano piano renderò il. Codice più "pulito".. Ma per ora il mio obiettivo è sistemare l'impostazione del timer...

Hai qualche esempio da consigliarmi... Non ho trovato nulla che fa al caso mio sulla rete

-zef-:
E' da un po' che non utilizzo un display lcd ma da quel che mi ricordo setCursor lo devi fare per indicare le coordinate del primo carattere che stampi, se gli altri seguono dopo non devi indicarne per ognuno la coordinata in modo progressivo

     lcd.setCursor(7, 0);

lcd.print(".");
     delay(1000);
     lcd.setCursor(8, 0);
     lcd.print(".");
     delay(1000);
     lcd.setCursor(9, 0);
     lcd.print(".");
     delay(1000);
     lcd.setCursor(10, 0);
     lcd.print(".");
     delay(1000);
     lcd.setCursor(11, 0);
     lcd.print(".");



lo puoi scrivere direttamente così:


lcd.setCursor(7, 0);
     lcd.print(".");
     delay(1000);
     lcd.print(".");
     delay(1000);
     lcd.print(".");
     delay(1000);
     lcd.print(".");
     delay(1000);
     lcd.print(".");



meglio ancora scriverlo così:


lcd.setCursor(7, 0);      
     for (int i=0; i <= 5; i++)
     {
           lcd.print(".");
           delay(1000);
     }

Grazie mille appena posso modifico il codice come mi hai suggerito... Mi puoi spiegare cosa vuol d'ore l'espressione accanto al for così ci capisco qualcosa. Sn entrato da poco in questo mondo e già aver sistemato un codice del del genere per me è un immenso traguardo

Prova a cercare sul reference, li il for probabilmente lo trovi

Fabiok89: come ti ha indicato "silente", fai sempre riferimento al reference di Arduino dove puoi trovare tutto quello che riguarda il linguaggio oppure ... la Bibbia :smiley:

Guglielmo

Silente:
Prova a cercare sul reference, li il for probabilmente lo trovi

Ah ok

Allora mi consigliate di riscrive il codice per quanto riguarda il timer... E nn cercare di modificare questo già funzionante?

Va bene modificarlo, ti ho solo detto di cercare cosa fa il or e cone funziona, come tu hai chiesto di sapere nel tuo post 3 ultima parte

un'altra cosa come programma simulativo cosa mi consigliate...?ne ho provati un paio online ma non hanno tutti i componenti che servono per il mio progetto

inv x quanto riguarda modificare il timer nessuno mi può aiutare?

Quanto a proramma simulativo suggerisco di non utilizzarlo, e fare i test su fisico, perché poi ci sono problemi tipo "sul simulatore funzionava, ora no", tanto una volta che hai fatto il circuito di fumo non ne esce

:smiley: o al limite esce subito alla prima accensione :smiley:

buon giorno...in questi giorni ho apportato delle piccole modifiche come suggerito da -zef- e da fabpolli per tenere il codice un pò più pulito da leggere

invece per quanto riguarda il timer ancora sn in alto mare, non riesco a trovare nessun esempio da seguire, su internet si trovano solo video di gente che usa il potenziometro e lo shield per impostare il countdown

qualcuno riesce a spiegarmi cosa devo modificare per aggiungere le ORE e visualizzare quando devo inserire i valori H00:M00:S00

questi sn i due codici che m gestiscono il timer

codice per inserire i valori del tempo( per ora è impostato a 4 cifre)

void inseriretempo() {
  lcd.setCursor(0, 0);
  lcd.print("Inserire Tempo:");
  while (currentTimeValue < 4)

  {
    // lcd.print("H00:M00:S00");
    lcd.setCursor(currentTimeValue + 6, 1);
      lcd.cursor();
    char key = keypad.getKey();
    key == NO_KEY;
    if (key != NO_KEY)
    {
      if ((key != '*') && (key != '#') && (key != 'A') && (key != 'B') && (key != 'C') && (key != 'D')) //caratteri non permessi
      {

        lcd.print(key);
        tempo[currentTimeValue] = key;
        currentTimeValue++;
      }
    }
  }
  if (currentTimeValue == 4)
  {
    delay(2000);
    lcd.noCursor();
    lcd.clear();
    lcd.setCursor(1, 0);
    lcd.print("Start in 5 Sec");
    lcd.setCursor(6, 1);
    for (int i = 0; i <= 4; i++) // ripete x 5 volte quello scritto tra {}
    {
      lcd.print((char)0); // richiama la clessidra
      delay(1000);
    }
    lcd.clear();
    currentTimeValue = 0;
  }
}

e questo è il void che mi converte i valori in minuti e secondi se non mi sbaglio

void settaggiotempo() {

  int l;
  char tempVal[3];
  char key = keypad.getKey();
  if (currentState == 1) {
    tempVal[0] = tempo[0];
    tempVal[1] = tempo[1];
    tempVal[2] = 0;
    
    timerSeconds = atol(tempVal) * 60;

    tempVal[0] = tempo[2];
    tempVal[1] = tempo[3];
    tempVal[2] = 0;

    timerSeconds = timerSeconds + atol(tempVal);
    currentState = 2;
  }

  if (lpcnt > 9) {
    lpcnt = 0;
    --timerSeconds;
    tone(buzzer, 1500, 500);
    countdown();

    if (timerSeconds <= 0) {
      currentState = 1;
      temposcaduto();
    }
  }
  ++lpcnt;
  delay(100);
}

rieccomi dopo qualche giorno...

Vi faccio un piccolo riassunto...alla fine ci sn riusci a settare le cose come dice io

però è nato un'altro probblema
vengo al dunque

siccome ho scritto tutto il codice nel loop(se lo metto fuori non mi funziona) ho il problema di resettare lo schermo nei vari passaggi la funzione lcd.clear() non va perché mi fa lampeggiare lcd esiste qualche altra soluzione, qualcuno ha qualcosa da consigliarmi su come procedere?

Senza l'attuale codice si fa poco
2)
La funzione lcd.clear() DEVE fare quello per cui é nata, quindi non é lei che non funziona. Puoi aver manomesso quello che vuoi ma mi rifiuto di credere che una funzione che tutti usano in un certo modo (cancellando lo schermo) lo faccia lampeggiare. Il problema deriva esclusivamente da come la si utilizza.
3)
L'architettura in funzioni DEVE funzionare, quanto é vero che Arduino funziona, quindi il problema sarà certamente in come le funzioni vengono fatte
4)
IL modo per cancellare un lcd é O quella funzione O riempirlo di spazi

>Fabiok89: è chiaro che se chiami a raffica (cosa che avviene se la metti nel loop()) la lcd.clear() hai un effetto tipo lampeggio ...
... o la chiami SOLO quando realmente ti serve di pulire TUTTO il display o pulisci (scrivendoci sopra degli spazi) solo le parti che ti serve pulire.

Guglielmo

praticamente dopo che inserisco la pass devo impostare il tempo...

il codice è scritto in modo che prima inserisco il tempo e dopo parte il countdown,non capisco il perchè ma il countdown me lo esegue subito(scrivendomi le scritte)

il problema e nelle ultime 5 righe, sicuramente sto sbagliando qualche valore

void codice2()
{
  lcd.print("Inserisci Tempo:");
  //updateDisplay();
  char key = keypad.getKey();
  //lcd.setCursor(0,1);
  //      lcd.print("H00:M00:S00");
  if (key != NO_KEY)
  {
    switch (conDig)
    {
      case 0:

        lcd.setCursor(conPos, 1);  // conPos = 0. Horas. First Digit.
        if (key <= '2')
        {
          lcd.print(key);
          conPos = 1;              // Moves the cursor at row 1 (the second one).
          conDig++;                // Moves on to the next case, with the cusor already in row 1.
          H = (key - 48) * 10;
        }
        break;
      case 1:
        lcd.setCursor(conPos, 1);   // conPos = 1. Horas. Second digit.
        lcd.print(key);
        lcd.print(":M ");
        conPos = 4;
        conDig++;
        H = H + (key - 48);
        break;
      case 2:
        lcd.setCursor(conPos, 1);   // conPos = 3. Minutos. Third digit.
        if (key <= '5')
        {
          lcd.print(key);
          conPos = 5;              // Moves the cursor at row 4 (the fifth one).
          conDig++;                // Moves on to the next case.
          M = (key - 48) * 10;
        }
        break;
      case 3:
        lcd.setCursor(conPos, 1);    // conPos = 4. Minutos. Forth digit.
        lcd.print(key);
        lcd.print(":S ");
        conPos = 8;
        conDig++;
        M = M + (key - 48);
        break;
      case 4:
        lcd.setCursor(conPos, 1);    // conPos = 6. Segundos. Fifth digit.
        if (key <= '5')
        {
          lcd.print(key);
          conPos = 10;
          conDig++;
          S = (key - 48) * 10;
        }
        break;
      case 5:
        lcd.setCursor(conPos, 1);    // conPos = 7. Segundos. Sixth digit.
        lcd.print(key);
        //  lcd.print(".");
        conDig++;
        S = S + (key - 48);
        break;
      case 6:

        timer();
    }
    while (conDig == 6)
    {
      // lcd.clear();
      // timer();
      confermapassword();
    }
  }

}

Allora finalmente dopo milioni di correzioni ne sono venuto a capo.
Sono riuscito a fare funzionare il tutto a dovere e secondo quello che mi ero prefissato all'inizio

Sto diventando pazzo su l ultima cosa, vorrei aggiungere un trattino al di sotto della cifra che sto per modificare iniziando da sinistra quindi prima le 2 cifre delle ore e cosi via, oppure fare lampeggiare lo 0 che deve essere modificato.

Sto avendo problemi con la prima cifra di Ore ,Minuti e secondi, con la seconda cifra funziona alla perfezione

di seguito vi condivido tutto lo sketch del timer , in questo momento l ho impostato con lcd.blink() all'inizio del caso 0 e lcd.noBlink() alla fine del caso 5 ,ma come detto sopra mi accontento anche di lcd.cursor()

qualcuno mi può spiegare dove sto sbagliando?

#include <Keypad.h>                     
#include <LiquidCrystal_I2C.h>


LiquidCrystal_I2C lcd(0x27, 16, 2);

const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'#', '0', '*', 'D'}
};
byte rowPins[ROWS] = {5, 4, 3, 2}; //pin delle righe
byte colPins[COLS] = {9, 8, 7, 6}; //in delle colonne

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

int conPos = 1;            // Position Counter variable that controls the position of the cursor.
int conDig = 0;            // Digital Counter variable the controls the case switching.

int ledPin = 9;            // LED connected to digital pin 9. Is used in the alarm.

int h = 0;             // This variables will store time values.
int m = 0;
int s = 0;


void setup()
{
  lcd.init();   // Configures the number of columns and rows in the LCD.
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Inserisci Tempo!");   // Prints a message in the LCD. "Introduce time".

  lcd.setCursor(0, 1);
  lcd.print("H00:M00:S00");

}

void loop()
{
  char key = keypad.getKey();

  if (key != NO_KEY)

  {

    switch (conDig)
    {

      case 0:
        lcd.blink();
        lcd.setCursor(conPos, 1);  // conPos = 0. Horas. First Digit.

        if (key <= '2')
        {
          lcd.print(key);
          conPos = 2;              // Moves the cursor at row 1 (the second one).
          conDig++;                // Moves on to the next case, with the cusor already in row 1.
          h = (key - 48) * 10;

        }
        break;
      case 1:

        lcd.setCursor(conPos, 1);   // conPos = 1. Horas. Second digit.
        lcd.print(key);
        //lcd.print(":M ");
        conPos = 5;
        conDig++;
        h = h + (key - 48);

        break;
      case 2:

        lcd.setCursor(conPos, 1);   // conPos = 3. Minutos. Third digit.
        if (key <= '5')
        {
          lcd.print(key);
          conPos = 6;              // Moves the cursor at row 4 (the fifth one).
          conDig++;                // Moves on to the next case.
          m = (key - 48) * 10;
        }

        break;
      case 3:
        lcd.setCursor(conPos, 1);    // conPos = 4. Minutos. Forth digit.
        lcd.print(key);
        //lcd.print(":S ");
        conPos = 9;
        conDig++;
        m = m + (key - 48);
        break;

      case 4:
        lcd.setCursor(conPos, 1);    // conPos = 6. Segundos. Fifth digit.
        if (key <= '5')
        {
          lcd.print(key);
          conPos = 10;
          conDig++;
          s = (key - 48) * 10;
          break;

        case 5:
          lcd.setCursor(conPos, 1);    // conPos = 7. Segundos. Sixth digit.
          lcd.print(key);
          conDig++;
          s = s + (key - 48);
          lcd.noBlink();
          delay(2000);
          break;
        }
    }
    while (conDig == 6)
    {
     Timer();
    }
  }

}

Se non ho capito male vorresti subito far lampeggiare sulla prima cifra delle ore, quindi nel setup dopo aver stampato H00:M00:S00 metti una setcurso nella posizione della prima cifra delle ore e metti li il blink, non appena finisce il setup inizia a lampeggiare sulla prima cifra delle ore, il resto non ho capito esattamente cosa non va perché a regola il blink continua finche non lo interrompi co0n la noblink quindi dovrebbe funzionare il codice così come l'hai scritto

Silente:
Nel momento in cui Arduino esegue la break di un case non esegue gli altri. Di conseguenza

  1. la lcd.blink() la esegue solo se entra nel case 0
  2. la lcd.noblink la esegue solo se entra nel case 5.

Se vuoi che valgano per tutti i casi basta metterli una prima dell'inizio e una dopo la fine dello switch

perfetto già ci avevo provato ma la prima cifra di ore min e sec non lampeggia...invece lampeggiano i : prima delle M e della S e poi appena aggiungo un valore passa direttamente al secondo 0 di ogni sezione

fabpolli:
Se non ho capito male vorresti subito far lampeggiare sulla prima cifra delle ore, quindi nel setup dopo aver stampato H00:M00:S00 metti una setcurso nella posizione della prima cifra delle ore e metti li il blink, non appena finisce il setup inizia a lampeggiare sulla prima cifra delle ore, il resto non ho capito esattamente cosa non va perché a regola il blink continua finche non lo interrompi co0n la noblink quindi dovrebbe funzionare il codice così come l'hai scritto

grazie...ok ci siamo quasi...ora lampeggiano i : dei minuti e dei secondi appena inserisco la cifra passa direttamente al secondo valore H00 tutto ok - :M00 lampeggiano i punti e il secondo 0 - :S00 stessa cosa...come risolvo?

#include <Keypad.h>                       // We include the libraries. 
#include <LiquidCrystal_I2C.h>


LiquidCrystal_I2C lcd(0x27, 16, 2);

const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'#', '0', '*', 'D'}
};
byte rowPins[ROWS] = {5, 4, 3, 2}; //pin delle righe
byte colPins[COLS] = {9, 8, 7, 6}; //in delle colonne

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

int conPos = 1;            // Position Counter variable that controls the position of the cursor.
int conDig = 0;            // Digital Counter variable the controls the case switching.

int ledPin = 9;            // LED connected to digital pin 9. Is used in the alarm.

int horas = 0;             // This variables will store time values.
int minutos = 0;
int segundos = 0;


void setup()
{
  lcd.init();   // Configures the number of columns and rows in the LCD.
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Inserisci Tempo!");   // Prints a message in the LCD. "Introduce time".

  lcd.setCursor(0, 1);
  
  lcd.print("H00:M00:S00");
  lcd.setCursor(conPos,1);
lcd.blink();
}

void loop()
{
  char key = keypad.getKey();

  if (key != NO_KEY)
  {
    switch (conDig)
    {

      case 0:
        lcd.blink();
        lcd.setCursor(conPos, 1);  // conPos = 0. Horas. First Digit.

        if (key <= '2')
        {
          lcd.print(key);
          conPos = 2;              // Moves the cursor at row 1 (the second one).
          conDig++;                // Moves on to the next case, with the cusor already in row 1.
          horas = (key - 48) * 10;

        }
        break;
      case 1:

        lcd.setCursor(conPos, 1);   // conPos = 1. Horas. Second digit.
        lcd.print(key);
        //lcd.print(":M ");
        conPos = 5;
        conDig++;
        horas = horas + (key - 48);

        break;
      case 2:

        lcd.setCursor(conPos, 1);   // conPos = 3. Minutos. Third digit.
        if (key <= '5')
        {
          lcd.print(key);
          conPos = 6;              // Moves the cursor at row 4 (the fifth one).
          conDig++;                // Moves on to the next case.
          minutos = (key - 48) * 10;
        }

        break;
      case 3:
        lcd.setCursor(conPos, 1);    // conPos = 4. Minutos. Forth digit.
        lcd.print(key);
        //lcd.print(":S ");
        conPos = 9;
        conDig++;
        minutos = minutos + (key - 48);
        break;

      case 4:
        lcd.setCursor(conPos, 1);    // conPos = 6. Segundos. Fifth digit.
        if (key <= '5')
        {
          lcd.print(key);
          conPos = 10;
          conDig++;
          segundos = (key - 48) * 10;
          break;

        case 5:
          lcd.setCursor(conPos, 1);    // conPos = 7. Segundos. Sixth digit.
          lcd.print(key);
          conDig++;
          segundos = segundos + (key - 48);
          lcd.noBlink();
          delay(2000);
          break;
        }
    }
    while (conDig == 6)
    {
      comienza();
    }
  }

}

Tu fai una setCursor per posizionare il cursore e visualizzare la cifra inserita, poi aumenti la posizone che dovrà assumere il cursore (conDig) ma non riposizioni il cursore finché l'utente non inserisce la cifra.
Per risolvere fuori dallo switch metti

lcd.setCursor(conPos, 1);

Ma noto anche un altro problema, sulla prima cifra verifichi che il valore inserito sia minore o uguale a due, si suppone quindi che non vuoi gestire ore superiori alle 24 ore, ma nei case successivi non c'è traccia di controlli, ovvero l'utente dopo aver messo il primo due è libero di imputare H29:M59:S59

Silente:
Nel momento in cui Arduino esegue la break di un case non esegue gli altri. Di conseguenza

  1. la lcd.blink() la esegue solo se entra nel case 0
  2. la lcd.noblink la esegue solo se entra nel case 5.

Se vuoi che valgano per tutti i casi basta metterli una prima dell'inizio e una dopo la fine dello switch

Una volta invocato il metodo blink il cursore continua a lampeggiare finché non viene invocato il metodo noBlink quindi non serve eseguirlo ad ogni ciclo di loop