Migliorare Timer Progetto

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

Tutto dipende da COME scrivi la funzione. Postane una che vediamo. Poi chiaramente la devi richiamare nel loop() al posto giusto.
Poi ti do un consiglio: non farti prendere dalla funzionmania, non riempire di funzioni. Metti in funzione quello che ripeti uguale (o quasi) nel loop, così vinci un terno all'otto

Silente:
vinci un terno all'otto

Fatto n1: non è di Napoli

testato:
Fatto n1: non è di Napoli

:smiley:

Fabiok89:
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

questo lo puoi fare a prescindere da dove hai scritto le istruzioni di "preparazione", la separazione in funzioni serve più che altro a semplificarti la vita nella stesura dei programmi ma non è strettamente necessaria al loro funzionamento. Aumentano la leggibilità ma il fatto di richiamare una funzione dal loop oppure mettere in quel punto tutte le istruzioni della funzione come dicevo non cambia proprio nulla. quindi la nuova schermata devi essere capace di implementarla... a prescindere :wink:

Patrick_M:
:smiley:

questo lo puoi fare a prescindere da dove hai scritto le istruzioni di "preparazione", la separazione in funzioni serve più che altro a semplificarti la vita nella stesura dei programmi ma non è strettamente necessaria al loro funzionamento. Aumentano la leggibilità ma il fatto di richiamare una funzione dal loop oppure mettere in quel punto tutte le istruzioni della funzione come dicevo non cambia proprio nulla. quindi la nuova schermata devi essere capace di implementarla... a prescindere :wink:

Io la schermata sono riuscito a riempirla... Ma ovviamente questo comporta un'altro errore che nn capisco quale... Sopra avevo creato uno sketch solo con il timer... E funziona perfettamente... Mi lampeggiano le cifre che mi interessano... Ecc... Ricopio tutto nel codice principale... I valori non mi cambiano e nn mi lampeggiano le cifre... Stesso identico codice... Appena arrivo a casa vi posto il tutto