1

I was trying to develop a traffic light signal controller . when the button is pressed, the pedestrian green light will turn on faster than before . I used delay() in Interrupt function, But it is not working as expected . I am totally new in Arduino coding. My whole code is below:

int carred = 11;
int caryellow = 10;
int cargreen = 9;

int padred = 13; int padgreen = 12;

int padpushbutton = 3; int buspushbutton = 2;

void setup(){ pinMode(carred , OUTPUT); pinMode(cargreen , OUTPUT); pinMode(caryellow , OUTPUT);

pinMode(padgreen , OUTPUT); pinMode(padred , OUTPUT);

pinMode(padpushbutton, INPUT_PULLUP); pinMode(buspushbutton,INPUT); attachInterrupt(digitalPinToInterrupt(padpushbutton), padcontrol,CHANGE); attachInterrupt(digitalPinToInterrupt(buspushbutton), buscontrol,CHANGE); } void loop() { carchangeLights(); } void carchangeLights(){

//turn carred,padgreen off padred high and cargreen on for 10 seconds digitalWrite(carred, LOW); digitalWrite(caryellow,LOW); digitalWrite(padred, HIGH); digitalWrite(cargreen, HIGH); delay(10000);

//cargreen off, turn on caryellow for 4 seconds

digitalWrite(cargreen, LOW); digitalWrite(caryellow, HIGH); delay(4000);

// turn caryellow and padred off,turn on padgreen, turn on carred for 7 seconds digitalWrite(caryellow, LOW); digitalWrite(padred,LOW); digitalWrite(padgreen,HIGH); digitalWrite(carred, HIGH); delay(7000); //turn padgreen off and padred high , caryellow high for 3 second digitalWrite(padgreen, LOW); digitalWrite(padred, HIGH); digitalWrite(caryellow, HIGH); delay(3000);

}

void padcontrol(){

int red = digitalRead(carred); int yellow = digitalRead(caryellow); int green = digitalRead(cargreen);

if (red == HIGH && yellow == LOW ) { digitalWrite(carred, HIGH); delay(2000); digitalWrite(padred, LOW); digitalWrite(padgreen, HIGH); delay(15000); }

else if(yellow == HIGH && red == LOW){
digitalWrite(caryellow, HIGH); delay(2000); digitalWrite(caryellow,LOW); digitalWrite(carred,HIGH); digitalWrite(padred,LOW); digitalWrite(padgreen,HIGH); delay(15000); } else if(yellow == HIGH && red == HIGH) {
digitalWrite(caryellow, HIGH); delay(1000); digitalWrite(caryellow,LOW); digitalWrite(padred,LOW); digitalWrite(padgreen,HIGH); delay(15000); } else{ digitalWrite(cargreen,LOW); digitalWrite(caryellow,HIGH); delay(3000);

digitalWrite(caryellow,LOW);
digitalWrite(carred,HIGH);
digitalWrite(padred,LOW);
digitalWrite(padgreen,HIGH);
delay(15000);

}

}

void buscontrol(){

int red = digitalRead(carred); int yellow = digitalRead(caryellow); int green = digitalRead(cargreen);

if (red == HIGH && yellow == LOW ) { digitalWrite(carred, HIGH); delay(3000); digitalWrite(carred,LOW); digitalWrite(padgreen, LOW); digitalWrite(padred, HIGH); digitalWrite(caryellow, HIGH); delay(2000); digitalWrite(caryellow,LOW); digitalWrite(cargreen, HIGH); delay(10000);

 }


else if(yellow == HIGH && red == LOW) { digitalWrite(padgreen,LOW); digitalWrite(padred,HIGH); digitalWrite(caryellow, HIGH); delay(2000); digitalWrite(caryellow,LOW); digitalWrite(cargreen,HIGH); delay(10000); } else if(yellow == HIGH && red == HIGH) {
digitalWrite(caryellow, HIGH); delay(1000); digitalWrite(carred,LOW); digitalWrite(caryellow,LOW);

digitalWrite(padgreen,LOW);
   digitalWrite(padred,LOW);
 digitalWrite(cargreen, HIGH);
  delay(10000);
}

else{ digitalWrite(padred,HIGH); digitalWrite(cargreen,LOW); delay(10000);

} }

Gerben
  • 11,332
  • 3
  • 22
  • 34
Saikot Das
  • 11
  • 1

1 Answers1

1

what to write instead of dely() in interrupt function?

Nothing. An interrupt service routine (ISR) should not do any things, that take long. That will block any other things from happening, for example Serial communication (which is done by interrupts in the background).

delay() does not work in an ISR, because it relies on the millis() counter to increment. But that is done in another ISR. While one ISR is running, no other can run at the same time. Thus delay() waits forever, that the millis() counter increments.

What to do instead?

Instead you should only use the ISR to set a simple flag variable, for example of type boolean (because it should be a single byte type). Then in your main code (meaning inside loop()) you check for this flag. When it is set by the ISR, you execute the corresponding code and reset the flag. Be sure to declare the flag variable as volatile, so that the compiler knows, that is can change at any time.


That said, you should really ditch all the delay() calls. Instead use a non-blocking coding style involving millis() like in the BlinkWithoutDelay example, that comes with the Arduino IDE. There are tons of tutorials and explanations about that on the web and this site. Just search for it. Using a non-blocking coding style is needed, if you want the code to be responsive while doing long timed things.

Also you should look into Finite State Machines (FSM). Thats a very powerful principle, that will come in useful. It fits exactly on a traffic light project. I have once wrote a longer explanation about FSMs in my answer to this question, though you can also google something like "Arduino fsm". You basically divide the behavior of the project into individual states. The current state is hold by a variable. By changing that variable you transition between states. For example padcontrol() could change the state variable to the state for the pedestrian light. I strongly suggest, that you learn that principle to structure your code. I can attest, that it is really helpful.

chrisl
  • 16,622
  • 2
  • 18
  • 27