#define BUTTON1_PIN 2 // Pulsante momentaneo (senza memoria)
#define BUTTON2_PIN 3 // Pulsante toggle (con memoria)
#define LED1_PIN 8 // LED controllato senza memoria
#define LED2_PIN 9 // LED controllato con memoria
#define DEBOUNCETIME 50 // Tempo di debounce in ms
/**
* Struttura Button per gestione avanzata del debounce
*
* Rileva immediatamente cambiamenti di stato e inibisce
* temporaneamente il rilevamento dei fronti successivi
*/
struct Button {
uint8_t pin; // Pin di Arduino collegato al pulsante
uint8_t val0; // Ultimo valore letto
unsigned long debtime; // Tempo di debounce in millisecondi
uint8_t val; // Valore attuale letto
uint8_t val00; // Ultimo stato stabile
unsigned long last; // Timestamp ultimo cambiamento
bool debState; // Flag per stato debounce (true = in debounce)
/**
* Rileva cambiamenti di stato con debounce
* @return true se è stato rilevato un cambiamento stabile
*/
bool changed() {
bool chg;
val = digitalRead(pin);
if(!debState) {
// Stato normale: attesa di un cambiamento
if(val != val0) {
// Primo cambiamento rilevato - attiva subito
debState = true;
last = millis();
chg = true;
} else {
chg = false;
}
val0 = val;
val00 = val; // Memorizza ultimo stato valido
} else {
// In debounce: ignora cambiamenti
if(val != val0) {
// Resetta timer se continua a cambiare
last = millis();
}
val0 = val;
chg = false;
// Gestione sicura dell'overflow di millis()
if((unsigned long)(millis() - last) > debtime) {
debState = false; // Fine debounce
val0 = val00; // Ripristina stato di riferimento
}
}
return chg;
}
};
// Inizializzazione pulsanti
Button buttonMomentary = {BUTTON1_PIN, LOW, 50}; // Pulsante senza memoria
Button buttonToggle = {BUTTON2_PIN, LOW, 50}; // Pulsante con memoria
// Stato per il pulsante con memoria
bool toggleState = false;
void setup() {
Serial.begin(115200);
// Configurazione I/O
pinMode(BUTTON1_PIN, INPUT_PULLUP); // Pulsanti con resistenza pullup
pinMode(BUTTON2_PIN, INPUT_PULLUP);
pinMode(LED1_PIN, OUTPUT); // LED
pinMode(LED2_PIN, OUTPUT);
// Stato iniziale LED
digitalWrite(LED1_PIN, LOW);
digitalWrite(LED2_PIN, LOW);
Serial.println("Sistema di controllo LED inizializzato");
Serial.println("- Pulsante 1: Controllo momentaneo (senza memoria)");
Serial.println("- Pulsante 2: Controllo toggle (con memoria)");
}
void loop() {
// 1. PULSANTE SENZA MEMORIA (momentaneo)
// Accende il LED solo quando il pulsante è premuto
if(buttonMomentary.changed()) {
// Il pulsante ha cambiato stato
if(buttonMomentary.val == LOW) { // Con pullup, LOW = premuto
digitalWrite(LED1_PIN, HIGH);
Serial.println("Pulsante 1 premuto - LED 1 acceso");
} else {
digitalWrite(LED1_PIN, LOW);
Serial.println("Pulsante 1 rilasciato - LED 1 spento");
}
}
// 2. PULSANTE CON MEMORIA (toggle)
// Cambia lo stato del LED ad ogni pressione
if(buttonToggle.changed()) {
if(buttonToggle.val == LOW) { // Solo sulla pressione (non sul rilascio)
toggleState = !toggleState; // Inverte lo stato
digitalWrite(LED2_PIN, toggleState);
Serial.print("Pulsante 2 premuto - LED 2 ");
Serial.println(toggleState ? "acceso" : "spento");
}
}
delay(1); // Breve pausa per stabilità
}
nano:12
nano:11
nano:10
nano:9
nano:8
nano:7
nano:6
nano:5
nano:4
nano:3
nano:2
nano:GND.2
nano:RESET.2
nano:0
nano:1
nano:13
nano:3.3V
nano:AREF
nano:A0
nano:A1
nano:A2
nano:A3
nano:A4
nano:A5
nano:A6
nano:A7
nano:5V
nano:RESET
nano:GND.1
nano:VIN
nano:12.2
nano:5V.2
nano:13.2
nano:11.2
nano:RESET.3
nano:GND.3
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r
btn2:1.l
btn2:2.l
btn2:1.r
btn2:2.r
vcc1:VCC
gnd1:GND
btn3:1.l
btn3:2.l
btn3:1.r
btn3:2.r
r4:1
r4:2
r5:1
r5:2
r6:1
r6:2
led1:A
led1:C
r7:1
r7:2
r3:1
r3:2