5 pulsanti con debounce per rele

Buongiorno a tutti,
sto cercando di collegare 5 pulsanti con funzione toggle, ho trovato in rete un codice che funziona correttamente con un pulsante e un relè. Con delay limitavo il rimbalzo dei pulsanti, ma aggiungendo altri pulsanti/rele la cosa non funziona correttamente, premetto che ho effettuato il collegamento dei pulsanti in PULL UP ecco il codice;

//1 pulsante
#define LED1 2                // LED collegato al pin digitale 13
#define BUTTON1 12              // pin di input dove è collegato il pulsante
byte val1 = 0;                  // si userà val per conservare lo stato del pin di input
byte vecchio_val1 = 0;          // si userà vecchio_val per conservare lo stato del pin di input al passo precedente
byte stato1 = 0;                // ricorda lo stato in cui si trova il led, stato = 0 led spento, stato = 1 led acceso

//2 pulsante
#define LED2 5                // LED collegato al pin digitale 13
#define BUTTON2 3              // pin di input dove è collegato il pulsante
byte val2 = 0;                  // si userà val per conservare lo stato del pin di input
byte vecchio_val2 = 0;          // si userà vecchio_val per conservare lo stato del pin di input al passo precedente
byte stato2 = 0;                // ricorda lo stato in cui si trova il led, stato = 0 led spento, stato = 1 led acceso

//3 pulsante
#define LED3 4               // LED collegato al pin digitale 13
#define BUTTON3 15              // pin di input dove è collegato il pulsante
byte val3 = 0;                  // si userà val per conservare lo stato del pin di input
byte vecchio_val3 = 0;          // si userà vecchio_val per conservare lo stato del pin di input al passo precedente
byte stato3 = 0;                // ricorda lo stato in cui si trova il led, stato = 0 led spento, stato = 1 led acceso

//4 pulsante
#define LED4 0                // LED collegato al pin digitale 13
#define BUTTON4 13              // pin di input dove è collegato il pulsante
byte val4 = 0;                  // si userà val per conservare lo stato del pin di input
byte vecchio_val4 = 0;          // si userà vecchio_val per conservare lo stato del pin di input al passo precedente
byte stato4 = 0;                // ricorda lo stato in cui si trova il led, stato = 0 led spento, stato = 1 led acceso

//5 pulsante
#define LED5 16                // LED collegato al pin digitale 13
#define BUTTON5 1              // pin di input dove è collegato il pulsante
byte val5 = 0;                  // si userà val per conservare lo stato del pin di input
byte vecchio_val5 = 0;          // si userà vecchio_val per conservare lo stato del pin di input al passo precedente
byte stato5 = 0;                // ricorda lo stato in cui si trova il led, stato = 0 led spento, stato = 1 led acceso



void setup() {

  //1 pulsante
  pinMode(LED1, OUTPUT);       // imposta il pin digitale come output
  pinMode(BUTTON1, INPUT);     // imposta il pin digitale come input

  //2 pulsante
  pinMode(LED2, OUTPUT);       // imposta il pin digitale come output
  pinMode(BUTTON2, INPUT);     // imposta il pin digitale come input

  //3 pulsante
  pinMode(LED3, OUTPUT);       // imposta il pin digitale come output
  pinMode(BUTTON3, INPUT);     // imposta il pin digitale come input

  //4 pulsante
  pinMode(LED4, OUTPUT);       // imposta il pin digitale come output
  pinMode(BUTTON4, INPUT);     // imposta il pin digitale come input

  //5 pulsante
  pinMode(LED5, OUTPUT);       // imposta il pin digitale come output
  pinMode(BUTTON5, INPUT);     // imposta il pin digitale come input

}

void loop() {

  val1 = digitalRead(BUTTON1);  // legge il valore dell'input e lo conserva
  val2 = digitalRead(BUTTON2);  // legge il valore dell'input e lo conserva
  val3 = digitalRead(BUTTON3);  // legge il valore dell'input e lo conserva
  val4 = digitalRead(BUTTON4);  // legge il valore dell'input e lo conserva
  val5 = digitalRead(BUTTON5);  // legge il valore dell'input e lo conserva

  // 1 pulsante
  if ((val1 == HIGH) && (vecchio_val1 == LOW)) {
    stato1 = 1 - stato1;
    delay(15);                // attesa di 15 millisecondi
  }
  vecchio_val1 = val1;            // ricordiamo il valore precedente di val
  if (stato1 == 1) {
    digitalWrite(LED1, HIGH);   // accende il led
  }
  else {
    digitalWrite(LED1, LOW);    //spegne il led
  }


  // 2 pulsante
  if ((val2 == HIGH) && (vecchio_val2 == LOW)) {
    stato2 = 1 - stato2;
    delay(15);                // attesa di 15 millisecondi
  }
  vecchio_val2 = val2;            // ricordiamo il valore precedente di val
  if (stato2 == 1) {
    digitalWrite(LED2, HIGH);   // accende il led
  }
  else {
    digitalWrite(LED2, LOW);    //spegne il led
  }


  // 3 pulsante
  if ((val3 == HIGH) && (vecchio_val3 == LOW)) {
    stato3 = 1 - stato3;
    delay(15);                // attesa di 15 millisecondi
  }

  vecchio_val3 = val3;            // ricordiamo il valore precedente di val

  if (stato3 == 1) {
    digitalWrite(LED3, HIGH);   // accende il led
  }
  else {
    digitalWrite(LED3, LOW);    //spegne il led
  }

  // 4 pulsante
  if ((val4 == HIGH) && (vecchio_val4 == LOW)) {
    stato4 = 1 - stato4;
    delay(15);                // attesa di 15 millisecondi
  }
  vecchio_val4 = val4;            // ricordiamo il valore precedente di val
  if (stato4 == 1) {
    digitalWrite(LED4, HIGH);   // accende il led
  }
  else {
    digitalWrite(LED4, LOW);    //spegne il led
  }

  // 5 pulsante
  if ((val5 == HIGH) && (vecchio_val5 == LOW)) {
    stato5 = 1 - stato5;
    delay(15);                // attesa di 15 millisecondi
  }

  vecchio_val5 = val5;            // ricordiamo il valore precedente di val

  if (stato5 == 1) {
    digitalWrite(LED5, HIGH);   // accende il led
  }
  else {
    digitalWrite(LED5, LOW);    //spegne il led
  }


}

c'è un sistema più efficace di questo ?
Saluti & Grazie

void readPuls(byte pin, byte &vecchio_val, uint32_t &t, byte &stato)
{
    byte in = digitalRead(pin);
    if (in == vecchio_val) { t = millis(); }
    else if (millis()-t > DEBTIME)
    {
        vecchio_val = in;
        if (PRESS_LEVEL == in) { stato ^= 1; }
    }
}
void loop(void)
{
    readPuls(BUTTON1, vecchio_val1, t1, stato1);
    readPuls(BUTTON2, vecchio_val2, t2, stato2);
    readPuls(BUTTON3, vecchio_val3, t3, stato3);
    readPuls(BUTTON4, vecchio_val4, t4, stato4);
    readPuls(BUTTON5, vecchio_val5, t5, stato5);

    digitalWrite(LED1, stato1 ? ACCESO : SPENTO);
    digitalWrite(LED2, stato2 ? ACCESO : SPENTO);
    digitalWrite(LED3, stato3 ? ACCESO : SPENTO);
    digitalWrite(LED4, stato4 ? ACCESO : SPENTO);
    digitalWrite(LED5, stato5 ? ACCESO : SPENTO);
}

-9

... oppure metti 5 condensatori in parallelo ai pulsanti. :slight_smile:

Datman:
... oppure metti 5 condensatori in parallelo ai pulsanti. :slight_smile:

Ma il toggle lo deve fare comunque, la differenza senza debounce software è minima:

void readPuls(byte pin, byte &vecchio_val, byte &stato)
{
    byte in = digitalRead(pin);
    if (in != vecchio_val)
    {
        vecchio_val = in;
        if (PRESS_LEVEL == in) { stato ^= 1; }
    }
}

void loop(void)
{
    readPuls(BUTTON1, vecchio_val1, stato1);
    readPuls(BUTTON2, vecchio_val2, stato2);
    readPuls(BUTTON3, vecchio_val3, stato3);
    readPuls(BUTTON4, vecchio_val4, stato4);
    readPuls(BUTTON5, vecchio_val5, stato5);

    digitalWrite(LED1, stato1 ? ACCESO : SPENTO);
    digitalWrite(LED2, stato2 ? ACCESO : SPENTO);
    digitalWrite(LED3, stato3 ? ACCESO : SPENTO);
    digitalWrite(LED4, stato4 ? ACCESO : SPENTO);
    digitalWrite(LED5, stato5 ? ACCESO : SPENTO);
}

-8

Claudio grazie per la risposta, il tuo codice mi piace, è leggibile ed essenziale, ma non riesco ad applicarlo, ho provato così per un solo pulsante

//1 pulsante
#define LED1 2                
#define BUTTON1 12             
byte val1 = 0;                  
byte vecchio_val1 = 0;          
byte stato1 = 0;   
byte PRESS_LEVEL =0;
byte ACCESO = HIGH;
byte SPENTO = LOW;
byte stato = 0;


void readPuls(byte pin, byte &vecchio_val, byte &stato)
{
    byte in = digitalRead(pin);
    if (in != vecchio_val)
    {
        vecchio_val = in;
        if (PRESS_LEVEL == in) { stato ^= 1; }
    }
}

void loop(void)
{
    readPuls(BUTTON1, vecchio_val1, stato1);
   /* readPuls(BUTTON2, vecchio_val2, stato2);
    readPuls(BUTTON3, vecchio_val3, stato3);
    readPuls(BUTTON4, vecchio_val4, stato4);
    readPuls(BUTTON5, vecchio_val5, stato5);*/

    digitalWrite(LED1, stato1 ? ACCESO : SPENTO);
    /*digitalWrite(LED2, stato2 ? ACCESO : SPENTO);
    digitalWrite(LED3, stato3 ? ACCESO : SPENTO);
    digitalWrite(LED4, stato4 ? ACCESO : SPENTO);
    digitalWrite(LED5, stato5 ? ACCESO : SPENTO);*/
}

, ma da "Errore durante la compilazione" esattamente questo errore:

c:/users/mike/documents/arduinodata/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-3-20ed2b9/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: core\core.a(core_esp8266_main.cpp.o): in function `do_global_ctors':

C:\Users\Mike\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266/core_esp8266_main.cpp:149: undefined reference to `setup'

c:/users/mike/documents/arduinodata/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-3-20ed2b9/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: core\core.a(core_esp8266_main.cpp.o): in function `loop_wrapper()':

C:\Users\Mike\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.5.0\cores\esp8266/core_esp8266_main.cpp:117: undefined reference to `setup'

collect2.exe: error: ld returned 1 exit status

exit status 1
Errore durante la compilazione per la scheda NodeMCU 1.0 (ESP-12E Module).

forse manca qualche libreria ?

Lo devo installare su di un nodemcu, non so se dovevo dirlo prima :slight_smile:

... ma hai letto i messaggi di errore ? ? ? :o

Manca il ... setup() ... che è obbligatorio :slight_smile:

Guglielmo

Hai ragione, lo avevo messo ma mi dava questo errore "expected primary-expression before 'pin'" allora vedendo quel "void loop(void)" pensavo che facesse una chiamata "strana" :slight_smile: al void e ho preferito riportarlo cosi.
p.s. giuro che non sto cercando la "pappa pronta" sono giorni che sto cercando di scrivere questo codice, finchè ne faccio 1 va bene, appena aumento i pulsanti (oltre i 3) e conseguenti relè non funziona più mi sono messo anche a mappare (provando un pulsante e un relè) tutti gli input/ouput del node pensando che avevo un nodemcu "fallato" questo è il risultato provando con un pulsante e un rele.

input
0=no
1 = no
2=no
3 =no
4 =si
5=si
9 =no
10=no
12=si
13=si
14=si
15=si
16=si

output
0=si
1=no
2=si
3=no
4=si
5=si
9=no
10=no
12=si
13=si
14=si
15=si
16=si

ma è normale che funziona su alcuni in/out e su altri no ? :frowning:

...ma una variabile byte che valori assume per HIGH e LOW?... Funziona?...
Mettici, piuttosto, 1 e 0, oppure usa un #define o, meglio ancora, scrivi direttamente HIGH e LOW nei digitalWrite!

void readPuls(byte pin, byte &vecchio_val, byte &stato)

Claudio, perché per vecchio_val e stato usi &, anziché semplicemente la variabile?

Perché se passassegli argomenti in modo normale sarebbero passati per valore, i in una chiamiamola copia locale
Deve passarli per indirizzo, per poter aggiornare la variabile nello scope chiamante, non la copia locale

I valori HIGH & LOW non sono rispettivamente 1 & 0 quindi byte è corretto no?
Cmq funziona, per quanto riguarda lo stralcio di codice con i puntatori riportato da Claudio, fino ad ora l'ho ricostruito in questo modo (soprattutto con l'aiuto di un programmatore dove lavoro)

# define ACCESO 1
# define SPENTO 0
# define PRESS_LEVEL 0
# define LED1 8
# define LED2 9
# define LED3 10
# define LED4 11
# define LED5 12
# define BUTTON1 '1'
# define BUTTON2 '2'
# define BUTTON3 '3'
# define BUTTON4 '4'
# define BUTTON5 '5'

byte vecchio_val1 = 0;
byte vecchio_val2 = 0;
byte vecchio_val3 = 0;
byte vecchio_val4 = 0;
byte vecchio_val5 = 0;

byte stato1 = 0;
byte stato2 = 0;
byte stato3 = 0;
byte stato4 = 0;
byte stato5 = 0;

void readPuls(byte pin, byte *vecchio_val, byte *stato)
{
  byte in = digitalRead(pin);
  if (in != *vecchio_val)
  {
    *vecchio_val = in;
    if (PRESS_LEVEL == in) {
      *stato ^= 1;
    }
  }
}


void setup ()
{

}
void loop(void)
{
  readPuls(BUTTON1, &vecchio_val1, &stato1);
  readPuls(BUTTON2, &vecchio_val2, &stato2);
  readPuls(BUTTON3, &vecchio_val3, &stato3);
  readPuls(BUTTON4, &vecchio_val4, &stato4);
  readPuls(BUTTON5, &vecchio_val5, &stato5);


  digitalWrite(LED1, stato1 ? ACCESO : SPENTO);
  digitalWrite(LED2, stato2 ? ACCESO : SPENTO);
  digitalWrite(LED3, stato3 ? ACCESO : SPENTO);
  digitalWrite(LED4, stato4 ? ACCESO : SPENTO);
  digitalWrite(LED5, stato5 ? ACCESO : SPENTO);

}

Ma ancora non funziona, oggi se il collega mi dedica del tempo "debugghiamo".
E per quanto riguarda i pin che alcuni funzionano e altri no, mi sono (finalmente) letto vari documenti per quanto riguarda l'utilizzo di tutti i pin del Node e ho le idee più chiare sul possibile (o meno) utilizzo degli IO.