Pressione bottone - Print su seriale e stop

Ciao a tutti.
Come da oggetto mi servirebbe sapere se c'è la possibilità di fare in modo che:
Premendo un tasto venga eseguita una funzione, print di una stringa sulla seriale, e fino a quando non ho rilasciato il tasto, il loop non venga eseguito ulteriormente.

Al momento per evitare N stringhe ho inserito un delay di un secondo ma vorrei leggere lo stato attivamente sul pulsante.

Qui il mio codice:

void setup() {
 
  Serial.begin(9600);
  
  pinMode(Start, INPUT);
  pinMode(Stop, INPUT);
  
}
  
void loop() {
  
  while (digitalRead(Stop) == HIGH) {Serial.println("Stop"); delay(1000);}
  while (digitalRead(Start) == HIGH) {Serial.println("Start"); delay(1000);}

}

Grazie per la disponibilità!

Si sta parlando di una cosa simile QUI ... leggi cosa è stato consigliato, vedi se lo puoi applicare e poi ne riparliamo :slight_smile:

Guglielmo

Non ho capito bene la domanda.
La loop è già un dentro ciclo while infinito. Di "nascosto" il core di Arduino esegue:

while(1) 
{ loop();
}

Mi paiono inutili quei while, bastano degli if adeguati. Poi se i due pulsanti devono escludersi a vicenda, si devono usare delle variabili di stato (una o più). In pratica delle variabili vero/falso che permettono di ricordare se qualcosa è avvenuto e quindi eseguire solo una parte del codice con un semplice if

Grazie a tutti per le risposte...
Mi guardo i flag, sperando di saltarci fuori :smiley:

@nid69ita sono un gran neofita, sicuramente la soluzione che ho implementato non è la migliore.
Prima avevo fatto questo:

 int StartState = digitalRead(Start);
 int StopState = digitalRead(Stop);
  
 if (digitalRead(Stop) == HIGH)
   {
   Serial.println("Stop");
   Serial.println("");
   }
 else if (digitalRead(Start) == HIGH)
   {
   Serial.println("Start");
   Serial.println("");
   }
 else
   {   
   Serial.println("Waiting for command..."); 
   Serial.println("");
   delay(100);
   }
}

Solo che essendo un loop continuo nel momento in cui non premevo nulla sulla seriale girava sempre il Waiting for command...
Se non mettevo il delay ad ogni pressione del tasto veniva printato N volte il comando.

Quello che sto cercando di fare in parole povere è:
Premo tasto A mi appare sulla seriale Start. Fino a quando non smetto di premere A rimane SOLO UNO start.
Premo tasto B, stessa cosa ma con scritto STOP.

E' una cosa molto banale, ripeto la soluzione non credo sia complessa, ovviamente per il momento mi sto perdendo in un bicchiere d'acqua :slight_smile:

Guarda il thread indicato e poi facci sapere :wink:

Guglielmo

Grazie Guglielmo.
Allora sto provando a fare questo:

boolean StopCheck = false;
..
..
void loop() {

if (StopCheck)
  {
    Serial.println("Stop");
    StopCheck = false;
  }

// Controllo lo stato del pulsante
if (digitalRead(Stop)==HIGH)
  {
    StopCheck = true ;
  }
if (digitalRead(Stop)==LOW)
  {
    StopCheck = false ;
  }
  
}

Allora quando premo il pulsante mi printa Stop all’infinito, quando rilascio si ferma tutto.
Ho mezzo imparato una cosa nuova :slight_smile: però non ha ancora il risultato che volevo…
Sicuramente sto sbagliando qualcosa… Dove?

Scusa, ma da quello che descrivi sta facendo quello quello che volevi ... cosa dovrebbe fare invece ?

Guglielmo

Vorrei che mi scrivesse nella seriale solo una volta Stop. Mentre al momento ho scritture all'infinito...

Quindi tu vuoi che non faccia nulla, poi se premi il pulsante scriva sulla seriale una cosa, ma fino a quando non lo lasci non scriva più ?

Usa due flag, una ti indica se devi scrivere, un'altra se devi aggiornare la prima flag :wink:

Prova a ragionarci sopra, il meccanismo è lo stesso ...

Guglielmo

Un’altra forma è usare una variabile che ti dice in che “stato” ti trovi …

  1. non stampo e attendo pressione, quando premo passo a 2
  2. stampo una volta passo a 3
  3. aspetto che il tasto sia rilasciato e torno a 1

Guglielmo

gpb01:
Un'altra forma è usare una variabile che ti dice in che "stato" ti trovi ...

  1. non stampo e attendo pressione, quando premo passo a 2
  2. stampo una volta passo a 3
  3. aspetto che il tasto sia rilasciato e torno a 1

Guglielmo

Il problema è che non riesco a capire come fare il "stampa una volta" :frowning:

Stampi solo se le variabile di stato è uguale a 2 e, dopo aver stampato, la metti subito a 3 ... :wink:

In pratica prealizzi una "macchina a stati finiti" ... un esempio e spiegazione QUI.

Guglielmo

Grazie per il link Guglielmo, credo di essere a buon punto ora.

Mi è capitato un paio di volte con pulsanti differenti che a volte lo stato stop venisse fuori anche senza la pressione del tasto, ho aggiunto un delay per questo motivo e ora sembra che funzioni correttamente, ho fatto un qualche centinaio di pressioni e sembra perfetto!

Metto il codice qui, magari me lo bocciate, magari a qualcuno può tornare utile!

  int ON = 12;
  int OFF = 8; 
  int Stato_ON;
  int Stato_OFF;
  #define Start_OK 1
  #define Start_NOK 0
  #define Stop_OK 1
  #define Stop_NOK 0


void setup() 
{

  Serial.begin(9600);
  pinMode(ON, INPUT);
  pinMode(OFF, INPUT);
  Stato_ON = Start_NOK;
  Stato_OFF = Stop_NOK;

}


void loop() 
{

  switch(Stato_ON) {
    case Start_NOK:
      if (digitalRead(ON)==LOW) {
      Stato_ON = Start_OK;
      delay(15);
      }

     break;
 
    case Start_OK:
      if (digitalRead(ON)==HIGH) {
      Serial.println("Start");
      Stato_ON = Start_NOK;
      delay(15);
      }
     break;
   }

  switch(Stato_OFF) {
    case Stop_NOK:
      if (digitalRead(OFF)==LOW) {
      Stato_OFF = Stop_OK;
      delay(15);
      }
     
     break;
 
    case Stop_OK:
      if (digitalRead(OFF)==HIGH) {
      Serial.println("Stop");
      Stato_OFF = Stop_NOK;
      delay(15);
      }
    
     break;
  }
  
}

In realtà il problema deriva dal fatto che un bottone “reale” NON si comporta come un bottone “ideale” … :confused:

Quando tu premi o rilasci il bottone … ecco quello che veramente arriva sul pin di Arduino :

… per questo motivo, nella lettura dei bottoni, si debbono adottare tecniche di “debouncing” (cerca con Google).

Esistono sia software che hardware (preferibili) … in allegato alcuni possibili schemi :wink:

Guglielmo

debouncing_hw.pdf (22.8 KB)

Ecco spiegato il motivo!
Provvedo a documentarmi un pò e ne faccio uno hardware con gli schemi che mi hai postato!
Per il momento grazie mille per tutto quanto :wink:

In effetti questa cosa dell'antirimbalzo secondo me meriterebbe un "megatopic" dedicato.

paulus1969:
In effetti questa cosa dell'antirimbalzo secondo me meriterebbe un "megatopic" dedicato.

In realtà c'è sempre la famosa idea di creare in megatopic un thread di "tutorials" come discusso più volte QUI ...
... è il tempo di preparare il tutto che manca ... ma prima o poi si fa :wink:

Guglielmo