Dopo aver smaltito enne ripetizioni di "brodo natalizio" (chiamarlo brodo è riduttivo), ho finalmente deciso di testare il chip in oggetto.
Tanto per complicarmi il test ho deciso di provare a gestire vari stati del pulsante, in particolare:
JUST_PRESSED //Appena premuto
PRESSED //Tenuto premuto
LONG_PRESSED //Tenuto premuto per più di n secondi
JUST_RELEASED //Appena rilasciato
questo lo schema dei collegamenti per i pulsanti
e qui il codice di test
/*
Hardware debounce con MC14490 - Test
Version: 1.0 - Dec 2019
Author: Federico Luciani (Federico66)
*/
//Decommentare per il debounce software
//#define DEBOUNCE_SOFTWARE
#ifdef DEBOUNCE_SOFTWARE
#define DEBOUNCE_DELAY 60
#endif
//Numero totale dei pulsanti
#define MAX_BTN 4
//Tempo limite per la definizione di pressione prolungata
#define LONG_PRESSED_TIME 1500
//Enumerazione degli stati del pulsante
enum BTN_STATE {
BTN_NONE = 0,
BTN_JUST_PRESSED = 1, //Appena premuto
BTN_PRESSED = 2, //Tenuto premuto
BTN_LONG_PRESSED = 3, //Tenuto premuto per più di n secondi
BTN_JUST_RELEASED = 4 //Appena rilasciato
};
//Pin utilizzati dai pulsanti
uint8_t btn_pin[MAX_BTN] = {3, 4, 5, 6};
//Pin utilizzati dai led
uint8_t led_pin[MAX_BTN] = {9, 10, 11, 12};
//Stato iniziale dei pulsanti virtuali
uint8_t btn_state[MAX_BTN] = {BTN_NONE, BTN_NONE, BTN_NONE, BTN_NONE};
//Stato iniziale dei pulsanti fisici
bool btn_prev_state[MAX_BTN] = {HIGH, HIGH, HIGH, HIGH};
//Stato iniziale dei led
bool led_state[MAX_BTN] = {LOW, LOW, LOW, LOW};
//Tempo iniziale di pressione per calcolo della pressione prolungata
uint32_t start_pressed = 0;
//Se software debounce, tempo ultima lettura
#ifdef DEBOUNCE_SOFTWARE
uint32_t last_time;
#endif
void setup() {
Serial.begin(9600);
for (uint8_t i = 0; i < MAX_BTN; i++) {
#ifdef DEBOUNCE_SOFTWARE
pinMode(btn_pin[i], INPUT_PULLUP);
#else
pinMode(btn_pin[i], INPUT);
#endif
pinMode(led_pin[i], OUTPUT);
digitalWrite(led_pin[i], LOW);
}
}
void loop() {
checkButtons();
//Il primo led si accende/spegne alla pressione del primo pulsante
if (btn_state[0] == BTN_JUST_PRESSED) {
Serial.println("Just Pressed");
led_state[0] = !led_state[0];
digitalWrite(led_pin[0], led_state[0]);
}
//Il secondo led si accende/spegne al rilascio del secondo pulsante
if (btn_state[1] == BTN_JUST_RELEASED) {
Serial.println("Just Released");
led_state[1] = !led_state[1];
digitalWrite(led_pin[1], led_state[1]);
}
//Il terzo led si accende dopo pressione prolungata del terzo pulsante
//e si spegne al suo rilascio
if (btn_state[2] == BTN_LONG_PRESSED && !led_state[2]) {
Serial.println("Long Pressed");
led_state[2] = HIGH;
digitalWrite(led_pin[2], led_state[2]);
} else if (btn_state[2] == BTN_JUST_RELEASED && led_state[2]) {
Serial.println("Just Released");
led_state[2] = LOW;
digitalWrite(led_pin[2], led_state[2]);
}
//Il quarto led si accende alla pressione del quarto pulsante,
//lampeggia dopo pressione prolungata e si spegne al suo rilascio
if (btn_state[3] == BTN_JUST_PRESSED) {
Serial.println("Just Pressed");
led_state[3] = HIGH;
digitalWrite(led_pin[3], led_state[3]);
} else if (btn_state[3] == BTN_LONG_PRESSED) {
Serial.println("Long Released");
led_state[3] = !led_state[3];
digitalWrite(led_pin[3], led_state[3]);
delay(100);
} else if (btn_state[3] == BTN_JUST_RELEASED) {
Serial.println("Just Released");
led_state[3] = LOW;
digitalWrite(led_pin[3], led_state[3]);
}
}
void checkButtons() {
#ifdef DEBOUNCE_SOFTWARE
if ((last_time + DEBOUNCE_DELAY) > millis())
return;
last_time = millis();
#endif
for (uint8_t i = 0; i < MAX_BTN; i++) {
bool btn_cur_state = digitalRead(btn_pin[i]);
if (btn_cur_state != btn_prev_state[i]) {
if (btn_cur_state == LOW) {
//Just pressed
start_pressed = millis();
btn_state[i] = BTN_JUST_PRESSED;
} else {
//Just released
btn_state[i] = BTN_JUST_RELEASED;
}
} else {
if (btn_cur_state == LOW) {
uint32_t timeHold = millis() - start_pressed;
if (timeHold >= LONG_PRESSED_TIME) {
//Long Pressed
btn_state[i] = BTN_LONG_PRESSED;
} else {
//Pressed
btn_state[i] = BTN_PRESSED;
}
} else {
//None
btn_state[i] = BTN_NONE;
}
}
btn_prev_state[i] = btn_cur_state;
}
}
Il risultato mi sembra buono, quindi io son contento 
Come al solito, ogni critica o proposta di miglioramento è ben accetta.
Se non avete il chip, ma volete testare il codice, vi basta decommentare la define DEBOUNCE_SOFTWARE; questa abilita un semplice debounce software.
A tal proposito, ho notato che il tempo di debounce, nel mio caso, deve essere di almeno 60 ms, altrimenti lo stato JUST_RELEASED non viene intercettato! Onestamente non ho indagato se è migliorabile, non era lo scopo del test.
Buon divertimento
Federico