sequenza led semaforica pulsante

ciao a tutti ho un problema con questa sequenza semaforica , quando tento di accenderla funziona tutto, ma il problema è quando ripremo il pulsante cotninua a lampeggiare non capisco come mai! ho bisogno di una mano

#define rosso1 13 
#define giallo1 12
#define verde1 11
#define rosso2 7
#define giallo2 6
#define verde2 5
#define BUTTON 2 
int val = 0; 
int vecchio_val = 0; 
int stato = 0;
void setup() { 
pinMode(rosso1, OUTPUT); 
pinMode(giallo1, OUTPUT);
pinMode(verde1, OUTPUT);
pinMode(rosso2, OUTPUT);
pinMode(giallo2, OUTPUT);
pinMode(verde2, OUTPUT);
pinMode(BUTTON, INPUT); 
}
void loop() { 
val = digitalRead(BUTTON); // leggo il valore dell'input
if ((val == HIGH) && (vecchio_val == LOW)){ 
stato = 1 - stato; 
delay(15); // attesa di 15 millisecondi 
}
vecchio_val = val;
if (stato == 1) { 
digitalWrite (rosso1, HIGH);
digitalWrite (verde2, HIGH);
digitalWrite (rosso2, LOW);
delay (5000);
digitalWrite (giallo2, HIGH);
digitalWrite (verde2, LOW);
delay (3000);
digitalWrite (rosso1, LOW);
digitalWrite (verde1, HIGH);
digitalWrite (verde2, LOW);
digitalWrite (giallo2, LOW);
digitalWrite (rosso2, HIGH);
delay (5000);
digitalWrite (giallo1, HIGH);
digitalWrite (verde1, LOW);
delay (3000);
digitalWrite (verde1, LOW);
digitalWrite (giallo1, LOW); 
} 
else { 
digitalWrite(rosso1,LOW); //spengo TUTTO
digitalWrite(giallo1, LOW);
digitalWrite(verde1, LOW);
digitalWrite(rosso2, LOW);
digitalWrite(giallo2, LOW);
digitalWrite(verde2, LOW);
} 
}

Perchè dentro all'IF stato==1 DEVI rimettere stato a 0 altrimenti rimane a vita a 1 !!

if (stato == 1) 
{ ...
 stato=0;
} else ...

Ok, il problema sembra quasi risolto , però inserendo lo stato=0 a fine sequenza si spegne in automatico, preferivo spegnerla alla pressione del pulsante

digitalWrite (verde1, LOW);
digitalWrite (giallo1, LOW); 
stato=0;
} 
else { 
digitalWrite(rosso1,LOW); //spengo TUTTO
digitalWrite(giallo1, LOW);
digitalWrite(verde1, LOW);
digitalWrite(rosso2, LOW);
digitalWrite(giallo2, LOW);
digitalWrite(verde2, LOW);
} 
}
[code]

Secondo me devi implementare un debouncing migliore per il pulsante. Prova ad allungare il delay(15), se ancora non va guarda l'esempio Debounce o usa una delle varie soluzioni hardware che puoi trovare con una ricerca sul forum.

zZocks:
Ok, il problema sembra quasi risolto , però inserendo lo stato=0 a fine sequenza si spegne in automatico, preferivo spegnerla alla pressione del pulsante

Allora togli quello stato=0

Ma... hai presente che, quando premi il pulsante, tu entri nel if e fai una sequenza piena di delay moooooolto lunghe ? Sai che una delay è bloccante ?
Quando c'e' una delay(5000) vuol dire che se premi il pulsante... per 5 secondi arduino è sordo ??

Purtroppo la logica che usi non funziona, un approccio migliore è usare una macchina a stati finiti, non semplicissima ma neppure difficile da fare. (qui un esempio)
Però devi prima imparare a NON usare quei delay bloccanti ma usare la millis(), vedi la differenza tra lo sketch di esempio "Blink" e "Blink Without Delay"

P.S. ma come mai 2 pin per ogni colore ?

sto iniziando ora con arduino, quindi non me ne intendo molto

grazie molte per i consigli ora provo a sistemarlo e vedo se funziona!

ho provato a modificare con il modello a stati finiti ma niente...

#define rosso1 13 
#define giallo1 12
#define verde1 11
#define rosso2 7
#define giallo2 6
#define verde2 5
#define BUTTON 2

// FSM states
#define STATE_OFF  0
#define STATE_ON   1

// variables
int fsm_state;

void setup() {
  fsm_state = STATE_OFF;
}

void loop() {
  // FSM states
  switch(fsm_state) {
    
    case STATE_OFF:
      if(BUTTON ==0) {
        digitalWrite (rosso1, HIGH);
digitalWrite (verde2, HIGH);
digitalWrite (rosso2, LOW);
delay (5000);
digitalWrite (giallo2, HIGH);
digitalWrite (verde2, LOW);
delay (3000);
digitalWrite (rosso1, LOW);
digitalWrite (verde1, HIGH);
digitalWrite (verde2, LOW);
digitalWrite (giallo2, LOW);
digitalWrite (rosso2, HIGH);
delay (5000);
digitalWrite (giallo1, HIGH);
digitalWrite (verde1, LOW);
delay (3000);
digitalWrite (verde1, LOW);
digitalWrite (giallo1, LOW); 
        fsm_state = STATE_ON;
      }
      break;
    
    case STATE_ON:
      if(BUTTON == 1) {
        digitalWrite(rosso1,LOW); //spengo TUTTO
digitalWrite(giallo1, LOW);
digitalWrite(verde1, LOW);
digitalWrite(rosso2, LOW);
digitalWrite(giallo2, LOW);
digitalWrite(verde2, LOW);
delay (10);
      }    
      break;
  }
}[code]

HO UTILIZZATO 2 pin per colore perche volevo simulare un'incrocio quando uno è rosso l'altro è verde etc etc

Se non levi i delay non basta.

Ho un esempio non proprio semplice, di semaforo lampeggiante giallo (stati S_ACCESO e S_SPENTO), quando premi il pulsante diventa verde, giallo e rosso per far passare il pedone che ha premuto e poi ritorna lampeggiante.

const byte pinBtn = 6;
const byte pinR   = 7;
const byte pinG   = 8;
const byte pinV   = 9;

const byte S_SPENTO = 0;     // stati del semaforo
const byte S_ACCESO = 1;
const byte S_VERDE  = 2;
const byte S_GIALLO = 3;
const byte S_ROSSO  = 4;
// enum t_Stati {S_SPENTO,S_ACCESO,S_VERDE,S_GIALLO,S_ROSSO} statoFSM;

byte statoFSM;           // memorizza lo stato corrente
byte bottone = LOW, old_bottone = LOW;   // bottone e suo debounce 
unsigned long previousMillis = 0;
int attesa;                        // tempo attesa a seconda dello stato

void setup()
{ delay(1000);
  Serial.begin(9600);
  pinMode(pinBtn,INPUT);
  pinMode(pinR,OUTPUT);
  pinMode(pinG,OUTPUT);
  pinMode(pinV,OUTPUT);
  SetStatoFSM(S_SPENTO);   // partiamo in lampeggiante
  previousMillis = millis();
}

void loop()
{ // EVENTO gestione bottone, se premuto, cambio di stato
  bottone = digitalRead(pinBtn);
  if (bottone == HIGH && old_bottone == LOW)
  { delay(15); // attesa di 15 millisecondi
    // se lampeggiante passa a verde
    if (statoFSM == S_SPENTO || statoFSM == S_ACCESO)
    { SetStatoFSM(S_VERDE);
      previousMillis = millis();
    }
  }
  old_bottone = bottone;
  // EVENTO gestione timer, se scatta, cambio di stato
  if ( int(millis() - previousMillis) >= attesa)
  { previousMillis = millis();
    switch (statoFSM)      // cambia stato
    { case S_VERDE:  SetStatoFSM(S_GIALLO);
                     break;
      case S_GIALLO: SetStatoFSM(S_ROSSO);  
                     break;
      case S_ROSSO:  SetStatoFSM(S_ACCESO); 
                     break;
      // i prossimi due transazione lampeggiante giallo
      case S_SPENTO: SetStatoFSM(S_ACCESO); 
                     break;
      case S_ACCESO: SetStatoFSM(S_SPENTO); 
                     break;
    }
  }
}

void SetStatoFSM(byte p_Stato) //t_Stati p_Stato
{ statoFSM = p_Stato;
  switch (p_Stato)
  { case S_ROSSO:  attesa = 5000; 
                   break;
    case S_GIALLO: attesa = 3000; 
                   break;
    case S_VERDE:  attesa = 5000; 
                   break;
    case S_SPENTO: // senza break prosegue riga seguente
    case S_ACCESO: attesa =  500; 
                   break;
  }
  if (statoFSM == S_ROSSO)
    digitalWrite(pinR, HIGH);
  else
    digitalWrite(pinR, LOW);
  if (statoFSM == S_GIALLO || statoFSM == S_ACCESO)  // giallo or acceso
    digitalWrite(pinG, HIGH);
  else
    digitalWrite(pinG, LOW);
  if (statoFSM == S_VERDE  || statoFSM == S_GIALLO)  // verde or giallo
    digitalWrite(pinV, HIGH); // in stato giallo il verde è acceso
  else
    digitalWrite(pinV, LOW);
  DEBUGStatoFSM(p_Stato);  // solo per debug su seriale
}

void DEBUGStatoFSM(byte p_Stato) //t_Stati p_Stato
{ Serial.print("Stato: ");
  switch (p_Stato)
  { case S_ROSSO:  Serial.println("ROSSO");               break;
    case S_GIALLO: Serial.println("GIALLO");              break;
    case S_VERDE:  Serial.println("VERDE");               break;
    case S_ACCESO: Serial.println("LAMPEGGIANTE ACCESO"); break;
    case S_SPENTO: Serial.println("LAMPEGGIANTE SPENTO"); break;
  }
}