Switch case - non viene attivato

Buongiorno a tutti.
Sono mi sto avvicinando per la prima volta al mondo microcontrollori e ne sono rimasto affascinato.

Sto cercando di creare un sistema di controllo di irrigazione attivato da un pulsante, che ad ogni pressione, attivi un relay per un periodo predeterminato, (oppure faccia entrare il sistema in funzionamento automatico...)
Sto cercando di scrivere il codice con delle soglie di debounce, per evitare dei doppi click non voluti...

Uso switch case, ma non viene attivato il case specifico.

if (pulsante == HIGH) {
              
        eventTime = millis();
        stato = deb_pr;
        
      }
      break;

    case deb_pr:
        Serial.print("  premuto debounce  ");
        if ((millis() - eventTime) >= (dpt)) {

Dopo vari tentativi, non so piu' che pesci pigliare, ed eccomi qui.

Vi allego il codice completo. E' un work in progress per cui alcune variabili non sono ancora state utilizzate... Siate indulgenti!

unsigned long dpt = 15; //DEFAULT_DEBOUNCE_PRESS_TIME
unsigned long drt = 15; //DEFAULT_DEBOUNCE_RELEASE_TIME
unsigned long mct = 400; //DEFAULT_MULTI_CLICK_TIME
unsigned long ht = 2000; //DEFAULT_HOLD_TIME



int Button_pin = 2;
int Relay_pin = 12;

int stato = 1;

int const attendi = 1;
int const deb_pr = 2;
int const attendi_ril = 3;
int const debounce_ril = 4;
int const attendi_multip = 5;

int pulsante = 0;

int conto = 0;

unsigned long eventTime = 0;




void setup() {
  Serial.begin(9600);
  pinMode(Button_pin, INPUT);
}
void loop() {
  pulsante = (digitalRead(Button_pin));
  stato = attendi;

  switch (stato) {

    case attendi:
    //Serial.print("Attendo ");
      conto = 0;
      if (pulsante == HIGH) {
       //Serial.print("   premuto   ");        
        eventTime = millis();
        stato = deb_pr;
        
      }
      break;

    case deb_pr:
        Serial.print("  premuto debounce  ");
        if ((millis() - eventTime) >= (dpt)) {
          Serial.print("  dovrei andare in attendi rilascio  ");
          eventTime = millis();
          stato = attendi_ril;
          
        }
        //else {
        //  stato = attendi;
        //  Serial.println("  vado in attesa per via del tempo debounce ");
       //}
        break;
      
    case attendi_ril :
      Serial.println ("Attendo rilascio");
      if (pulsante == LOW) {

        if ((millis() - eventTime) > ht) {
          stato = attendi;
          conto = -1;
          Serial.print("pressione lunga");
        }
      }
      else {
        stato = debounce_ril;
        eventTime = millis();
      }

      break;


    case debounce_ril:
      if ((millis() - eventTime) > drt) {
        conto += 1;
        stato = attendi_multip;
        eventTime = millis();
      }
      else stato = attendi;
      break;

    case attendi_multip:
      if (pulsante == HIGH) {
        stato = deb_pr;
        eventTime = millis();
      }
      else if ((millis() - eventTime) > mct) {
        stato = attendi;
        conto ++;
      }
      break;

  }
  if (conto != 0) {
    Serial.print(conto);
  }
}

Buongiorno, :slight_smile:
essendo il tuo primo post, nel rispetto del regolamento della sezione Italiana del forum (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con molta attenzione tutto il su citato REGOLAMENTO ... Grazie. :slight_smile:

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposito thread, nessuno ti potrà rispondere, quindi ti consiglio di farla al più presto. :wink:

L'errore macroscopico che vedo è la variabile 'stato' impostata a 1 ad ogni ciclo di programma.

Claudio_FF:
L’errore macroscopico che vedo è la variabile ‘stato’ impostata a 1 ad ogni ciclo di programma.

Questa ovviamente non la sapevo… Potresti fornirmi maggiori dettagli?

Appena prima dello switch hai scritto stato=attendi;
quindi ad ogni giro viene eseguito sempre e solo lo stato attendi

Più chiaro di cosi:

void loop() {
  pulsante = (digitalRead(Button_pin));
  stato = attendi;[/color]
  //  stato vale SEMPRE 1 !!

Devi rivedere gli stati del tuo sistema. Partirà a 1 (nel setup) e poi ci sarà un momento in cui torna a 1. Non può di certo essere fisso a 1

Inoltre le variabili dei pin possono essere const e byte
const byte Button_pin=2;
e questa sintassi non è corretta:
int const attendi = 1; const va prima const int attendi=1;

Consiglio anche di separare nettamente la gestione del debounce da quella delle altre temporizzazioni.

Lavorando con una variabile lettura già pulita, la logica si semplifica molto.

Il debounce può anche essere realizzato in hardware con un condensatore da 100nF..1uF tra l'ingresso e GND, così il software si semplifica ancora.

Salve.
Mi avete giustamente detto quello che non andava nel mio sketch…
Dopo parecchio arrovellarmi sono giunto alla conclusione, a farlo funzionare e ad ottenere quello che volevo. Ho eliminato il switch case che avevo inserito nel mio primo tentativo…

Vi allego lo sketch, se a qualcuno volesse interessare o se qualcuno avesse dei suggerimenti su come migliorare.
In pratica ad ogni pressione allungo il tempo di accensione del relay, che comunque si spegne alla fine di un tempo predeterminato. O tenendo premuto il pulsante, lo spengo anticipatamente.

[code]
int Button_pin = 2; //pin pulsante
int Relay_pin = 12; // pin relay o led

unsigned long upTime = 0; //Tempo pressione pulsante
unsigned long downTime = 0;  // Tempo rilascio pulsante
unsigned long Diff_Time = 1; // Durata pressione

unsigned long eventTime = 0; // Contatore durata accensione
unsigned long Durata = 1; // Durata dell'accensione del Relay


unsigned long debounce = 20;  //temp debounce
unsigned long longpress = 1500; //durata pressione lunga
unsigned long UdA = 2000; //unità di accensione (UdA * n = Durata accensione Relay)
int n = 0; // numero di pressioni

int finestra_up = 0;
int finestra_down = 0;


void setup() {
  Serial.begin(9600);
  pinMode(Button_pin, INPUT);
  pinMode(Relay_pin, OUTPUT);

}

void loop() {

  int pulsante = digitalRead(Button_pin);


  if ((pulsante == HIGH) & (finestra_up == 0)) {
    upTime = millis();
    finestra_up = 1;
    finestra_down = 0;
    //eventTime = millis();
    //Serial.println (upTime);
    Serial.print( "  PREMUTO  " ) ;
  }

  if ((pulsante == LOW) & (finestra_down == 0)) {
    Serial.println( "  RILASCIO  " ) ;
    downTime = millis();
    //Serial.println (downTime);
    finestra_down = 1;
    finestra_up = 0;
    Diff_Time = (downTime - upTime);
    //Serial.println (Diff_Time);
  }

  if (Diff_Time > longpress) {
    n = 0;
    Diff_Time = 0;
    digitalWrite(Relay_pin, LOW);
    Serial.println ("  SPENGO  ");
  }

  if  ((Diff_Time > debounce) & (Diff_Time < longpress)) {

    n ++ ;
    Diff_Time = 0;
    Serial.print ("  premuto  ");
    Serial.print (n);
    Serial.println (" volte  ");
    Durata = ((n) * UdA);
    Serial.print ( "  durata =  " ) ;
    Serial.println(Durata);

    digitalWrite(Relay_pin, HIGH);
  }

  if ((millis() - upTime) >= (Durata)) {

    digitalWrite (Relay_pin, LOW );
    n = 0;

  }
}

/code]