Arduino Traffic Lights – Take Two

Standard

Ok, so after starting my first project (yesterday: Arduino timer-based traffic lights), I decided to expand upon the concept today. In keeping with the traffic light theme (it seemed like a good idea!), I added a few extra LEDs and a digital switch so that someone can ‘cross the road’ by pressing the button to change the lights to red.

Scenario: traffic and crossing lights

Instead of having the lights cycle from red – amber – green infinitely as in the previous project, this time I wanted the lights to go through a fake initialise sequence (i.e. turn on the Arduino board, have the red LED blink 5 times, then have all three traffic lights switch on, as an example) then to step to amber, then green. To make things a little more interesting, I also added two new LEDs: a ‘Green Man’ and a ‘Red Man’ light – to help our little pedestrians figure out when it’s safe to cross the road. 🙂

The traffic lights should remain on green until a ‘pedestrian’ presses the crossing button, at which point we should go to amber, then red. We should wait a little bit for the pedestrian to cross, blink the green man light a few times to indicate that the pedestrian needs to get out of the road, followed by blinking the Amber light a few times to alert the traffic to get ready, then go back to a green traffic light and a red man light.

The lights and crossing should obey the following rules:

  • When a red traffic light is displayed, the green man light should be on
  • When a green traffic light is displayed, the red man light should be on

Common sense really! 🙂

So our sequence of events needs to resemble the following:

  • Initialise the lights (blink red LED 5 times, then turn on all three traffic lights)
  • Show amber traffic light
  • Show green traffic light and wait on green
    • When the crossing button is pressed:
      • Show the amber traffic light
      • Show the red traffic light
      • Show the green man
      • Wait a preset amount of time to let the pedestrians cross
      • Blink the green man light a few times
      • Blink the amber traffic light a few times
      • Extinguish the green man light and turn on the red man light
    • Resume green traffic light
    • Repeat!

After about a half hour tinkering, I’d stripped the breadboard and added a digital switch and two new LEDs (for the crossing indicators). The Arduino sketch was modified to include controls for the crossing LEDs, and the continuous alternating traffic light sequence was replaced with a solid green LED (which remains green until the switch is pressed).

A quick observation: the digital switch and pull-down resistors

My switch is connected to a digital input. Initially, this resulted in an intermittent switch: picking up HIGH or LOW sometimes worked, and sometimes didn’t. I figured out after a little bit of Googling that I actually needed to connect the switch in a mini ‘pull-down resistor circuit’ which now works brilliantly. I will admit, I have yet to fully understand the principles behind why this works, but that’s something I will continue to look into (besides wanting to just have fun with the Arduino, one of my goals is to learn more about the basic electrical principles regarding physical computing).

The board setup:

Pedestrian Crossing with Traffic Lights

And the wiring diagram:

Now then! The lovely Fritzing program I used to create the above diagram (which I absolutely love), is so new, that it doesn’t (yet) have a switch symbol for the type of switch I have used. Hence, with my very limited knowledge of electrical schematics, I’ve used the standard switch symbol and tried to represent how I’ve actually wired the switch up. Here’s a close-up photograph of what I’ve actually done, in the hopes that someone can correct me:

Switch Detail

I found this technique here.

Video:

The Sketch

This is a bit messy at the moment, but I’ll clean it up tomorrow (I’ve used generic on/off methods to set light states instead of just using a ‘setRed’ or ‘setGreen’ method, which encapsulates the code to extinguish lights that aren’t used by that mode, for instance) and also remove some of the ‘debugging’ serial code I wrote:

// Configure the light pins
int redLed = 2;
int yelLed = 3;
int grnLed = 4;
int redManLed = 8;
int grnManLed = 7;

// Program variables
int lightState = 0;
int crossingRequestSwitchPin = 13; // The pin our crossing button is connected to
int switchStatePin = 6;

// Traffic Light Variables
int timerDelayTime = 3000; // The ms between each light change when running in timer mode
int crossingTime = 5000;

// Setup
void setup() {
pinMode(redLed, OUTPUT);
pinMode(yelLed, OUTPUT);
pinMode(grnLed, OUTPUT);
pinMode(switchStatePin, OUTPUT);
pinMode(grnManLed, OUTPUT);
pinMode(redManLed, OUTPUT);
pinMode(crossingRequestSwitchPin, INPUT);
Serial.begin(9600); // Initialise the serial port for debugging
changeLightState(-1); // Set the light state to “initialise”.
}

void loop() {
if (lightState == -1) {
doBeginSequence();
changeLightState(0); // Now our “initialise” phase is done, increment the light state
}
if (lightState == 0) {
lightOn(redLed);
lightOn(yelLed);
lightOn(grnLed);
delay(1500);
startLightsOnTimer();
}
}

void doBeginSequence() { // Handles the lighting sequence for lights that have just been started.
Serial.println(“Begin sequence was requested.”);
blinkLed(redLed, 5, 500);
}

void startLightsOnTimer() {

Serial.println(“Starting timed-sequence.”);
allLightsOff(); // Turn all lights off

while ( lightState == 0 ) {

lightOn(grnLed);
lightOn(redManLed);

/*lightOn(redLed);
delay(timerDelayTime);
lightOn(yelLed);
delay(timerDelayTime);
lightOff(redLed);
lightOff(yelLed);
lightOn(grnLed);
*/

// When the light is green, allow anyone to signal for a crossing request
int request = checkForCrossingRequest();
if (request > 0) {
Serial.println(“Beginning crossing sequence…\n”);
beginCrossing();
}

}

}

// Switch lights to red for a crossing sequence
void beginCrossing() {

changeLightState(1); // Indicate that we’re beginning a crossing sequence

// Goto Amber…
allLightsOff();
lightOn(yelLed);
delay(timerDelayTime);

// Goto Red, and wait for crossingTime milliseconds before continuing…
lightOff(redManLed);
lightOff(yelLed);
lightOn(redLed);
lightOn(grnManLed);
delay(crossingTime);
blinkLed(grnManLed, 5, 500);

// Blink the Yellow Led…
lightOff(redLed);
blinkLed(yelLed, 5, 500); // Blink the Yellow LED 5 times to signal to drivers to proceed if the way is clear
lightOn(grnLed);
lightOff(grnManLed);
changeLightState(0); // Change back to timer mode lighting

}

// Check for crossing button push
int checkForCrossingRequest() {
int val = digitalRead(crossingRequestSwitchPin);
if (val == HIGH) {
Serial.println(“*** Crossing Request Received ***\n”);
return 1; // Crossing requested
} else {
return 0;
}
}

// Helper functions
void lightOn(int pin) { // Turn an LED on
digitalWrite(pin, HIGH);
Serial.print(“Set pin “);
Serial.print(pin);
Serial.print(” to HIGH.\n”);
}

void allLightsOff() { // Turns all LEDs off
digitalWrite(redLed, LOW);
digitalWrite(yelLed, LOW);
digitalWrite(grnLed, LOW);
Serial.println(“All lights turned OFF.\n”);
}

void lightOff(int pin) { // Turn an LED off
digitalWrite(pin, LOW);
Serial.print(“Set pin “);
Serial.print(pin);
Serial.print(” to LOW.\n”);
}

void blinkLed(int pin, int timesToBlink, int blinkIntervalMs) { // Blinks the LED pin the set number of times
Serial.print(“Beginning blink sequence… Pin “);
Serial.print(pin);
Serial.print(“, “);
Serial.print(timesToBlink);
Serial.print(” times with a “);
Serial.print(blinkIntervalMs);
Serial.println(“ms interval between each blink.\n”);

for (int i=0; i <= timesToBlink; i++) { digitalWrite(pin, HIGH); delay(blinkIntervalMs); digitalWrite(pin, LOW); delay(blinkIntervalMs); } } void changeLightState(int newLightState) { // Changes the current lightState Serial.print("Light state changed from "); Serial.print(lightState); Serial.print(" to "); Serial.print(newLightState); Serial.println(".\n"); lightState = newLightState; } [/sourcecode] So! There you have it... My second Arduino project... or, rather an extension of the first! Thanks for reading! /Rich

Advertisements

3 thoughts on “Arduino Traffic Lights – Take Two

Comments are closed.