programma per semplice semaforo

Salve,
questo è il mio primo post, pertanto vorrei iniziare col ringraziare Massimo Banzi, per la semplice, ma quanto geniale soluzione di arduino.
E’ spiego subito il perchè! XD
Sono un perito elettronico diplomato nel 2002, e ricordo benissimo le difficoltà riscontrare durante le sperimentazioni in classe per programmare e realizzare circuiti con gli AVR90 e i costosi tool di sviluppo della ATMEL =(
Quindi Massimo Banzi e arduino “santo subito”! XD

Ma veniamo all’oggetto del post.
Premetto che ho ordinato il mio arduino e quindi sto sperimentado con il programma VirtualBreadbord 4.2.9
Ho realizzato un semplice programma che controlla un semaforo.
Tramite 4 pulsanti, si ha la possibilità, di accendere solo il verde, far lampeggiare solo il giallo, accendere solo il rosso, o avviare la sequenza semaforica.

/*
Programma per centralina semaforo
 Note:
 Premendo sul pulsante collegato al pin3, accende il verde;
 Al pin4, accende il giallo con lampeggiante;
 Al pin5, accende il rosso;
 Al pin6, avvia sequenza semaforica.
 */
 
const int green = 12;    //led colleged to digital pin
const int yellow = 11;
const int red = 10;
const int pushGreen = 3;
const int pushYellow = 4;  // push colleged to digital pin
const int pushRed = 5;
const int pushSequence = 6;


void setup() {
    //inizializzo il pinmode in output
    pinMode(green, OUTPUT);
    pinMode(yellow, OUTPUT);
    pinMode(red, OUTPUT);
    //inizializzo il pinmode in input
    pinMode(pushGreen, INPUT);
    pinMode(pushYellow, INPUT);
    pinMode(pushRed, INPUT);
    pinMode(pushSequence, INPUT);
              }
              
void loop() {
        // accensione del solo verde
       int buttonStateGreen = digitalRead(pushGreen);
        if (buttonStateGreen == HIGH){
                  digitalWrite(green, HIGH);
                              } 
                              else {
                                      digitalWrite (green, LOW);
                              }
                              
                             //accensione e lampeggio del giallo
                              int buttonStateYellow = digitalRead(pushYellow);
        if (buttonStateYellow == HIGH){
                  digitalWrite(yellow, HIGH);
                                delay(500);
                                digitalWrite(yellow, LOW);
                                delay(500);
                              } 
                              else {
                                      digitalWrite (yellow, LOW);
                                      }
                              
                             //accensione del solo rosso
                              int buttonStateRed = digitalRead(pushRed);
        if (buttonStateRed == HIGH){
                  digitalWrite(red, HIGH);
                              } 
                              else {
                                      digitalWrite (red, LOW);
                              }
                              //avvio sequenza semaforica
                              int buttonStateSequence = digitalRead(pushSequence); 
        if (buttonStateSequence == HIGH){
                  digitalWrite(green, HIGH);           //accendo verde
                  delay(30000);                          // verde acceso per 30 s
                  digitalWrite(green, LOW);                //spengo verde
                  digitalWrite(yellow, HIGH);             //accendo giallo
                  delay(5000);                           //giallo acceso per 5 s
                  digitalWrite(yellow, LOW);            //spengo giallo
                  digitalWrite(red, HIGH);              //accendo rosso
                  delay(30000);                         //rosso acceso per 30 s
                              } 
                              else {        //altrimenti spengo tutti i led
                                      digitalWrite (green, LOW);
                                      digitalWrite (yellow, LOW);
                                      digitalWrite (red, LOW);
                              }
                              }

Ora, a me il codice sembra corretto, ma su VirtualBreadboard, avviene questo:
Premendo il pulsante del giallo, lampeggia regolarmente;
La sequenze semaforica funziona, ma portando l’interrutore in possizione di OFF, non spegne il LED, ne rimane uno acceso,
Premendo i relativi pulsanti, solo verde, o solo giallo, quest’ultimi anzichè stare accessi lampeggiano.
Ho risolto eliminando l’ultimo ELSE.
Secondo voi è un bug di VirtualBreadboard, o c’è qualcosa che non va nel codice?

Grazie anticipate

circuito.jpg

gladio: Secondo voi è un bug di VirtualBreadboard, o c'è qualcosa che non va nel codice?

Grazie anticipate

Dando un occhio dovrebbe funzionare ma il bug di fondo è come è scritto. Metà delle righe non servono e ci perdi la testa. Primo: non usare la tecnica delle graffe aperte a fine linea: è una moda stupida. Corretto è if [state] { funct(); }

Secondo non usare logiche ripetitive piene di parentesi. Corretto è: if [parm] funct1(); else funct2(); Su una sola linea senza parentesi e chiamando funzioni.

Ad esempio: if (buttonStateYellow == HIGH){ digitalWrite(yellow, HIGH); delay(500); digitalWrite(yellow, LOW); delay(500); } else { digitalWrite (yellow, LOW); }

è inutile l'else e meglio era:

if (buttonStateYellow == HIGH) { digitalWrite(yellow, HIGH); delay(500); digitalWrite(yellow, LOW); delay(500); }

Comunque se da lì passa si spegne dopo.... Ma non voglio fare il nonno del forum, poi mi odiate alla fine. Sappimi dire dopo la semplificazione.

Ciao Paolo, il problema dell' IF è più stilistico che funzionale, comunque hai ragione, il codice anche "visivamente" è un po' un casino, cioè si fa fatica a capire dove inizia e finisce un ciclo. Prova ogni tanto a chiamare l'Auto Format (Ctrl+T)

/*
Programma per centralina semaforo
 Note:
 Premendo sul pulsante collegato al pin3, accende il verde;
 Al pin4, accende il giallo con lampeggiante;
 Al pin5, accende il rosso;
 Al pin6, avvia sequenza semaforica.
 */

const int green = 12;    //led colleged to digital pin
const int yellow = 11;
const int red = 10;
const int pushGreen = 3;
const int pushYellow = 4;  // push colleged to digital pin
const int pushRed = 5;
const int pushSequence = 6;


void setup() {
  //inizializzo il pinmode in output
  pinMode(green, OUTPUT);
  pinMode(yellow, OUTPUT);
  pinMode(red, OUTPUT);
  //inizializzo il pinmode in input
  pinMode(pushGreen, INPUT);
  pinMode(pushYellow, INPUT);
  pinMode(pushRed, INPUT);
  pinMode(pushSequence, INPUT);
  digitalWrite(red, LOW);              
  digitalWrite(yellow, LOW);              
  digitalWrite(green, LOW);              
}

void loop() {
  // accensione del solo verde
  int buttonStateGreen = digitalRead(pushGreen);
  if (buttonStateGreen == HIGH){
    digitalWrite(green, HIGH);
  } 
  else {
    digitalWrite (green, LOW);
  }

  //accensione e lampeggio del giallo
  int buttonStateYellow = digitalRead(pushYellow);
  if (buttonStateYellow == HIGH){
    digitalWrite(yellow, HIGH);
    delay(500);
    digitalWrite(yellow, LOW);
  } 
  else {
    digitalWrite (yellow, LOW);
  }

  //accensione del solo rosso
  int buttonStateRed = digitalRead(pushRed);
  if (buttonStateRed == HIGH){
    digitalWrite(red, HIGH);
  }   
  else {
    digitalWrite (red, LOW);
  }

  //avvio sequenza semaforica
  int buttonStateSequence = digitalRead(pushSequence); 
  if (buttonStateSequence == HIGH){
    digitalWrite(green, HIGH);           //accendo verde
    delay(30000);                          // verde acceso per 30 s
    digitalWrite(green, LOW);                //spengo verde
    digitalWrite(yellow, HIGH);             //accendo giallo
    delay(5000);                           //giallo acceso per 5 s
    digitalWrite(yellow, LOW);            //spengo giallo
    digitalWrite(red, HIGH);              //accendo rosso
    delay(30000);                         //rosso acceso per 30 s
    digitalWrite(red, LOW);              
    digitalWrite(yellow, LOW);              
    digitalWrite(green, LOW);              
  } 
}

Secondo me l'ultimo else è inutile visto che ti spegne tutto. Hai messo delle resistenze di pulldown?

Intanto vi ringrazio per le risposte. @Paolo, per carità ogni consiglio è sempre ben accetto. Effettivamente l' ELSE in quel passaggio non serve, sicuramente meglio come l'hai scritto tu:

if (buttonStateYellow == HIGH) { digitalWrite(yellow, HIGH); delay(500); digitalWrite(yellow, LOW); delay(500); }

ma solo in quel passagio, altrimenti, nei casi di sola luce verde, o sola luce rossa, se non metto ELSE l'uscita mi rimane in HIGH.

Questo è il codice rivisto. Ditemi cosa ve ne pare.

/*
Programma per centralina semaforo
 Note:
 Premendo sul pulsante collegato al pin3, accende il verde;
 Al pin4, accende il giallo con lampeggiante;
 Al pin5, accende il rosso;
 Al pin6, avvia sequenza semaforica.
 */

const int green = 12;    //led colleged to digital pin
const int yellow = 11;
const int red = 10;
const int pushGreen = 3;
const int pushYellow = 4;  // push colleged to digital pin
const int pushRed = 5;
const int pushSequence = 6;


void setup() {
  //inizializzo il pinmode in output
  pinMode(green, OUTPUT);
  pinMode(yellow, OUTPUT);
  pinMode(red, OUTPUT);
  //inizializzo il pinmode in input
  pinMode(pushGreen, INPUT);
  pinMode(pushYellow, INPUT);
  pinMode(pushRed, INPUT);
  pinMode(pushSequence, INPUT);
}

void loop() {
  // accensione del solo verde
  int buttonStateGreen = digitalRead(pushGreen);
  if (buttonStateGreen == HIGH)
      {
    digitalWrite(green, HIGH);
      } 
  else {
    digitalWrite (green, LOW);
      }

  //accensione e lampeggio del giallo
  int buttonStateYellow = digitalRead(pushYellow);
  if (buttonStateYellow == HIGH)
  {
    digitalWrite(yellow, HIGH); delay(500);
    digitalWrite(yellow, LOW); delay(500);
  } 

  //accensione del solo rosso
  int buttonStateRed = digitalRead(pushRed);
  if (buttonStateRed == HIGH)
  {
    digitalWrite(red, HIGH);
  } 
  else {
    digitalWrite (red, LOW);
      }
      
  //avvio sequenza semaforica
  int buttonStateSequence = digitalRead(pushSequence); 
  if (buttonStateSequence == HIGH)
  {
    digitalWrite(green, HIGH);           //accendo verde
    delay(30000);                          // verde acceso per 30 s
    digitalWrite(green, LOW);                //spengo verde
    digitalWrite(yellow, HIGH);             //accendo giallo
    delay(5000);                           //giallo acceso per 5 s
    digitalWrite(yellow, LOW);            //spengo giallo
    digitalWrite(red, HIGH);              //accendo rosso
    delay(30000);                         //rosso acceso per 30 s
    digitalWrite(red, LOW); 
  } 
  //per spegnere i led, stacco l'alimentazione :)
}

Mi spiego meglio.

/* Programma per centralina semaforo Note: Premendo sul pulsante collegato al pin3, accende il verde; Al pin4, accende il giallo con lampeggiante; Al pin5, accende il rosso; Al pin6, avvia sequenza semaforica. */

// ****** Mai usare variabili (è legato al compilatore l'interpretazione di const come spazio in // memoria ) per quelle che sono #define!!!!!!!!!!!! ************

define green 12 //led colleged to digital pin

define yellow 11

define red 10

define pushGreen 3

define pushYellow 4 // push colleged to digital pin

define pushRed 5

define pushSequence 6

void setup() { //inizializzo il pinmode in output pinMode(green, OUTPUT); pinMode(yellow, OUTPUT); pinMode(red, OUTPUT); //inizializzo il pinmode in input pinMode(pushGreen, INPUT); pinMode(pushYellow, INPUT); pinMode(pushRed, INPUT); pinMode(pushSequence, INPUT); }

void loop() { // accensione del solo verde

if (digitalRead(pushGreen) == HIGH) digitalWrite(green, HIGH); else digitalWrite (green, LOW);

//accensione e lampeggio del giallo

if (digitalRead(pushYellow) == HIGH) { digitalWrite(yellow, HIGH); delay(500); digitalWrite(yellow, LOW); delay(500); }

//accensione del solo rosso

if ( digitalRead(pushRed) == HIGH) digitalWrite(red, HIGH); else digitalWrite (red, LOW);

//avvio sequenza semaforica

if ( digitalRead(pushSequence) == HIGH) { digitalWrite(green, HIGH); //accendo verde delay(30000); // verde acceso per 30 s digitalWrite(green, LOW); //spengo verde digitalWrite(yellow, HIGH); //accendo giallo delay(5000); //giallo acceso per 5 s digitalWrite(yellow, LOW); //spengo giallo digitalWrite(red, HIGH); //accendo rosso delay(30000); //rosso acceso per 30 s digitalWrite(red, LOW); }

//per spegnere i led, stacco l'alimentazione :) }

Mi spiace ma l'ddentazione del codice sul forum non viene bene. Usa sempre un TAB prima di ogni dichiarazione. Iddenta il codice per renderlo visibile. Non nascondere le parentesi a destra, poi ti incasini.

Spero di non essere troppo noioso. Sai noi vecchiucci del PDP11 con RMS (io lo rimpiango altro che questo troiaio di W7) lo siamo.. :grin:

paolo1957: Mi spiace ma l'ddentazione del codice sul forum non viene bene.

Usando l'apposito tag te lo dovrebbe indentare per bene. E' il pulsantino con #.

Sai noi vecchiucci del PDP11 con RMS (io lo rimpiango altro che questo troiaio di W7) lo siamo.. :grin:

Uhm... troiaio? Si dice dalle mie parti... di dove sei, scusa? :)

[/quote]