Problema con lo Switch Case

salve a tutti 8) mi sono appena iscritto al forum :slight_smile:
Premetto che : non ho ancora una basetta Arduino , ma ben presto , quando sarà possibile ne comprerò una. Nel frattempo in vista degli esami del quarto anno , da appassionato , ho già in mente un progetto nel quale userò Arduino. E per non appesantirmi il prossimo Anno fra vari impegni ho deciso già da ora di studiarlo. Fra vari video e guide su Internet ho capito qualcosa , e ho imparato maggiormente il C anche se ho ancora molte lagune. Tramite un programma di simulazione ( al quanto limitato e scadente ) della basetta in questione , ho provato gli esempi del software Arduino 1.0.5. Alcuni mi sembrano ben chiari altri forse è meglio provarli sul socket.
Andando al mio problema : ho provato a creare un programma che tutto sommato funziona.. solo che quando ci sono delle Delay , non funziona più come dovrebbe : si tratta di uno Switch Case.

Questo è il Programma :

const int pulsante = 10;
const int led      = 12;
const int led2     = 13;
const int led3     = 11;
int stato = 0;
int inizio        = 0;
int ultimo        = 0;
int count         = 0;

void setup() {
  pinMode(led,OUTPUT);
  pinMode(pulsante,INPUT);
  pinMode(led2,OUTPUT);
  pinMode(led3,OUTPUT);

}

void loop(){
  digitalWrite(led,LOW);
  if  (digitalRead(pulsante))
  {
    delay(1000);
    if (count<2) count=count+1 ;
    else count=0;

  }

  switch (count)
  {
  case 0:
    digitalWrite(led,HIGH);
    digitalWrite(led2,HIGH);
    break;

  case 1:
    digitalWrite(led2,LOW);
    digitalWrite(led,LOW);
    break;

  case 2:
    if (digitalRead(pulsante)) break;
    digitalWrite(led,HIGH);
    if (digitalRead(pulsante)) break;
    delay(500);
    if (digitalRead(pulsante)) break;
    digitalWrite(led,LOW);
    if (digitalRead(pulsante)) break;
    delay(500);
    if (digitalRead(pulsante)) break;
    break;


  }
}

Quando vado a premere per la 3 volta il pulsante , per far partire il "Case 3" questo non torna al "Case 0" ... a causa , probabilmente delle delay ..

Una soluzione al problema?
Accetto ogni tipo di correzione .
Grazie in anticipo :wink:

Io codice deve essere racchiuso negli appositi tag, come da regolamento.
Usa il pulsante con il simbolo #, li mette lui. Il codice và messo entro quei due tag (altrimenti alcune parti del codice possono perdersi)

Comunque, quale "case 3" ?

Scusa intendevo dire "case 2" comunque non ho capito cosa intendi , scusa l'ignoranza.. in teoria quando vado a premere la prima volta il pulsante il "led" e il "led2" devono essere accesi , quando lo premo per la seconda volta spenti e quando lo premo per la terza volta il "led" deve lampeggiare.

Ciao Magnum, benvenuto.
Sarebbe gradita una presentazione nell'apposito topic --> Re: Presentazioni nuovi iscritti, fatevi conoscere da tutti! (Part 1) - Generale - Arduino Forum
e poi non dispiacerebbe se leggessi anche il funzionamento del forum --> http://forum.arduino.cc/index.php?topic=149082.0 in particolare il punto 7 e il punto 11.

Riguardo il codice, prima di pubblicarlo, se lo stai scrivendo con l'IDE di Arduino, ricordati di usare il comando "Formattazione automatica". In questo modo, a parte verificare se sono presenti tutte le parentesi in ugual misura(tante aperte quanto chiuse), il codice viene identato ovvero vengono aggiunte le tabulazioni in modo che la lettura del codice, soprattutto i cicli, sia facilitata.

count a 3 non arriverà mai perché se non è minore di 2 viene azzerato: quindi varia tra 0 e 2.
Inoltre tu leggi il pulsante molte volte nel ciclo, e per quanto veloce possa essere il ciclo, lo stato del puntante potrebbe variare.
Ti conviene leggero ad inizio ciclo assegnandolo ad una variabile e poi ragionare sullo stato della variabile.

p.s. Hai usato QUOTE e non CODE :grin:

case 2:
  digitalWrite(led,HIGH);
  delay(500);
  digitalWrite(led,LOW);
  delay(500);
  break;

Forse volevi fare cosi? :wink:

per quanto riguarda il "case 3" avevo solo sbagliato a scrivere :grin: per quanto riguarda il programma , invece , io inizialmente ho fatto come hai scritto tu :

case 2:

      digitalWrite(led,HIGH);
      delay(500);
      digitalWrite(led,LOW);
      delay(500);
      break;

poi fra tentativi e ragionamenti ho aggiunto le condizioni "if" però non ho concluso niente xD

case 2:
    if (digitalRead(pulsante)) break;
    digitalWrite(led,HIGH);
    if (digitalRead(pulsante)) break;
    delay(500);
    if (digitalRead(pulsante)) break;
    digitalWrite(led,LOW);
    if (digitalRead(pulsante)) break;
    delay(500);
    if (digitalRead(pulsante)) break;
    break;

P.s. ho modificato in code :smiley:

Tornando al programma ora lo riscriverò meglio aggiungendo anche qualche commento per renderlo più chiaro :slight_smile:

Si ho capito in ritardo , credo che adesso vada bene , giusto? :roll_eyes:

// Esempio 05:  
// Primo tocco:   I led si accendono
// Secondo tocco: I led si spengono 
// Terzo tocco:   Uno dei due led lampeggia


const int pulsante = 10;  // Pin dove è collegato il pulsante
const int led      = 12;  // Pin dove è collegato un led
const int led2     = 13;  // Pin dove è collegato un led
int count          = 0;   // Conteggio del bottone

void setup() {
  pinMode(led,OUTPUT);    // imposta il pin come pin d'ucita
  pinMode(pulsante,INPUT);// impasta il pin come pin d'ingresso
  pinMode(led2,OUTPUT);

}

void loop(){
  if  (digitalRead(pulsante)) // verifico se l'utente ha premuto il pulsante
  {
    delay(1000);              // do un secondo di tempo in modo che l'utente possa levare il dito dal pulsante
    if (count<2) count=count+1 ; // Incremento la variabile count ( ovvero le volte che il pulsante viene premuto )
    else count=0;

  }

  switch (count)  //In base allo stato del bottone scelgo l'azione del led   
  {
  case 0:
    digitalWrite(led,HIGH); // Accendo il led
    digitalWrite(led2,HIGH);// Accendo il led2
    break;                   

  case 1:
    digitalWrite(led2,LOW); //Spengo il led
    digitalWrite(led,LOW);  //Spengo il led2
    break;

  case 2:
    digitalWrite(led,HIGH);  //in questa case faccio lampeggiare il led
    delay(500);
    digitalWrite(led,LOW);
    delay(500);
    break;


  }
}

Credo adesso sia più chiaro.. allora : in poche parole quando premo il pulsante per la 4 volta ( ovvero quando mi dovrebbe riaccendere entrambi i led ) devo provarci più volta affinché questo accada.. ho pensato a mettere degli "if" in modo da interrompere il "case 2" ogni volta che il pulsante viene premuto , ma ho risolto poco ...

Sono molto ignorante in campo di programmazione però sono molto appassionato e vorrei imparare .. accetto ogni consiglio e insegnamento :slight_smile:

questo pezzo non è che mi convinca molto, 1000 di delay sono un po' tanti per un debounce su un pulsante (di norma 50-100 sono sufficienti)

 if  (digitalRead(pulsante)) // verifico se l'utente ha premuto il pulsante
  {
    delay(1000);              // do un secondo di tempo in modo che l'utente possa levare il dito dal pulsante
    if (count<2) count=count+1 ; // Incremento la variabile count ( ovvero le volte che il pulsante viene premuto )
    else count=0;
  }

Io mi assicurerei prima di tutto che il pulsantino si comporti correttamente alle pressioni e risponda bene ai tempi prestabiliti, poi si da il risultato filtrato e corretto in pasto al resto dell'elaborazione

Comincia col usare un debounce non invasivo tipo questo che utilizza un millis():

metti un led e osserva se esso fa quello che deve fare alle varie pressioni con le giuste modifiche allo sketch, se non è soddisfacente aggiungi un debounce hardhare.

ciao

@Pablos
Nel primo post Magum ha scritto che non ha ancora Arduino e sta facendo le prove su un simulatore software. :wink:

@Magum
Ricordati, quando avrai l'Arduino, che con i led è necessaria una resistenza in serie; altrimenti bruci led e pin di Arduino.

Mi è sfuggita la questione del simulatore, io non mi fido dei simulatori, secondo me impari più velocemente con Arduino davanti che con un simulatore. Il rapporto e 1/10, comunque in quel programma manca il salvataggio su variabile dello stato del pulsante
Ciao

Sono d'accordissimo ... però con questo progettino banale , è uscito fuori un problema ... e onestamente vorrei risolverlo... in poche parole il mio intento è quello di far cambiare stato a questo benedetto led però nel momento in cui c'è una delay di mezzo devo premere il led + volte affinché cambi stato... avete qualche suggerimento? o soluzione? :frowning:

magum12:
avete qualche suggerimento? o soluzione? :frowning:

Si, ma il codice si complica e non poco.
Cerca l'esempio "Blink without delay".

Si, ma il codice si complica e non poco.
Cerca l'esempio "Blink without delay".

Beh non è molto difficile in fin dei conti.. ora cerco di approfondirlo meglio :slight_smile: Grazie .. in caso di bisogno faccio un fischio :stuck_out_tongue:

:smiley: Ok ho risolto Vi ringrazio a tutti quanti :slight_smile: Ho semplicemente rifatto il programma inserendo in ogni "case" l'esempio del "blinkwithoutdelay" :smiley:

Ecco il programma

int StatoLed =LOW;
const int pul = 4 ;
const int led = 13;
long pMillis =0;
long interval =1000;
long interval1=500; 
int       count=0;
void setup() {
  pinMode(led,OUTPUT);
  pinMode(pul,INPUT);


}

void loop() {
  if (digitalRead(pul)) {

    delay(250);
    if (count < 2) count=count+1;
    else count=0;
  }
  switch(count)
  {
  case 1:
    {
      unsigned long cMillis = millis();

      if ( cMillis - pMillis > interval ){
        pMillis = cMillis;

        if (StatoLed == LOW)
          StatoLed = HIGH;
        else
          StatoLed = LOW;
        digitalWrite(led,StatoLed);

      }
    }
    break;
  case 2:
    {
      unsigned long cMillis = millis();

      if ( cMillis - pMillis > interval1 )
      {
        pMillis = cMillis;

        if (StatoLed == LOW)
          StatoLed = HIGH;
        else
          StatoLed = LOW;
        digitalWrite(led,StatoLed);
      }

      break;
    }
  case 0:
    {
      digitalWrite(led,LOW);
      break;
    }

  }
}

è uscito fuori un problema ... e onestamente vorrei risolverlo... in poche parole il mio intento è quello di far cambiare stato a questo benedetto led però nel momento in cui c'è una delay di mezzo devo premere il led + volte affinché cambi stato... avete qualche suggerimento? o soluzione?

Veramente te lo avevo detto al post #7 come usare un delay tramite millis()

davvero? non ci avevo fatto completamente caso... mi sono soffermato sull'antirimbalzo senza farci caso , scusa :blush: