Migliorare Timer Progetto

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

Silente:
Grazie, non lo sapevo (non avevo neanche capito cosa facesse)

:o non prendertela a male... ma se non hai capito a cosa serve un istruzione dai dei suggerimenti così a casaccio???

fabpolli:
... dai dei suggerimenti così a casaccio???

... e, per di più, poi piglia e cancella il post così non si capisce più nulla ! Che brutto vizio che ha certa gente ... >:(

Guglielmo

levatemi l ultimo dubbio e poi chiudo il post...

sono riuscito a fare funzionare il tutto...xrò ho una domanda.. ho riletto questo codice 1ml di volte e non capisco perchè funziona solo nel loop()

se lo inserisco fuori dal loop non mi inserisce il valore da tastiera come se la tastiera non e collegata come mai?

beh, il loop è l'unica cosa che funziona... cioè dopo aver eseguito il setup, arduino ripete le istruzioni del loop e basta.
per eseguire "pezzi" fuori dal loop bisogna che questi "pezzi" siano delle funzioni complete e verranno eseguite solamente se nel loop ci sarà la chiamata a queste funzioni, eventuali pezzi o funzioni non chiamate non verranno eseguite
unica eccezzione le routine di interrupt... ma questo è un altro discorso :slight_smile:

Patrick_M:
beh, il loop è l'unica cosa che funziona... cioè dopo aver eseguito il setup, arduino ripete le istruzioni del loop e basta.
per eseguire "pezzi" fuori dal loop bisogna che questi "pezzi" siano delle funzioni complete e verranno eseguite solamente se nel loop ci sarà la chiamata a queste funzioni, eventuali pezzi o funzioni non chiamate non verranno eseguite
unica eccezzione le routine di interrupt... ma questo è un altro discorso :slight_smile:

Quindi come lo dovrei scrivere x farlo funzionare fuori dal loop?

devi fare una funzione

void miaFunzione(void) {
   //tutta la serie di istruzioni relative
   //alla funzione
   //in oggetto
   //per esempio 
   //una serie
   //di stampe
}
//poi nel loop quando ti serve la chiami
void loop() {
   miaFunzione();
   ...
   ...
}

questo è un esempio
ma per che motivo la vuoi spostare "fuori dal loop?

Patrick_M:
devi fare una funzione

void miaFunzione(void) {

//tutta la serie di istruzioni relative
  //alla funzione
  //in oggetto
  //per esempio
  //una serie
  //di stampe
}
//poi nel loop quando ti serve la chiami
void loop() {
  miaFunzione();
  ...
  ...
}



questo è un esempio
ma per che motivo la vuoi spostare "fuori dal loop?

xkè volevo inserire che dopo aver inserito il tempo spuntasse una nuova schermata con scritto "pronto" "premi un puls x iniziare" e parte un countdown pre-partita...che da il tempo di chiudere e posare la valigetta...

va bene grazie dell esempio...continuerò a fare delle prove