#define BUTTON1_PIN 14     // Pulsante momentaneo (senza memoria)
#define BUTTON2_PIN 23     // Pulsante toggle (con memoria)
#define LED1_PIN 13        // LED controllato senza memoria
#define LED2_PIN 12        // 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 = false;  // Inizializza per sicurezza
		val = digitalRead(pin);
		
		if(val != val0) {  // C'è una transizione
			if(!debState) {  // E siamo in stato stabile
				debState = true;  // Attiva debounce
				last = millis();  // Memorizza timestamp
				chg = true;       // Segnala cambiamento
				val0 = val;       // Aggiorna ultimo valore letto
				val00 = val;      // Memorizza stato valido
        Serial.println("primo");
			}else{
				last = millis();  // Memorizza timestamp
				chg = false;  // Nessun cambiamento
        Serial.println("transiz in debounce");
			}
		}else if(val == val0){  // Non c'è transizione
			if(!debState) {  // E siamo in stato stabile
				val0 = val;   // Aggiorna ultimo valore letto
				val00 = val;  // Memorizza stato valido
			}
		}else if(debState && ((unsigned long)(millis() - last) > debtime)) {  // Tempo di debounce scaduto
			debState = false;  // Torna a stato stabile
			val0 = val00;      // Ripristina stato di riferimento
			chg = true;       
		}else if(debState && ((unsigned long)(millis() - last) <= debtime)){
      val0 = val;
      chg = false;
    }
				
		return chg;     
	}
};

// Inizializzazione pulsanti
Button buttonMomentary = {BUTTON1_PIN, LOW, 1000};  // 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);  // Pulsanti con resistenza pullup
  pinMode(BUTTON2_PIN, INPUT);
  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 == HIGH) {  // 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 == HIGH) {  // 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à
}
esp:VIN
esp:GND.2
esp:D13
esp:D12
esp:D14
esp:D27
esp:D26
esp:D25
esp:D33
esp:D32
esp:D35
esp:D34
esp:VN
esp:VP
esp:EN
esp:3V3
esp:GND.1
esp:D15
esp:D2
esp:D4
esp:RX2
esp:TX2
esp:D5
esp:D18
esp:D19
esp:D21
esp:RX0
esp:TX0
esp:D22
esp:D23
led1:A
led1:C
led2:A
led2:C
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r
r1:1
r1:2
r2:1
r2:2
r3:1
r3:2
btn2:1.l
btn2:2.l
btn2:1.r
btn2:2.r
r4:1
r4:2