Aiuto per espandere il codice del mio progetto

Salve a tutti premetto che e la mia prima volta su questo tipo di programmazione…quindi siate clementi se commetto errori stupidi.

Allora veniamo al punto della situazione,con la mia squadra di softair abbiamo deciso di crearci un valigetta giocattolo molto semplice, Vi spiego più o meno quel’è la mia intenzione e cosa sono riuscito a fare:

1)avvio con scritta personalizzata ( e fino a qua ci sono riuscito)

2)settaggio di un conto alla rovescia tramite tastiera (e qui sorge il primo problema)

3)Inserimento di un password a 4 cifre per bloccare il conto alla rovescia( altro problema)

4)Ed in fine con il tasto " * " volevo riattivare la valigetta

Di tutto ciò che ho elencato sopra sono riuscito solo a programmare un countdown con tempo predefinito
da pc

ora di seguito li lascio lo sketch che sono riuscito a compilare girando su internet e utilizzando gli esempi sul programma

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

int S = 5; // count seconds
int M = 0; // count minutes
int H = 0; // count hours

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {4, 3, 2, 1}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {8, 7, 6, 5}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 

LiquidCrystal_I2C lcd(0x27, 20, 4); // set the LCD address to 0x27 for a 16 chars and 2 line display

void setup()
{
  lcd.init();                      // initialize the lcd
  // Print a message to the LCD.
  Serial.begin(9600);
  lcd.backlight();
  lcd.setCursor(4, 0);
  lcd.print("S.M.A.S.");
  lcd.setCursor(3, 1);
  lcd.print("La Bombaaa!");
  delay(5000);  //  tempo di attessa
  lcd.clear();
}

void loop()
{
  // lcd.clear();        // Start with a blank screen
  lcd.setCursor(3, 0);
  lcd.print ("Countdown!");
  lcd.setCursor(6, 1);
  lcd.print(":");
  lcd.setCursor(9, 1);
  lcd.print(":");

  S--;
  delay(1000);
  if (S < 0)
  {
   
    lcd.setCursor(1, 0);
    lcd.print("Tempo Scaduto");
    lcd.setCursor(3, 1);
    lcd.print("Sei Morto!");
    delay(5000);
    lcd.clear();
    lcd.setCursor(3, 0);
    lcd.print("Riavviare!");
    lcd.setCursor(4, 1);
    lcd.print("*SI  #NO");
    
    delay(100000);    //lcd.clear();
  }
  if (M < 0)
  {
    H--;
    M = 59;
  }
  if (H < 0)
  {
    H = 23;
    M = 59;
    S = 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);
    lcd.setCursor(9, 1);
    lcd.print(":");
  }

  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);
    lcd.setCursor(12, 1);
    lcd.print(" ");
  }

  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(":");
  }
}

praticamente da come vedete l’unica cosa che sono riuscito a fare e far spuntare a video le varie scritte senza la possibilità di interagire da keypad(anche se già nel codice ho inserito la funzione)

qualcuno di buon cuore e armato di tanta pazienza mi può aiutare per completare questo progetto

Purtroppo quello che vuoi fare non può essere fatto con l'istruzione delay(), ma devi usare millis(). Se googli "millis arduino" trovi anche dei tutorial che possono aiutarti. Puoi cominciare a studiare qualche esempio. Per quello che non capisci, siamo qua.

L'istruzione delay() blocca il funzionamento di arduino impedendogli sia di acquisire dati da tastiera sia di visualizzare alcunché sul display.

Ciao,
P.

Tutto quello che c'è da sapere su millis() lo trovi studiando prima QUI, poi QUI e QUI e QUI e tutti gli articoli che sono in QUESTA pagina ... vedrai che ti si chiariranno le idee :wink:

Guglielmo

Mi raccomando di capire bene il “problema” del millis() rollover…

speedyant:
Mi raccomando di capire bene il “problema” del millis() rollover…

falso problema se si usa il contatore (… perché altro non è) come si deve ! Ed in TUTTI quegli esempi è usato come si deve, quindi evitiamo di creare inutili “preoccupazioni”. :wink:

Guglielmo

mmm allora do una belle lettura a tutto e comincio con il sostituire il delay()

e per il fatto di acquisire dati da tastiera come faccio c’è qualche esempio che posso guardare?

Fabiok89:
e per il fatto di acquisire dati da tastiera come faccio c'è qualche esempio che posso guardare?

Immagino usi una libreria ... ::slight_smile:
... ogni libreria normalmente installa anche degli esempi che trovi tra gli esempi dell'IDE.

Guglielmo

da come vedi su…nel codice che ho postato uso la libreria Keypad.h

ho eseguito l esempio customkeypad(che poi ho riportato nel mio progetto)ho settato tutti i valori in base ai collegamenti che ho fatto ma non succede nulla sul display

hocapito xk non mi inserisce i valori…la tastiera che sto usando è mezza partita…infatti nel monitor seriale alcuni pulsanti non vanno…ho mandato a ritirare una tastiera a membrana 4x4 …appena mi arriva mi rimetto al lavoro…

intanto non c’è nessuno che mi può aiutare con il codice?

ho levato i delay() dal loop ed inserito i millis() cosi è corretto?

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

int S = 5; // count seconds
int M = 0; // count minutes
int H = 0; // count hours

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {4, 3, 2, 1}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {8, 7, 6, 5}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display

void Countdown(){
  
  }

void Password(){
  
  }
void setup()
{
  lcd.init();                      // initialize the lcd
  // Print a message to the LCD.
  Serial.begin(9600);
  lcd.backlight();                 //noBlacklight per oscurare schermo
  lcd.setCursor(4, 0);
  lcd.print("S.M.A.S.");
  lcd.setCursor(3, 1);
  lcd.print("La Bombaaa!");
  delay(5000);
  lcd.clear();

}

void loop()
{
  // lcd.clear();        // Start with a blank screen
  lcd.setCursor(3, 0);
  lcd.print ("Countdown!");
  lcd.setCursor(6, 1);
  lcd.print(":");
  lcd.setCursor(9, 1);
  lcd.print(":");

  S--;
  delay(1000);
  if (S < 0)
  {

    lcd.setCursor(1, 0);
    lcd.print("Tempo Scaduto");
    lcd.setCursor(3, 1);
    lcd.print("Sei Morto!");
    for (int x = 0; x < 5000; x++) {   // Wait for 1 second
      delay(1);
    }
    lcd.clear();
    lcd.setCursor(3, 0);
    lcd.print("Riavviare!");
    lcd.setCursor(4, 1);
    lcd.print("*SI  #NO");

    for (int x = 0; x < 100000; x++) {   // Wait for 1 second
      delay(1);
    }
    //lcd.clear();
  }
  if (M < 0)
  {
    H--;
    M = 59;
  }
  if (H < 0)
  {
    H = 23;
    M = 59;
    S = 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);
    lcd.setCursor(9, 1);
    lcd.print(":");
  }

  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);
    lcd.setCursor(12, 1);
    lcd.print(" ");
  }

  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(":");
  }
}
   delay(1000);
....
....
   for (int x = 0; x < 5000; x++) {   // Wait for 1 second
      delay(1);
    }
....
....
    for (int x = 0; x < 100000; x++) {   // Wait for 1 second
      delay(1);
    }

no, la prima riga e le successive 3 fanno la medesima cosa, bloccano il programma in quella posizione impedendo l’esecuzione di altre istruzioni

diverso è

unsigned long myOldTime;
unsigned long pausa= 5000;
...
...

    lcd.print("Sei Morto!");
    myOldTime= millis();

    if ( millis() - myOldTime >= pausa) {   // Wait for 5 sec
       lcd.clear();
       lcd.setCursor(3, 0);
       lcd.print("Riavviare!")
    } else {
       // esegui altre cose fino a quando la if diventa vera
    }

ciao sto provando a modificare il codice come mi hai suggerito tu e forse ci sono riuscito

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

unsigned long myOldTime;
unsigned long pausa = 5000;
int S = 5; // count seconds
int M = 0; // count minutes
int H = 0; // count hours

const byte ROWS = 4; //4 Righe
const byte COLS = 4; //4 Colonne

char hexaKeys[ROWS][COLS] = {  //definire i simboli e i numeri sulla tastiera
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {4, 3, 2, 1}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {8, 7, 6, 5}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display

void Countdown() {

}

void Password() {

}
void setup()
{
  lcd.init();                      // initialize the lcd
  // Print a message to the LCD.
  Serial.begin(9600);
  lcd.backlight();                 //noBlacklight per oscurare schermo
  lcd.setCursor(4, 0);
  lcd.print("S.M.A.S.");
  lcd.setCursor(3, 1);
  lcd.print("La Bombaaa!");
  delay(5000);
  lcd.clear();

}

void loop()
{
  // lcd.clear();        // Start with a blank screen
  lcd.setCursor(3, 0);
  lcd.print ("Countdown!");
  lcd.setCursor(6, 1);
  lcd.print(":");
  lcd.setCursor(9, 1);
  lcd.print(":");


  S--;
  delay(1000);
  if (S < 0)
  {
    lcd.setCursor(1, 0);
    lcd.print("Tempo Scaduto");
    lcd.setCursor(3, 1);
    lcd.print("Sei Morto!");
    myOldTime = millis();

    if ( millis() - myOldTime >= pausa) {   // Wait for 5 sec
      lcd.clear();
      lcd.setCursor(3, 0);
      lcd.print("Riavviare!");
    } else {
      // esegui altre cose fino a quando la if diventa vera
    }
  }
  if (M < 0)
  {
    H--;
    M = 59;
  }
  if (H < 0)
  {
    H = 23;
    M = 59;
    S = 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);
    lcd.setCursor(9, 1);
    lcd.print(":");
  }

  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);
    lcd.setCursor(12, 1);
    lcd.print(" ");
  }

  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(":");
  }
}

Però sul display una volta che il countdown finisce si sovrappone la scritta countdown (e il tempo continua a score in negativo,non c’è una funzione per bloccarlo a 00:00:00) e la scritta che spunta dopo cioè “Tempo Scaduto”/ “sei morto”

ho sbagliato ad inserire il codice?

Altra domanda con il codice del countdown che sto utilizzando va bene anche per quando inserirò la tastiera cosi da impostare il tempo che voglio dalla valigetta?

  S--;
  delay(1000);
  if (S < 0) {
    lcd.setCursor(1, 0);
    lcd.print("Tempo Scaduto");
    lcd.setCursor(3, 1);
    lcd.print("Sei Morto!");
    myOldTime = millis();

    if ( millis() - myOldTime >= pausa) {   // Wait for 5 sec
      lcd.clear();
      lcd.setCursor(3, 0);
      lcd.print("Riavviare!");
    } else {
      // esegui altre cose fino a quando la if diventa vera
    }
  }

gia fai il controllo quando S è minore di zero
e se non gli dici tu di smettere di fare s-- come fa a fermarsi il contatore?

Rieccomi a chiedere aiuto.

In questi giorni ho modificato un po il codice, girando per la rete ho trovato pezzi di codice che mi servivano per il progetto li ho incollati ma giustamente non funziona nulla (però lo sketch non ha errori)

sono riuscito anche a collegare una tastiera 4x4 e a farla funzionare
non sto riuscendo però a richiamare i 2 void che dovrebbero fare settare la password e il countdown,come posso richiamarli nella void setup?

vi riporto il codice aggiornato all’ultima modifica

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

unsigned long myOldTime;
unsigned long pausa = 5000;


int timeLength = 0;
int passLength = 0;
String mostra = "    ";
String password = "cccc";
String time = "    ";
boolean getted = true;
char last = 'p';
boolean timeGetted = false;
int residuo = 0;
boolean passGetted = false;

const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
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}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {9, 8, 7, 6}; //connect to the column pinouts of the keypad

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

LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display

void Countdown() {
  if (timeLength < 5) { //attendo l'inserimento di 4 numeri
    mostra = time;
    if (!getted) {
      if (last == 'c') {   //se viene premuto C, cancello tutto e ricomincio
        time = "____";
        timeLength = 0;
        getted = true;
      } else {
        if (timeLength < 4) { //finchè non ho 4 numeri non accetto la conferma
          if ((last != '*') && (last != '#') && (last != 'a') && (last != 'b') && (last != 'd')) { //accetto solo numeri e li salvo, se è il 3 alora solo inferiori a 6
            time.setCharAt(timeLength, last);
            //Serial.println(time);
            timeLength++;
            getted = true;
          } else {
            getted = true;
          }
        } else { //ho gia 4 numeri
          if (last == 'a') { //se ricevo la conferma proseguo
            getted = true;
            timeLength++;
            timeGetted = true;
            //Serial.println(time);
            //                   residuo = timeToInt(time);
          }
          else {
            getted = true;
          }
        }
      }
    }
  }
}


void Password() {
  if (passLength < 5) { //attendo l'inserimento di 4 numeri
    mostra = password;
    if (!getted) {
      if (last == 'c') {   //se viene premuto C, cancello tutto e ricomincio
        password = "cccc";
        passLength = 0;
        getted = true;
      } else {
        if (passLength < 4) { //finchè non ho 4 numeri non accetto la conferma
          if ((last != '*') && (last != '#') && (last != 'a') && (last != 'b') && (last != 'd')) { //accetto solo numeri e li salvo
            password.setCharAt(passLength, last);
            passLength++;
            getted = true;
          } else {
            getted = true;
          }
        } else { //ho gia 4 numeri
          if (last == 'A') { //se ricevo la conferma proseguo
            getted = true;
            passLength++;
            passGetted = true;
            //Serial.println(password);
          }
          else {
            getted = true;
          }

        }
      }
    } else {
      delay(5);
    }
  }
}

void setup()
{

  lcd.init();                      // initialize the lcd
  // Print a message to the LCD.
  Serial.begin(9600);
  lcd.backlight();                 //noBlacklight per oscurare schermo
  lcd.setCursor(4, 0);
  lcd.print("S.M.A.S.");
  lcd.setCursor(3, 1);
  lcd.print("La Bombaaa!");
  delay(5000);
  lcd.clear();
  
}

void loop()
{
 
}

per richiamarli basta scrivere la chiamata alla funzione
Password();
Countdown();

però, non ho capito se tutto il programma lo vuoi scrivere nella funzione setup... non ha molto senso

Patrick_M:
per richiamarli basta scrivere la chiamata alla funzione
Password();
Countdown();

però, non ho capito se tutto il programma lo vuoi scrivere nella funzione setup... non ha molto senso

Ciao.. Gia avevo provato a richiamare il tutto come mi hai consigliato tu.. Ma sul display al di fuori del messaggio che c'è scritto nel setup non mi compare nulla...

Io ora sn con il tel appena arrivo al pc vi mando l'ultima modifica di codice... Che sempre non sto riuscendo a fare funzionare... Un amico che ci capisce qualcosa in più di me,mi ha detto che i codici sn tutti giusti solamente si deve trovare il giusto ordine per farli funzionare