Programma controllo led-pulsante

Salve a tutti volevo provare a realizzare il sequente programma:
-3 led (uno verde, uno giallo e uno rosso) e un pulsante.
Inizialmente il sistema parte col led verde acceso fisso per 20 secondi.
Dopo 20 secondi, il led verde comincia a lampeggiare a cadenza di un secondo. Inoltre da questo momento è possibile resettare il sistema premendo il pulsante.
Dopo altri 10 secondi, il led verde si spenge e si accende a intermittenza il led giallo.
Infine, dopo altri 10 secondi, si accende anche il led rosso a intermittenza (assieme a quello giallo).

Ho provato a buttare giù due righe, ma mi sono bloccato e il compilatore dice che il codice non è giusto. Sapete aiutarmi? Grazie!

Vi posto il programma che ho provato a fare. Non è completo, ma vorrei sapere se da qui posso continuare…

#define g 13    //pin led verde
#define y 12    //pin led giallo
#define r 11    //pin led rosso
#define p 2    //pin pulsante


int stato = 0;    //lo stato del sistema

void setup() {
  pinMode(g, OUTPUT);    //imposta led verde come uscita
  pinMode(y, OUTPUT);    //imposta led giallo come uscita
  pinMode(r, OUTPUT);    //imposta led rosso come uscita
  pinMode(p, INPUT);    //imposta il pulsante come entrata
}

void loop() {
  if (stato==0)
  {
    for (int i=0; i <= 2000; i++){
    digitalWrite (g, HIGH);}
    stato=1;
  }
  if (stato==1) {
    while (p==LOW){
    digitalWrite (g, LOW);
    delay (1000);
    digitalWrite (g, HIGH);
    }
  }
}

i define mi sa che li vuole maiuscoli…
questo compila…

#define G 13    //pin led verde
#define Y 12    //pin led giallo
#define R 11    //pin led rosso
#define P 2    //pin pulsante


int stato=0;    //lo stato del sistema

void setup() {
  pinMode(G, OUTPUT);    //imposta led verde come uscita
  pinMode(Y, OUTPUT);    //imposta led giallo come uscita
  pinMode(R, OUTPUT);    //imposta led rosso come uscita
  pinMode(P, INPUT);    //imposta il pulsante come entrata
}

void loop() {
  if (stato==0)
  {
    for (int i=0; i <= 2000; i++){
    digitalWrite (G, HIGH);
  }
    stato=1;
  }
  if (stato==1) {
    while(P==LOW){
    digitalWrite (G, LOW);
    delay(1000);
    digitalWrite (G, HIGH);
    }
  }
}

Ciao

la tua sfortuna è che hai definito come costante la lettera "p" che nelle librerie core di Arduino viene usata comunemente per indicare i parametri delle funzioni... quindi il compilatore ha sostituito tutte quelle belle "p" con il numero 2 e ha dato ko :roll_eyes:

Il consiglio è di usare costanti con nomi un po' più univoci di una lettera...

mi sembra di vedere un po’ di casino con l’if e anche il for…

void loop() {
  if (stato==0) -->qui controlli se è a 0 è inialmente lo è
  {
    for (int i=0; i <= 2000; i++){  --> se con questo for volevi fare una pausa devi usare delay o millis (che non ferma l'esec. del codice)
    digitalWrite (G, HIGH);  --> accendi led verde
  }
    stato=1; -->qui imposti la variabile stato a 1 e quindi quindi il prossimo if sicuramente lo trova a 1
  }
  if (stato==1) {   
    while(P==LOW){ --qui inizi un ciclo while che prosegue fino a quando il pulsante non viene premuto
    digitalWrite (G, LOW);
    delay(1000);        ---> se premi il pulsante quando sei in pausa non ti prende il comando, usa millis
    digitalWrite (G, HIGH); 
    }  --> qui mi sa che dovrai aggiungere uno stato=0 altrimenti non sarà mai verde e poi gli automobilisti strombazzano :D
  }
}

Io riscriverei di nuovo il codice completando prima la logica dei led, e poi successivamente la parte del pulsante…

Allora ho provato a riscriverlo da zero e mi è venuto così:

#define Verde 13    //pin led verde
#define Giallo 12    //pin led giallo
#define Rosso 11    //pin led rosso
#define Pulsante 2    //pin pulsante


int stato = 0;    //lo stato del sistema

void setup() {
  pinMode(Verde, OUTPUT);    //imposta led verde come uscita
  pinMode(Giallo, OUTPUT);    //imposta led giallo come uscita
  pinMode(Rosso, OUTPUT);    //imposta led rosso come uscita
  pinMode(Pulsante, INPUT);    //imposta il pulsante come entrata
}

void loop() {
  digitalWrite (Verde, HIGH);    //led verde sempre acceso
  delay(10000);                  //per 10 secondi
    stato=1;                     //passo allo stato 1
  for (int i = 0; i==10;) //ripete lo stato 1 per 10 secondi
  {
  digitalWrite (Verde, LOW);     //il led verde si spenge
  delay(1000);                   //per un secondo
  digitalWrite (Verde, HIGH);    //il led verde si accende
  delay(1000);                    //per un secondo
  i++;
  }
  digitalWrite (Verde, LOW);
   for (int i = 0; i==10;) //ripete lo stato 2 per 10 secondi
   {
     digitalWrite (Giallo, HIGH); //giallo accesso
     delay(1000);                 //per 1 secondo
     digitalWrite (Giallo, LOW);  //giallo spento
     delay(1000);                //per 1 secondo
     i++;
   }
   while (stato==1) {
     digitalWrite (Giallo, HIGH);
     digitalWrite (Rosso, HIGH);
     delay(1000);
     digitalWrite (Giallo, LOW);

   }
}

Ora il programma parte, ma rimane acceso il led verde e dopo 10 secondi si accendono quello giallo e quello rosso in modo continuo. Quindi la parte del verde lampeggiante, del giallo lampeggiante e del giallo & rosso lampeggiante vengono completamente saltate. Cosa ho sbagliato?

il ciclo for, se metti i = 0; i == 10 esce subito (gli stai dicendo, parti da 0 e continua finché i == 10, che è subito falso e quindi esce dal ciclo)

correttamente sarebbe for(i = 0; i < 10; i++) {

in questo modo puoi togliere anche il comando i++ nel loop
bye

grazie lucadentella! Questo è il programma SENZA il pulsante:

#define Verde 13    //pin led verde
#define Giallo 12    //pin led giallo
#define Rosso 11    //pin led rosso
#define Pulsante 2    //pin pulsante


int stato = 0;    //lo stato del sistema

void setup() {
  pinMode(Verde, OUTPUT);    //imposta led verde come uscita
  pinMode(Giallo, OUTPUT);    //imposta led giallo come uscita
  pinMode(Rosso, OUTPUT);    //imposta led rosso come uscita
  pinMode(Pulsante, INPUT);    //imposta il pulsante come entrata
}

void loop() {
  digitalWrite (Verde, HIGH);    //led verde sempre acceso
  delay(10000);                  //per 20 secondi
    stato=1;                     //passo allo stato 1
  for (int i = 0; i < 10; i++) //ripete lo stato 1 per 10 secondi
  {
  digitalWrite (Verde, LOW);     //il led verde si spenge
  delay(1000);                   //per un secondo
  digitalWrite (Verde, HIGH);    //il led verde si accende
  delay(1000);                    //per un secondo
  
  }
  digitalWrite (Verde, LOW);
   for (int i = 0; i < 10; i++) //ripete lo stato 2 per 10 secondi
   {
     digitalWrite (Giallo, HIGH); //giallo accesso
     delay(1000);                 //per 1 secondo
     digitalWrite (Giallo, LOW);  //giallo spento
     delay(1000);                //per 1 secondo
     
   }
   while (stato==1) {
     digitalWrite (Giallo, HIGH);
     digitalWrite (Rosso, HIGH);
     delay(1000);
     digitalWrite (Giallo, LOW);
     digitalWrite (Rosso, LOW);
     delay(1000);

   }
}

Ora per quanto riguarda il pulsante, ho provato a fare un digitalread e a mettere il risultato in una variabile detta valore. Ho fatto poi un if e se valore è uguale a 1 (cioè alto), faceva un goto all’inizio di loop. Il problema è che con goto non mi prende la funzione loop (dice è stata usata ma non è definita), quindi ho provato a creare una funzione che contenesse il programma inziale (quello col led verde), ma come al solito sono sortiti i peggio errori. Quindi la mia domanda è questa: c’è un modo per dire al programma da questo momento in poi se viene premuto il pulsante torna all’inizio?

Dimentica il goto! :-) La funzione loop() viene chiamata ripetutamente, all'infinito (a meno che non ci sia un ciclo infinito al suo interno, ovviamente).

Secondo me dovresti strutturare il programma in base al valore di "stato", magari con uno switch/case. La pressione del pulsante potrebbe riportare la variable "stato" al valore iniziale (ad esempio 0). In questo modo la sequenza dei led ripartirebbe dal principio.

Dopo 20 secondi, il led verde comincia a lampeggiare a cadenza di un secondo. Inoltre da questo momento è possibile resettare il sistema premendo il pulsante.
Dopo altri 10 secondi, il led verde si spenge e si accende a intermittenza il led giallo.

for (int i = 0; i < 10; i++) //ripete lo stato 1 per 10 secondi

{
  digitalWrite (Verde, LOW);    //il led verde si spenge
  delay(1000);                  //per un secondo
  digitalWrite (Verde, HIGH);    //il led verde si accende
  delay(1000);                    //per un secondo

dici dopo 10 secondi, questo ciclo dura 20 secondi
Il tuo arduino deve solo fare questo? perchè lo impegni con tutti sti delay e non riuscirà a fare altro nel frattempo.

ciao

lo switch/case che dovrei fare lo devo mettere all'inizio del programma o in fondo?

si pablos hai ragione infatti quando l'ho provato me ne sono reso conto che ci metteva 20 secondi, ma in che senso non riesce a fare altro?

Shakalaka93:
lo switch/case che dovrei fare lo devo mettere all’inizio del programma o in fondo?

si pablos hai ragione infatti quando l’ho provato me ne sono reso conto che ci metteva 20 secondi, ma in che senso non riesce a fare altro?

Scusa, ma non capisco la domanda: cosa intendi dire con “all’inizio o in fondo” ?

Ciao!

come dice giustamente Pablos, hai un problema di fondo... tu vorresti far eseguire "contemporaneamente" due cose:

  • controllo dello stato del pulsante -> se premuto riparto da capo
  • sequenza di lampeggio

questo è difficile se usi dei delay(), l'unica è che dopo (o prima) di ognuno di questi controlli il pulsante e, se premuto, fai un "return" che chiude l'esecuzione del loop() attuale e ricomincia da capo (http://arduino.cc/it/Reference/Return)

Altrimenti dovresti rivedere tutto il tuo programma in modo da non utilizzare i delay che sono "bloccanti", ma con un approccio tipo l'esempio del blinking led (http://arduino.cc/en/Tutorial/BlinkWithoutDelay)

bye