inserire tempi lunghi nel temporizzatore

salve a tutti ho finito il mio progetto per accendere le luci da strada con keypad e da casa con il pulsante , ma ho un problema praticamente non riesco ad impostare il tempo di luci accese per piu di 30 secondi, qualcuno puo aiutarmi???
appena avrò finito il progetto e sara efficiente pubblicherò un articolo sul progetto completo magari potrà essere utile a qualcun’altro…

#include <Keypad.h>
#define luci 13      //filo blu bianco
#define led 12       //filo blu
 int buttonPin = 10; // filo marrone
int val = 0;
int tempo = 30000;
const byte ROWS = 4; //quattro righe
const byte COLS = 3; //tre colonne
char keyInsert[2];
// Queste variabili servono come verifica del corretto inserimento del codice
int i = 0;
int j = 0;
int s = 0;
int x = 0;
// Codice segreto
char code[2]= "6";
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte rowPins[ROWS] = {8,7,6,5}; //i Pin a cui sono connesse le righe del KeyPad
byte colPins[COLS] = {4,3,2}; // i Pin a cui sono connesse le colonne del KeyPad
 
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
 
void setup(){
  Serial.begin(9600);
  pinMode(luci,OUTPUT); // relè luci strada
  pinMode(led, OUTPUT); // led tastiera
digitalWrite(luci,HIGH);

digitalWrite(led, HIGH);
}

void loop(){


val = digitalRead(buttonPin);
       if (val == HIGH){
        Serial.println("ACCENSIONE CON PUSANTE OK");
        digitalWrite(luci, LOW);
        delay(tempo);
        digitalWrite(luci, HIGH);
        x=0;
        i=0;
        j=0;
      
      while(0);
       }

char key = keypad.getKey();

 {
 if (i==0){
    Serial.println("inserisci il codice....");
    i++;
  }
  if (key != NO_KEY && j<1){
    Serial.print("*");
    //Serial.println(key);
    keyInsert[j]=key;
    j++;
  }
      //tasto da premere per accendere i led tastiera
       if(key == '#'){
       
      digitalWrite(led,LOW);
     Serial.println("led tastiera acceso");
       x=0;
        i=0;
        j=0;
      
      while(0);
       }
      
   if(key == '*') {
      Serial.println();
      Serial.println("verifica del codice...");
      delay(1000);
      for(s=0; s<1;s++){
        if(keyInsert[s]==code[s]){
          x++;
      }
    } 
  
      if(x== 1){
      Serial.println("Codice corretto"); 
      digitalWrite (led,HIGH);
      digitalWrite(luci,LOW);
      Serial.println("led tastiera spento");                  
      delay(tempo); 
      digitalWrite (luci,HIGH);
      digitalWrite (led,HIGH);
        x=0;
        i=0;
        j=0;
      
      //TODO possibili ulteriori implementazioni
      }else{
         Serial.println("Codice non corretto, riprova");
         delay(2000);
         x=0;
         i=0;
         j=0;
      }
   }


}
   }

questo ?

    if (val == HIGH){
        Serial.println("ACCENSIONE CON PUSANTE OK");
        digitalWrite(luci, LOW);
        delay(tempo);
        digitalWrite(luci, HIGH);
        x=0;
        i=0;
        j=0;
     
      while(0);
       }

while(0)

prova while(true); o '1'

appena avrò finito il progetto e sara efficiente pubblicherò un articolo sul progetto completo magari potrà essere utile a qualcun'altro...

Se lo fai con l'istruzione delay(tempo); ti consiglio di non pubblicarlo, creeresti altri problemi ad altri utenti.

>gminga78: l’uso del delay(), dato quello che devi fare, è da sconsigliare, difatti è una funzione “bloccante” e, una volta chiamata, fino allo scadere del tempo, NON è possibile fare altro.

Ti consiglio quindi di ripensare la logica del tuo programma con l’utilizzo invece della funzione millis()
… per capire come funziona e come si applica ti consiglio di studiare prima QUI, poi QUI ed infine leggi anche QUI e QUI.

In questo modo dovresti avere una panoramica del suo utilizzo e doversti quindi capire come applicarla nel tuo programma :slight_smile:

Guglielmo

Se ha fatto tutto quel programma, penso che ne fosse a conoscenza.

pablos: Se ha fatto tutto quel programma, penso che ne fosse a conoscenza.

Da cosa deriva questa tua convinzione ? :smiling_imp:

... ed in ogni caso ... anche se ne era a conoscenza ... non mi sembra che abbia applicato come si deve il "sapere" :grin:

Guglielmo

int tempo = 30000;

Oltre il giá detto sopra che delay fa aspettare Arduino senza la possibilitá di eseguire altro codice (perché appunto esegue delay()) e perui é problematico il problema da Te descritto é il int da Te usato per memorizzare il tempo di delay.

Una variabile di tipo int puó memorizzare valori da -32,768 a 32,767 se cerchi di assegnare un numero piú grande la variabile avrá li valore del numero assegnato sotratto multipli di -32,768 o 32,767 ( a secondo se il numero é positivo o negativo)

La funzione delay() acetta come valore dei numeri unsigned long da 0 a 4,294,967,295. devi usare una variabile di tipo unsigned long e puoi fare ritardi fino a ca 4294967 secondi ovvero fino ca 49 giorni.

https://www.arduino.cc/en/Reference/Int https://www.arduino.cc/en/Reference/UnsignedLong https://www.arduino.cc/en/Reference/Delay

Comunque per l' uso che vuoi fare devi usare millis() come suggerito da Guglielmo.

Inoltre Ti consiglio di imparare meglio la programmazione perché il Tuo sketch non va bene. un while(0); non fa niente perché aspetta finche l'argomento sia sbagliato e 0 lo é sempre. puoi anche cancellare il while(0); e lo sketch funziona uguale. Non usare variabile a b c ma dagli nomi "parlanti" che fanno capire che cosa significano.

Ciao Uwe

Glielo avrei spiegato anch'io, ma mi aspettavo un "perchè" dall'utente, insomma una forma di partecipazione ... "eccomi ci sono", invece avete rovinato appunto la partecipazione all'argomento. la domanda che invoglia a imparare, perchè senza le domande non si impara e le cose difficilmente saranno ricordate. Un argomento, una soluzione, un trucco, rimane impresso quando è la tua volontà, curiosità a chiederla. Questa è la pappa pronta che tanto detesti. :smiling_imp:

Ciao a tutti e grazie per le vostre risposte/commenti il programma che ho pubblicato non l'ho scritto io da.zero ma ho cercato di modificare nei miei limiti uno ed invece non ci sono riuscito come. Volevo.... adesso tramide un amico che ne sà un po' piu di me abbiamo risolto e mi ha spiegato cosa sbagliavo e.come andava modificato grazie a tutti per l aiuto. Adesso però avrei anche io un sassolino da togliermi, visto che chiunque ha il diritto di rispondere..... sono iscritto in tanti altri forum per altre mie passioni e mi accorgo che ogni qualvolta che qualcuno chiede in questo forum un aiuto ci sono sempre i "professori" che deridono di quelli come me che hanno più o meno solo le basi, vorrei solo dirvi che se uno chiede aiuto in un forum è perché non sà come risolvere e non per farsi insultare. Cmq grazie a tutti e scusate lo sfogo

Nessuno ti ha deriso e nessuno ti ha insultato, se questo è quello che hai interpretato allora mi scuso, "deridere" e "insultare" sono ben altri termini. Io mi sono limitato a dirti "se usi quell'istruzione potresti creare problemi ad altri utenti" ed è vero, perchè ci si ritrova spesso a prendere spunto da siti ben fatti che all'apparenza sembrano creati da veri esperti e alla fine ci si accorge che è spazzatura su spazzatura (e non mi riferisco al tuo shetch).

Ora tu supponi che un altro utente vuole creare un timer, ma nello stesso tempo vuole controllare un ingresso costantemente, prende il tuo sketch e viene qui, "ho copiato questo programma ma non fa quello che mi aspettavo", certo ... non può farlo con un delay(30000).

Se tu avessi chiesto qui e approfondito soprattutto cercato, la risposta l'avevi sotto il naso.

adesso tramide un amico che ne sà un po' piu di me abbiamo risolto e mi ha spiegato cosa sbagliavo e.come andava modificato

Da "professore" quale mi definisci, posso vedere cosa ti ha suggerito il tuo amico? prometto che non commento.

ciao

Salve a tutti pubblico il mio progetto da me terminato e FUNZIONANTE PER LE MIE ESIGENZE, però sono a disposizione per avere dei suggerimenti in merito magari da poter migliorare in altre occasioni, lo skech ancora non ho finito di commentarlo ma lo farò quanto prima…
spiego in due parole a cosa serve il progetto:
ho necessità di accendere un illuminazione esterna con una keypad dalla strada e con un pulsante dall’interno di casa, per un tempo di 90 secondi (che può essere variato).
il codice di attivazione è un numero solo cioè il “6” ma nella realtà facendo una piccola modifica ho inserito tre cifre. Spero di essere di aiuto a qualcuno e accetto suggerimenti tranquillamente perchè ho voglia di imparare. grazie a tutti.

#include <Keypad.h>
#define luci 13      //dichiaro il 13 per le luci
#define led 12       //dichiaro il 12 per i led
int buttonPin = 10; // dichiaro il 10 per pulsante per accensione luci
int val = 0;          // varabile per il pulsnte
int tempo = 90;       // tempo per luci accese
byte n;               
byte spento;
unsigned int tingresso, tcorrente;
const byte ROWS = 4; //quattro righe
const byte COLS = 3; //tre colonne
char keyInsert[2];
// Queste variabili servono come verifica del corretto inserimento del codice
int i = 0;
int j = 0;
int s = 0;
int x = 0;
// Codice segreto
char code[2]= "6";
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte rowPins[ROWS] = {8,7,6,5}; //i Pin a cui sono connesse le righe del KeyPad
byte colPins[COLS] = {4,3,2}; // i Pin a cui sono connesse le colonne del KeyPad
 
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
 
void setup(){
  Serial.begin(9600);
  pinMode(luci,OUTPUT); // relè luci strada
  pinMode(led, OUTPUT); // led tastiera
digitalWrite(luci,HIGH);
digitalWrite(led, HIGH);
tcorrente=0;
tingresso=0;
spento=1; // indica lo stato di accensione con pulsante vale 1 quando non è stato acceso con pulsante
}

void loop(){

      tcorrente=(millis()/1000);

     val = digitalRead(buttonPin);
     n=0;
     if(val == LOW){ 
         while( (val==LOW) && (n < 4)){
           n++; 
           delay(50); // queste righe di codice sono state pensate per evitare la falsa lettura 
           val=digitalRead(buttonPin);  // dell'ingresso in questione,  
             if(n >=4) {  //  tutto questo è dovuto al fatto che abbiamo 
               val=LOW;   // abbiamo utilizzato per la lettura degli ingressi una configurazione a resistenze  di tipo PULL-DOWN
              } 
         }
   }  
       if(val == HIGH || !spento){
       if(spento){
        Serial.println("ACCENSIONE CON PUSANTE OK");
        digitalWrite(luci, LOW);
        spento=0;
        tingresso=tcorrente;
        }
        if((tcorrente-tingresso)>=tempo){
        digitalWrite(luci, HIGH);
        spento=1;
        }
        x=0;
        i=0;
        j=0;
      
       }
 

char key = keypad.getKey();

 {
 if (i==0){
    Serial.println("inserisci il codice....");
    i++;
  }
  if (key != NO_KEY && j<1){
    Serial.print("*");
    //Serial.println(key);
    keyInsert[j]=key;
    j++;
  }
  
       
       
       //tasto da premere per accendere i led tastiera
       if(key == '#'){
       
      digitalWrite(led,LOW);
     Serial.println("led tastiera acceso");
       x=0;
        i=0;
        j=0;
      
       }
      
   if(key == '*') {
      Serial.println();
      Serial.println("verifica del codice...");
      delay(1000);
      for(s=0; s<1;s++){
        if(keyInsert[s]==code[s]){
          x++;
      }
    } 
  
      if(x== 1){
      Serial.println("Codice corretto"); 
      if(spento){
        digitalWrite(luci, LOW);
        spento=0;
        tingresso=tcorrente;
        }
        if((tcorrente-tingresso)>=tempo){
        digitalWrite(luci, HIGH);
        spento=1;
        }
        x=0;
        i=0;
        j=0;
     
      //TODO possibili ulteriori implementazioni
      }else{
         Serial.println("Codice non corretto, riprova");
         delay(2000);
         x=0;
         i=0;
         j=0;
      }
   }


}
  

  
   }

Ma perché non usate mai quella bella funzione dell'IDE che si trova nel menu Tools -> Auto Format ? ... così avreste un codice ordinato e leggibile con tutte le indentature al posto giusto ! :grin:

Se poi si eliminano anche tutte quelle inutili righe vuote che vedo in giro ... il programma risulta molto più pulito ;)

Guglielmo

… ecco, guarda come viene :

#include <Keypad.h>
#define luci 13      //dichiaro il 13 per le luci
#define led 12       //dichiaro il 12 per i led

int buttonPin = 10;  // dichiaro il 10 per pulsante per accensione luci
int val = 0;         // varabile per il pulsnte
int tempo = 90;      // tempo per luci accese
byte n;
byte spento;
unsigned int tingresso, tcorrente;
const byte ROWS = 4; //quattro righe
const byte COLS = 3; //tre colonne
char keyInsert[2];

// Queste variabili servono come verifica del corretto inserimento del codice
int i = 0;
int j = 0;
int s = 0;
int x = 0;

// Codice segreto
char code[2] = "6";
char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}
};
byte rowPins[ROWS] = {8, 7, 6, 5}; //i Pin a cui sono connesse le righe del KeyPad
byte colPins[COLS] = {4, 3, 2}; // i Pin a cui sono connesse le colonne del KeyPad

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

void setup() {
  Serial.begin(9600);
  pinMode(luci, OUTPUT); // relè luci strada
  pinMode(led, OUTPUT); // led tastiera
  digitalWrite(luci, HIGH);
  digitalWrite(led, HIGH);
  tcorrente = 0;
  tingresso = 0;
  spento = 1; // indica lo stato di accensione con pulsante vale 1 quando non è stato acceso con pulsante
}

void loop() {
  tcorrente = (millis() / 1000);
  val = digitalRead(buttonPin);
  n = 0;
  if (val == LOW) {
    while ( (val == LOW) && (n < 4)) {
      n++;
      delay(50); // queste righe di codice sono state pensate per evitare la falsa lettura
      val = digitalRead(buttonPin); // dell'ingresso in questione,
      if (n >= 4) { //  tutto questo è dovuto al fatto che abbiamo
        val = LOW; // abbiamo utilizzato per la lettura degli ingressi una configurazione a resistenze  di tipo PULL-DOWN
      }
    }
  }
  if (val == HIGH || !spento) {
    if (spento) {
      Serial.println("ACCENSIONE CON PUSANTE OK");
      digitalWrite(luci, LOW);
      spento = 0;
      tingresso = tcorrente;
    }
    if ((tcorrente - tingresso) >= tempo) {
      digitalWrite(luci, HIGH);
      spento = 1;
    }
    x = 0;
    i = 0;
    j = 0;
  }
  char key = keypad.getKey();
  {
    if (i == 0) {
      Serial.println("inserisci il codice....");
      i++;
    }
    if (key != NO_KEY && j < 1) {
      Serial.print("*");
      //Serial.println(key);
      keyInsert[j] = key;
      j++;
    }
    //tasto da premere per accendere i led tastiera
    if (key == '#') {
      digitalWrite(led, LOW);
      Serial.println("led tastiera acceso");
      x = 0;
      i = 0;
      j = 0;
    }
    if (key == '*') {
      Serial.println();
      Serial.println("verifica del codice...");
      delay(1000);
      for (s = 0; s < 1; s++) {
        if (keyInsert[s] == code[s]) {
          x++;
        }
      }
      if (x == 1) {
        Serial.println("Codice corretto");
        if (spento) {
          digitalWrite(luci, LOW);
          spento = 0;
          tingresso = tcorrente;
        }
        if ((tcorrente - tingresso) >= tempo) {
          digitalWrite(luci, HIGH);
          spento = 1;
        }
        x = 0;
        i = 0;
        j = 0;
        //TODO possibili ulteriori implementazioni
      } else {
        Serial.println("Codice non corretto, riprova");
        delay(2000);
        x = 0;
        i = 0;
        j = 0;
      }
    }
  }
}

Non sono entrato nel merito del programma, ma mi è balzata una cosa agli occhi …
… a che servono le graffe che racchiudono il blocco da linea 76 alla fine ?

Guglielmo

hai ragione non avevo fatto caso nella fretta di finire il lavoro,

pooso commentare?

Ma certo che. Puoi , il mio sfogo era rivolto al.fatto che..quando si vue aiutare qualcuno non servono tante chiacchere ma magari una risposta del tipo vediamo dove sbagli e magari cerchiamo di capire come andrebbe risolto tutto qui..... vi ripeto che molta gente è autodidatta quindi molto limitata.....

Il millis() dura circa 50 giorni, perchè l'hai diviso per 1000 e caricato su un INT?

L ho diviso per. 1000 perche almeno non dovevo.scrivere i millisecondi me. Se hai visto.ho.inserito i secondi normalmente

Si ma tecnicamente questo è un errore

unsigned int tingresso, tcorrente;
tcorrente = (millis() / 1000);

Ti ripeto che non ho mai studiato.il linguaggio c quindi se vedo che funziona per me funziona e se è un errore ed.ho sbagliato accetto molto volentieri di capire e come andrebbe fatto Grazie intanto per il tuo interesse