Modalità di accesso alla lettura degli ingressi

No niente richiesta di aiuto, per una volta tanto volevo anch’io portare un contributo al forum.

Una semplice utilità da inserire nei nostri sketch, che permette una gestione degli ingressi per così dire avanzata.

L’idea è partita per gestire vari pulsanti, ma si adatta ad altre funzionalità, conta impulsi, pulsanti a doppia funzione, pulsanti on/off, ecc.

In sostanza le 5 righe all’inizio del ‘void loop’ permettono di intercettare la pressione o il rilascio del tasto, settando le rispettive variabili.
Il contenuto della variabile resta ‘vero’ per un singolo ciclo di loop e pertanto non è necessario preoccuparsi di problemi ‘debouncing’ o impostare flag di controllo.

Se l’idea fosse già nota allora mi ritiro in buon ordine, altrimenti resto a disposizione per fornire ulteriori dettagli.

  #define IngrPin 4
  #define LedPin 13
  
  byte IngrOld;          // stato ingresso precedente
  byte Ingr;             // stato ingresso attuale
  byte IngrX;            // risultato xor logico
  byte IngrDown;         // vero se ingresso high > low (FALLING)
  byte IngrUp;           // vero se ingresso low > high (RISING)

  word Counter;          // a supporto dell'esempio contaimpulsi

// -----------------------------------------------------------------------------------------------

void setup() {
  Serial.begin(9600);
  pinMode (LedPin,OUTPUT);
  pinMode (IngrPin,INPUT_PULLUP);
  Ingr = digitalRead(IngrPin);     // legge nuovo stato ingresso

}

// -----------------------------------------------------------------------------------------------

void loop() {


//-----------------------------------------------------------------------
// Blocco funzionale per aggiornare le variabili

  IngrOld  = Ingr;                     // memorizza stato precedente
  Ingr     = digitalRead(IngrPin);     // legge nuovo stato ingresso
  IngrX    = Ingr ^ IngrOld;           // esegue xor logico
  IngrDown = IngrX & IngrOld;
  IngrUp   = IngrX & Ingr;
//-----------------------------------------------------------------------

// Esempio dell'implemetazione di un semplice contaimpulsi

  Counter += IngrUp;


// Esempi per intercettare la pressione o rilascio del tasto
// o meglio le transizioni FALLING o RISING

  if (IngrUp){     // RISING 
    Serial.println(" Tasto rilasciato");

    Serial.print(" Counter = "); Serial.println(Counter);
  }

  if (IngrDown){   // FALLING
    Serial.println(" Tasto premuto");

    // Esempio Pulsante ON/OFF
    digitalWrite(LedPin,!digitalRead(LedPin));
  }

delay(50);
}

(editato succ.)
Durante tutto il loop per evitare problemi, raccomando di leggere lo stato dell'ingresso selezionato dalla variabile 'Ingr' e non utilizzando la funzione 'digitalRead(IngrPin)'.

il deboucing riguarda la lettura del dato, tu non la implementi e senza un hardware adeguato quel codice farà "cilecca".
Il tutto ti sembra funzionare perché hai messo un delay alla fine del loop() e questo è un involontario debounce.

Ti consiglio di raggruppare e ottimizzare il codice dentro un'apposita funzione.

L'utilità l'ho proposta come semplici righe di programma proprio per dar maniera di seguirne in modo semplice le varie fasi.

Il delay l'ho inserito proprio per simulare quello che sarà il tempo medio di loop dell'applicazione dell'utente, e 50mS mi sembra un tempo davvero sottostimato.

Questa soluzione la uso ormai da tempo, e proprio per l'affidabilità offerta mi sono convinto pubblicarla in queste pagine.

Rispetto ad altri lavori equivalenti risulta molto efficente, sopratutto leggendo gli ingressi a livello di porta.
In questo modo a parità di codice si legge direttamente 8 bit con rispettivi stati Up e Down.

Aggiungo una nota importante all'introduzione.
Durante tutto il loop per evitare problemi, raccomando di leggere lo stato dell'ingresso selezionato dalla variabile 'Ingr' e non utilizzando la funzione 'digitalRead(IngrPin)'.

se colleghi un pulsante al + ed ad un ingresso hai una bella antenna che ti intercetta anche il passaggio delle mosche con conseguente "sbalenamento" in ingresso, quindi in queste situazioni nel tuo codice non hai nessuna sorta di sicurezza.
Ma questo può accadere in qualsiasi configurazione che non sia un debounce hardware.

Una ritoccatica al codice la darei lo stesso.

se posso intervenire, anche un delay(1) certe volte lo guardo con malocchio :slight_smile: ... non si può guardare, l'istruzione andrebbe abolita.