https://www.arduino.cc/en/tutorial/switch
L'esempio di quella pagina mi sembra sbagliato per diversi motivi.
Intanto usa variabili tempo long invece di unsigned long.
Poi non filtra la pressione, un breve disturbo impulsivo viene accettato subito come buono.
Filtra i rimbalzi successivi alla pressione (quando ha già dato l'ok, come dire no a pressioni troppo ravvicinate).
Filtra anche i rimbalzi del rilascio... PURCHÉ il rilascio avvenga entro il tempo di debounc, altrimenti il primo rimbalzo del rilascio viene preso come nuova pressione valida (per questo ha dovuto scrivere un tempo di debounch così lungo)...
In sostanza è inutilizzabile se si volesse implementare il riconoscimento di un long-press o per la lettura di un contatto/interruttore che apre/chiude con tempi lunghi.
Lo riscriverei senz'altro in questo modo, le variazioni sia alla pressione che al rilascio sono sempre subordinate alla permanenza stabile del livello in input per almeno DEBOUNCE millisecondi (ne bastano 40..50):
#define PRESSED_LEVEL ... // livello ingresso con pulsante premuto
#define IN_PIN 2 // the number of the input pin
#define OUT_PIN 13 // the number of the output pin
#define DEBOUNCE 40 // the debounce time, increase if the output flickers
#define OFF_LEVEL ... // livello uscita spenta
byte previous = !PRESSED_LEVEL; // the previous reading from the input pin
unsigned long time = 0; // the last time the output pin was toggled
byte state = OFF_LEVEL; // the current state of the output pin
void setup()
{
pinMode(IN_PIN, INPUT);
pinMode(OUT_PIN, OUTPUT);
}
void loop()
{
byte reading = digitalRead(IN_PIN);
if (reading == previous)
time = millis();
else if (millis() - time > DEBOUNCE)
{
previous = reading;
if (reading == PRESSED_LEVEL)
state = !state;
}
digitalWrite(OUT_PIN, state);
}
NOTA: Le costanti PRESSED_LEVEL e OFF_LEVEL definite all'inizio del programma vanno impostate a 1 o 0 in base al collegamento hardware che si realizza (verso Vcc o verso massa).
Poi ancora meglio separare completamente la logica di lettura/debounce da quella di controllo/comando, ad esempio fare in modo che la lettura/debounce produca solamente una variabile pulita, stabile, filtrata, che rappresenta lo stato ideale premuto/rilasciato. In questo modo sono sicuro che 'pressed' vale 1 (o HIGH o true) quando il pulsante è premuto e 0 (o LOW o false) quando non lo è. Nel resto del programma uso questa variabile come "ingresso ideale" privo di rimbalzi.
byte reading = digitalRead(IN_PIN);
if (reading == previous)
time = millis();
else if (millis() - time > DEBOUNCE)
previous = reading;
byte pressed = (previous == PRESSED_LEVEL);