Controllo del periodo di lampeggio tramite pulsante (non-blocking mode)

Si vuole modificare il programma che varia il leriodo di lampeggio dei led alla pressione del pulsante inserendo la loro gestione tramite timer.

Eliminando i delay() il programma diventa non-blocking e il controllo del pulsante può avvenire in continuazione, eliminando la necessità di tenerlo premuto per circa 1 secondo.

// All'inizio led acceso
// Primo tocco: led lampeggia con periodo di mezzo secondo
// Secondo tocco: led lampeggia con periodo un secondo
// Terzo tocco: led lampeggia con periodo un secondo e mezzo
// Quarto tocco: led acceso

const int BUTTON = 7;    // pin di input a cui è collegato il pulsante
const int LED = 13;       // LED collegato al pin digitale 13

// Variabili globali 
bool statoButton;      // stato del pulsante 
int countButton = 0;   // Conteggio del bottone

unsigned long timenow = 0;  // variabile di appoggio per il conteggio dei microsecondi
unsigned long lastUpdate = 0;  // variabile di appoggio per il conteggio dei millisecondi da quando è avvenuto l'ultimo evento nel LED
unsigned long interval = 0;      // semiperiodo del LED in millisecondi (0 led acceso)
bool statoLed = LOW;         // stato del LED (LOW spento, HIGH acceso)


// Avvio dell'applicazione
void setup()  
{  
  pinMode(LED, OUTPUT);       // imposta il pin digitale come output
  pinMode(BUTTON, INPUT);     // imposta il pin digitale come input
  digitalWrite(LED, HIGH);    // accende il LED
}  
// Avvio del loop
void loop()  
{
  statoButton = digitalRead(BUTTON);  // legge il valore dell'input e lo conserva
  if(statoButton == HIGH)             // verifico se l'utente ha premuto il bottone  
  {  
      // Aumento il count del bottone
      if(countButton<=3) countButton=countButton+1;  
      else countButton=0;  
      while(digitalRead(BUTTON) == HIGH);   // Aspettare il rilascio del pulsante
      // delay(200);   // debounce, decommentare se necessario

      switch (countButton) // In base allo stato del bottone scelgo il periodo del led  
      {   
      case 1:  
        interval = 250;     // periodo lampeggio 0.5 secondi          
        break;  
      case 2:  
        interval = 500;     // periodo lampeggio 1 secondo 
        break;  
      case 3:  
        interval = 750;     // periodo lampeggio 1.5 secondi
        break;   
      case 0:      digitalWrite(LED, HIGH);  // accende il LED
        interval = 0; 
        break;  
      }
  }      

  // gestione del lampeggio  
  timenow = millis();  // carico il tempo passato dall'avvio del programma

  // Verifico se devo fa cambiare stato al LED1
  // && è l'operatore AND logico
  // (interval !=0) per gestire il pulsante sempre acceso
  if ((timenow >= lastUpdate + interval) && (interval !=0)){
    if (statoLed == 0){
      digitalWrite(LED, HIGH);  // accende il LED
      statoLed = HIGH;          // aggiorna stato LED
    }
    else{
      digitalWrite(LED, LOW);   // spegne il LED
      statoLed = LOW;           // aggiorna stato LED
    }

    /* Al posto di tutto il blocco if si sarebbe potuto mettere    
     *  digitalWrite(LED, !statoLed);
     */
    
    lastUpdate = timenow;  // aggiorno per il nuovo evento
  }
  
} 

Ultime modifiche: sabato, 28 marzo 2020, 20:38