Arduino Traffic Light for Beginners
by joshdont in Circuits > Arduino
14554 Views, 28 Favorites, 0 Comments
Arduino Traffic Light for Beginners
This instructable will walk you through the steps of creating a one way traffic light. It is designed to work in tandem with our Line Following Car for Beginners. By combining the two, you will have a Line Following Robot that obeys a Traffic Signal - if you want it to : ) Depending on how you source your parts, we estimate this project (without the car) costs approximately $30 to $50. We recommend you have a few hours of dedicated time for completion.
This project was originally designed for a summer camp at a Hackerspace in Ann Arbor, MI. If you aren't already familiar with what a Hackerspace/Makerspace is, we highly recommend you check one out! They can be a wonderful resource for both tools and information. Things like access to a LASER cutter can make this project look significantly better with minimal effort. Find one near you!
Suggested Tools:
- Soldering Iron
- Wire Snips
- Pliers (Needle Nose Preferred)
- Wire Strippers (22 AWG)
- Utility Knife
- Phillips Head Screwdriver (No. 1)
- Pencil
- Arduino UNO
- Breadboard
- 9V Battery Holder with 2.1mm Barrel Connector
- LASER Cutter
Suggested Materials:
- Solder
- 9V Battery
- Electrical Tape
- ~6" of HeatShrink (3/32")
- 8 x Sticky Rubber Feet
- Traffic Light Enclosure
- 3 x 220 Ohm Resistors (Red Red Brown)
- 1 x 100 Ohm Resistor (Brown Black Brown)
- 1 x 10k Ohm Resistor (Brown Black Orange)
- 1 x Red LED
- 1 x Yellow LED
- 1 x Green LED
- 3 x Blue LEDs (Any color will do, but all three should match)
- 1 x NPN Transistor (PN2222)
- 1 x Photocell
- 22 AWG Hook Up Wire, preferably in the colors Red, Black, Green, and Yellow.
Highly Recommended
- Clean workspace
- Good lighting
- Someone awesome to work with
Short on resources?
- Find out if there's a local hackerspace near by!
- Need it today? Radioshack. Can you wait a few days? Adafruit, and Sparkfun are excellent resources.
Who made this?
- This instructable was brought to you by Khevna Shah and Josh Williams, and much help from the World's Friendliest Hackerspace: All Hands Active
Downloads
Prepare Your Red, Green, and Yellow LEDs for Soldering
We use photos for most of the instructions of the physical setup. For each step:
- First, review the Tools & Materials Needed.
- Second, open the first image.
- Third, move your mouse cursor over the comment box for a short description.
- Click the arrow on the right side of the image to move to the next image.
- When no more arrows show up, close the image and move onto the next step.
Tools Needed:
- Hands
- Wire Strippers
Materials Needed:
- 1 x Red LED
- 1 x Green LED
- 1 x Yellow LED
- 1 x Black Wire (22 AWG Solid Core, ~21 cm in length
Position and Solder Your Lights!
- Hands
- Wire Strippers
- Wire Snips
- Soldering Iron
Materials Needed:
- Unsoldered Traffic Light
- 1 x Red Wire (22 AWG, ~21cm in Length)
- 1 x Green Wire (22 AWG, ~21cm in Length)
- 1 x Yellow Wire (22 AWG, ~21cm in Length)
- 1 x Traffic Light Housing (two parts)
Solder Track Lights
Tools Needed:
- Hands
- Wire Strippers
- Wire Snips or Scissors
- Soldering Iron
- Heat Gun
Materials Needed:
- Solder
- 1 x Black Wire (22 AWG, ~41cm in Length)
- 1 x Red Wire (22 AWG, ~41cm in Length)
- 3 x Blue LEDs
- 2 x Heatshrink (2cm in length, 2.3mm (3/32") diameter)
FYI: The second image in this is step an absolutely amazing gif animation. Please hang tight, it might take a moment to load.
Solder Photocell
* HOW LONG TO SHRINK BRO?
Tools Needed:
- Hands
- Wire Strippers
- Wire Snips or Scissors
- Soldering Iron
- Heat Gun
Materials Needed:
- Solder
- 1 x Black Wire (22 AWG, ~25cm in Length)
- 1 x Red Wire (22 AWG, ~25cm in Length)
- 1 x Photocell
- 2 x Heatshrink tube (4cm in length, 2.3mm (3/32") diameter)
There is no gif animation here. Maybe the next step will!
Assembling Track Lights
- Hands
- Scissors
- No. 1 Phillips Screwdriver
Materials Needed:
- Pre-soldered Track Light
- Electrical Tape
Assembling Photocell Onto Track
- Hands
- Scissors
- No. 1 Phillips Screwdriver
Materials Needed:
- Pre-soldered Photocell Sensor
- Electrical Tape
Attach Your Traffic Light!
- Hands
- Utility Knife
- Pencil
Materials Needed:
- Pre-soldered Traffic Light Setup
- Traffic Light Plates (If you're participating in the AHA Summer Camp, these are already in your kit!)
- - If you aren't in summer camp. You can use these files with a LASER Cutter.
- - Or Print them out on your printer and use it as a guide to cut out of cardboard!
- - Or design your own!
Connect the Wires!
- Hands
- Arduino Uno
- Breadboard
- Wire Strippers
- Wire Snips
- Pliers
Materials Needed:
- Assembled Traffic Light
- Assembled Photocell / Sensor
- Assembled 3 x LED Setup
- Red Wire
- Black Wire
- Green Wire
- Yellow Wire
- Blue Wire
- 4 x 220 Ohm Resistors (Red Red Brown)
- 1 x 10k Ohm Resistor (Brown Black Orange)
- 1 x 100 Ohm Resistor (Brown Black Brown)
- 1 x NPN Transistor
Set Up the Arduino Environment
- The Arduino Software downloaded and installed on your computer.
- Plugged in and tested your Arduino by following the installation guide appropriate for your computer.
- Approximately one hour of time to spare, and a nice clean workspace with plenty of lighting.
Mission Complete? Continue on!
Note:
Go to this page for tutorials: http://arduino.cc/en/Tutorial/HomePage
Go to this page for references: http://arduino.cc/en/Reference/HomePage
Image Source: The Getting Started w/Arduino Guide
Basic Arduino Programming
The Setup function runs once when the Arduino is turned on or reset.
The Loop function runs continuously after the setup function runs once.
Here's a basic Arduino program. This program doesn't do anything interesting yet, but that comes next!
void setup()
{
// code in here runs once
}
void loop()
{
// after the setup function, code in here runs over and over
}
Turn on Your Green LED
First, you need to tell the Arduino that you will
OUTPUT
data on the pin you plugged the Green LED into.You can do this by using the
pinMode
function.
An example of this is:pinMode(3, OUTPUT);
where my pin number is3
.
Second, you need to send a
HIGH
signal to the LED to turn it on! (A "LOW" signal will turn the LED off.)You can do this by using the
digitalWrite
function.
An example of this is:digitalWrite(3, HIGH);
where my pin number is3
.
Now try turning on the Green LED! It should be on PIN 2. Here is some code to help you get started:
void setup()
{
// set the pinMode to OUTPUT
// your code here
}
void loop()
{
// digitalWrite the pin to HIGH
// your code here
}
Variables!
pinMode(2, OUTPUT);
and digitalWrite(2, HIGH);
What if I wanted to move my Green LED to PIN 4? This would mean changing numbers in two different places! Yuck!
Instead, we tell the computer that the word GREEN means 2, and then use the word GREEN everywhere! That way, if I moved my Green LED to PIN 4, I would just tell the computer that GREEN now means 4!
To do this we use: Variables!
Variables allow you to give names to things. There are lots of different types of variables.
Today we're going to learn about a number variable called an int (short for integer). An int can be any whole number from -32,768 to 32,767. More details here: http://arduino.cc/en/Reference/Int
Variables have 3 properties: type, name, and value.
For instance:
int GREEN = 2;
has a type of int
, a name of GREEN
, and a value of 2
.A variable is used in place of a value.
Anywhere you want to use a
2
you can now write GREEN
* Remember: You have to make a variable before you can use it!
Now try turning on the Green LED using the variable "GREEN." It should be on PIN 2. Here is some code to help you get started:
// make your variable
// your code here
void setup()
{
// set the pinMode to OUTPUT using GREEN
// your code here
}
void loop()
{
// digitalWrite the pin to HIGH using GREEN
// your code here
}
* Variables exist in different areas known as scopes. A scope is the area between a starting curly bracket { and its matching ending curly bracket }. In our case, we're going to declare the variables all at the top of the code. These variables are known as global variables. A global variable can be used anywhere in the document.
Make Your Green LED Blink! (Part 1/2)
digitalWrite
to write HIGH
and then LOW
to GREEN
.What happens when you try this:
Does it work? No? Go on to Part 2!
// variables
int GREEN = 3;
void setup()
{
// setup LED modes
pinMode(GREEN, OUTPUT);
}
void loop()
{
// High turns things on
digitalWrite(GREEN, HIGH);
// low turns things off
digitalWrite(GREEN, LOW);
}
Making Your Green LED Blink! (Part 2/2)
To solve this problem, we're going to add a
delay
between the light being on and the light being off!More details here: http://arduino.cc/en/Reference/DelayYou can do this by using the
delay
function.
An example of this is:delay(100);
where my delay is100
milliseconds.
Use the variable
DELAY_GREEN
to create a 1 second, 1000 millisecond, delay between the light being on and off:
// variables
int GREEN = 3;
int DELAY_GREEN = 1000;
void setup()
{
// setup LED modes
pinMode(GREEN, OUTPUT);
}
void loop()
{
// High turns things on
digitalWrite(GREEN, HIGH);
// we need a delay here!
// your code here
// low turns things off
digitalWrite(GREEN, LOW);
// what happens next?
}
Blink Both the Green and the Yellow LEDs
YELLOW
and set it to 7 and another variable called DELAY_YELLOW
and set it to be 500 milliseconds.Set it up so that your Green LED stays on for 1000 milliseconds and your Yellow LED stays on for 500 milliseconds.
Start with this code:
// variables for green light
int GREEN = 2;
int DELAY_GREEN = 1000;
// variables for yellow light
// your code here
void setup()
{
// setup LED modes
pinMode(GREEN, OUTPUT);
}
void loop()
{
// High turns things on
digitalWrite(GREEN, HIGH);
delay(DELAY_GREEN);
// low turns things off
digitalWrite(GREEN, LOW);
delay(DELAY_GREEN);
}
Tips for debugging:
* Did you create all your variables?
* Have you set all your pins to OUTPUT?
* Did you remember to turn off one LED and turn on the other?
* Did you put your delays so that after you turn on the LED, you use the same color's delay variable?
Blink All the LEDs!
Remember to use variables for your pins and delays!
Use Functions!
digitalWrite(GREEN, HIGH);
digitalWrite(YELLOW, LOW);
digitalWrite(RED, LOW);
And then you had to repeat them for the yellow light and then again for the red light.
To avoid doing that, we use a Function. Functions also allow us to make our code easier to read.
Functions allow you to group instructions. Functions have 3 main parts. Input, instructions, and output!
Today we're going to focus on just the grouping of instructions!
Functions are just like variables. Once your create them, you can replace the sets of instructions you put into the function in the rest of your program.
Turning this set of instructions:
void loop()
{
digitalWrite(GREEN, HIGH);
digitalWrite(YELLOW, LOW);
digitalWrite(RED, LOW);
}
Into this:
void loop()
{
green_light();
}
void green_light()
{
digitalWrite(GREEN, HIGH);
digitalWrite(YELLOW, LOW);
digitalWrite(RED, LOW);
}
A function is used in place of instructions.
Anywhere you want to make a green light, you can now write
green_light();
.Try completing the following code:
// variables
int GREEN = 2;
int YELLOW = 7;
int RED = 12;
int DELAY_GREEN = 5000;
int DELAY_YELLOW = 2000;
int DELAY_RED = 5000;
void setup()
{
// setup LED modes
pinMode(GREEN, OUTPUT);
pinMode(YELLOW, OUTPUT);
pinMode(RED, OUTPUT);
}
void loop()
{
green_light();
delay(DELAY_GREEN);
// code to make a yellow light
delay(DELAY_YELLOW);
//code to make a red light
delay(DELAY_RED);
}
void all_LEDs_off()
{
digitalWrite(GREEN, LOW);
digitalWrite(YELLOW, LOW);
digitalWrite(RED, LOW);
}
void green_light()
{
all_LEDs_off();
digitalWrite(GREEN, HIGH);
}
void yellow_light()
{
// your code here
}
void red_light()
{
// your code here
}
//
Add in Code for Your Blue Street Lights!
Call your street light PIN variable
STREET_LIGHTS
.* Remember to use variables for your pins and set them to output mode!
* Remember to turn off your LEDs in the
all_LEDS_off
function!Sensors! Part 1: Reading Input
You can read input values from the analog pins!
Earlier we talked about how functions have 3 main parts. Input, instructions, and output!You can do this by using the
analogRead
function.
An example of this is:analogRead(A0);
where my analog pin number isA0
.
The
analogRead
function returns (outputs) an int (integer) between 0 and 1023.More details here: http://arduino.cc/en/Reference/AnalogRead
Here is an example piece of code that stores the value that is returned by the
analogRead
function in a variable:But now what?
int SENSOR_PIN = A0;
int sensor_value = 0;
void setup()
{
}
void loop()
{
sensor_value = analogRead(SENSOR_PIN);
}
Sensors! Part 2: Displaying Text
Let's try seeing what information we're reading! This takes two steps.
First you need to inform the Arduino that you want to see some information.
More details here: http://arduino.cc/en/Serial/BeginYou can do this by using the
Serial.begin
function.
An example of this is:Serial.begin(9600);
where9600
is the rate at which we want to see the information.
Next you want to print out that information onto your computer!
More details here: http://arduino.cc/en/Serial/PrintYou can do this by using the
Serial.println
function.
An example of this is:Serial.println(sensor_Value);
where the information I want to see issensorValue
.
This is a great tool for debugging!
Let's see how it works.
First upload this code to your Arduino:
Now press the little magnifying glass on the top right of your Arduino Environment (as shown in the picture!).
int SENSOR_PIN = A0;
int sensor_value = 0;
void setup()
{
Serial.begin(9600);
}
void loop()
{
sensor_value = analogRead(SENSOR_PIN);
}
Try covering your Photocell with your hand or pointing a flashlight at it! You should see values between 0 and 1023! Neat huh?
Sensors! Part 3: Using the Input Information (If Statements and Comparisons)
int sensor_mid = 511;
Now we're going to use this value to turn on and off lights when the photocell sees more or less light than the middle value.
There are two really important things that will help!
You can do this by using theLet's take a second to think about what happens when you use anif
statement and comparisons<
and>
.
An example of this is:
if(sensor_value < sensor_mid)
where I comparesensor_value
andsensor_mid
.
if
statement. An if
statement allows you to do two different things depending on whether the comparison is true
or false
.An example of this is:
if(sensor_value < sensor_mid)
{
// do something
} else {
// do something else
}
Try turning on the green light when the sensor value is greater than the middle and turning on the red light when the sensor value is less than the middle!
int SENSOR_PIN = A0;
int sensor_mid = 511;
int GREEN = 2;
int YELLOW = 7;
int RED = 12;
int STREET_LIGHTS = 13;
void setup()
{
pinMode(GREEN, OUTPUT);
pinMode(YELLOW, OUTPUT);
pinMode(RED, OUTPUT);
pinMode(STREET_LIGHTS, OUTPUT);
Serial.begin(9600);
}
void loop()
{
int sensor_value = analogRead(SENSOR_PIN);
Serial.println(sensor_value);
if(sensor_value < sensor_mid)
{
// your code here
}
//your code here
}
void all_LEDs_off()
{
digitalWrite(GREEN, LOW);
digitalWrite(YELLOW, LOW);
digitalWrite(RED, LOW);
}
void green_light()
{
all_LEDs_off();
digitalWrite(GREEN, HIGH);
}
void yellow_light()
{
all_LEDs_off();
digitalWrite(YELLOW, HIGH);
}
void red_light()
{
all_LEDs_off();
digitalWrite(RED, HIGH);
digitalWrite(STREET_LIGHTS, HIGH);
}
Sensors! Part 4: Calibrating (While Loops)
To solve this issue, we do something called calibrating! When we calibrate the photocell, we look for the highest value it sees and lowest value it sees and then set the middle between those two values. We're going to calibrate the value for about 5 seconds.
To do this, we're going to be using a number of different tricks!
First, we're going to learn about time. The Arduino keeps track of how long it has been since the Arduino has been turned on. We can look at what that value is.
What is anYou can do this by using the
millis
function.
An example of this is:unsigned long current_time = millis();
where I store the value of time in the variablecurrent_time
.
unsigned long
? A long
is like an integer but bigger! A long goes from -2,147,483,648 to 2,147,483,647. The word unsigned
means that instead of going from -2,147,483,648 to 2,147,483,647, it goes from 0 to 4,294,967,295. Since time is never negative, we use an unsigned
number for it!More details here: http://arduino.cc/en/Reference/Long
and here: http://arduino.cc/en/Reference/UnsignedLong
Next we're going to use something called a
while
loop! A while
loop is like an if
statement, while the condition provided is true
, it executes. The difference between an if
statement and a while
statement is that the while
statement keeps on executing until the condition is false
-- just like how the loop
function runs until you turn off your Arduino. Make sure your end_time is also is an unsigned long.An example of this is:
while(current_time < end_time)
{
// do something
// now update the current time
current_time = millis();
}
The code you put in the "do something" area will keep going until the time goes past end_time
After that, what we need to do is look for the highest and the lowest values that the Photocell sees and store those values.
You can do this by first starting the high value at
0
and the low value at1023
.
sensor_low = 1023;
sensor_high = 0;
Next, every time we go through the while loop, we'll look to see if the sensor value is less than the lowest value it's seen, if so, since that new value is lower, we'll set the low value to that instead.
An example of this is:
if(sensor_value < sensor_low)
{
sensor_low = sensor_value
}
Similarly with the high value, if the sensor sees a higher value, we'll set it to the higher value!
An example of this is:
if(sensor_value > sensor_high)
{
sensor_high = sensor_value
}
After the 5 seconds of calibrating, we'll go ahead and set sensor_mid to the average of the low and high values.
Now try it yourself:
int SENSOR_PIN=A0;
int sensor_mid = 511;
int GREEN = 2;
int YELLOW = 7;
int RED = 12;
int STREET_LIGHTS = 13;
void setup()
{
pinMode(GREEN, OUTPUT);
pinMode(YELLOW, OUTPUT);
pinMode(RED, OUTPUT);
pinMode(STREET_LIGHTS, OUTPUT);
calibrate();
}
void loop()
{
int sensor_value = analogRead(SENSOR_PIN);
Serial.println(sensor_value);
if(sensor_value < sensor_mid)
{
green_light();
}
else
{
red_light();
}
}
void calibrate()
{
int sensor_high = 0;
int sensor_low = 1023;
int current_time = millis();
int end_time = current_time + 5000;
// we have to calibrate this in the first five seconds
while (current_time < end_time)
{
// now update the current time
current_time = millis();
// update sensor value here!
// your code here
// record the minimum sensor value
if (sensor_value < sensor_low)
{
//your code here
}
// record the maximum sensor value
if //your code here
{
sensor_high = sensor_value;
}
}
//set mid to be the MIDDLE! :)
sensor_mid = (sensor_high + sensor_low)/2;
}
void all_LEDs_off()
{
digitalWrite(GREEN, LOW);
digitalWrite(YELLOW, LOW);
digitalWrite(RED, LOW);
digitalWrite(STREET_LIGHTS, LOW);
}
void green_light()
{
all_LEDs_off();
digitalWrite(GREEN, HIGH);
}
void yellow_light()
{
all_LEDs_off();
digitalWrite(YELLOW, HIGH);
}
void red_light()
{
all_LEDs_off();
digitalWrite(RED, HIGH);
digitalWrite(STREET_LIGHTS, HIGH);
}
Sensors! Part 5: Sensors + Lights
Let's first get the lights going from green to yellow to red!
Add your DELAY variables back to the top!
// variables for green light
int DELAY_GREEN = 1000;
int DELAY_YELLOW = 500;
int DELAY_RED = 1000;
Change your loop function from the previous step to:
void loop()
{
green_light();
delay(DELAY_GREEN);
yellow_light();
delay(DELAY_YELLOW);
red_light();
delay(DELAY_RED);
}
Sensors! Part 6: Extending the Green Light
First, we need to look for the car. This happens when the photocell sees less than
sensor_mid
.Then, if the Photocell sees the car, we should extend the green light.
To do this we're going to need a new variable type:
boolean
. A boolean
can be either true
or false
just like an int
has a range of -32,768 to 32,767. More details here: http://arduino.cc/en/Reference/BooleanVariablesAn example of this is:
boolean i_love_kittens = true;
where the variablei_love_kittens
is set totrue
.
Remember how we talked about Functions having three parts? Input, Instructions, and Output? Let's talk about outputs!
The setup and the loop function have outputs too. They're void. Void is computer language for nothing. Our function will output a boolean.
In the function, we're going to set the return_value to true when the car sensor sees the car.First you need to tell the Arduino that you want your function to output a boolean.
Then you need to actually return (ouput) a boolean value.
An example of this is:
boolean my_awesome_function()
{
boolean i_love_kittens = true;
return i_love_kittens;
}
Try adding this function to your code:
Then in the loop function, look for a car and then extend the green light if the Photocell sees the car.boolean look_for_car()
{
int current_time = millis();
int end_time = current_time + 2000; // we'll look for about two seconds
boolean saw_car = false;
while(current_time < end_time)
{
sensor_value = analogRead(SENSOR_PIN);
if(sensor_value < sensor_mid)
{
// set the value of saw_car to true
// your code here
}
// update the current time
// your code here
}
return saw_car;
}
If it sees the car, remember to add a second delay, if not, don't delay!
Quick example:
boolean saw_car = look_for_car();