More Animation and the Rest of the Story
Fig. 2 will need 9 LEDs = 3 Red, 3 Yellow, 3 Green.
Six xxxx Ohm, ¼ Watt resistors
The animation time is 5 seconds per light change.
Fig. 3 will need 12 LEDs = 4 Red, 4 Yellow, 4 Green
Six xxxx Ohm, ¼ Watt resistors
The animation time is 5 seconds per light change.
Fig. 4 also will need 12 LEDs = 4 Red, 4 Yellow, 4 Green
Six xxxx Ohm, ¼ Watt resistors
The animation time is 5 seconds per light change.
Fig. 5 needs:
54 LEDs = 18 Red, 18 Yellow and 18 Green.
A total of 24 LEDs are used for the Red, Yellow, and Green lights on the North-South routes.
A total of 30 LEDs are used for the Red, Yellow, and Green light on the East-West routes.
15 xxxx Ohm, ¼ Watt resistors
The animation time is 10 seconds per light change.
City blocks are not to scale
The Schematic:
The LEDs next to the 12 volts in Fig. 6 are wired as “common anode” (see Fig. 7 for clarification).
The 470-ohm Resistor Value:
Those six 470-ohm resistors in Fig. 6:
Each 470-ohm resistor at the Arduino I/O pins (2,4,6,8,10 and 12) in Fig. 6 are fixed and do not affect how many LEDs the 2N3904 transistor can light. I chose 470 ohms because I wanted to turn the transistor on hard with about 10ma. The maximum current of each Arduino output is 40ma. I cut that to 10ma to be safe and to keep the smoke inside the Arduino.
Assuming the Arduino puts out 5 volts when high (it’s a little less), and ignoring the voltage drop across the base-emitter junction (it’s about 0.7 volts), I used Ohms Law R=E/I to find the resistor value. So, R = 5 volts/ 0.010 amps = 500 ohms. I picked a 470-ohm resistor, hooked it up and measured about 8.5ma (0.0085 amps). Close enough. The actual voltage across the resistor is 4 volts. Now I know the Arduino will not need to deliver over 25ma total for any combination of LEDs being energized.
UK operation will have up to three Arduino outputs energized simultaneously (about 25ma total); US operation will only have two outputs energized simultaneously, (about 17ma total).
How the Transistor Works:
And how one sixth of the circuit works (shown are the 10 East-West RED LEDs in figure 5).
(LEDs 8, 16, and 20 are wired “common anode”.)
The Arduino can deliver up to 40ma per output. The 470-ohm resistor between the Arduino I/O and the base of the transistor limits the base current to about 8.5ma. That transistor base current then allows the transistor to conduct from its collector to its emitter. When the C-E path of the transistor is conducting, the collector voltage drops to about 0.08 volts. That’s almost a short circuit. Current then flows from the 12-volt supply through the LEDs and the resistor, and through the transistor to ground. All the LEDs will light. The 2N3904 is capable of up to 200ma between the collector and the emitter but shouldn’t be designed for over 100ma. Still, that’s a lot of LEDs potentially being powered!
The Other Resistor Values:
What’s the value of “R-?”
It depends on the LED color and how many LEDs are wired in series. It also depends on how bright you want the traffic lights. LEDs are current devices, meaning the more current, the brighter it gets. Increasing resistor “R-?” dims all four LEDs equally.
For example:
GREEN LEDs: Most LEDs have a current rating of 20ma at maximum brightness. To begin, I decided to cut that 20ma in half. Going back to Ohm’s Law and assuming the C-E of the 2N3094 is a dead short, and also assuming the LEDs are shorted, I found R = 12volts/10ma = 1,200 ohms. I selected a 1,000-ohm resistor and connected it in series with the LED and then to 12 volts. Each Green LED lit up with 2.75 volts across it, and it was too bright.
Next I divided 12 volts by the LED volts and came up with 4.36 LEDs. Can’t use over four LEDs. I hooked up the four Green LEDs and the 1,000-ohm resistor in series as shown in Fig. 8. The current through the string was about 1ma and the resistor had 0.65 volts across it. The C-E voltage went to 0.35 volts, putting diodes into a different part of their current operating curve. A small increase or decrease in voltage across any LED results in a tremendous change in brightness, so the current must be controlled, not the voltage. This time the brightness was just about right. I can always increase the resistance to make the LED dimmer if I want to. Right now the value of “R-?” is 1,000-ohm for each string of four Green LEDs.
My RED LEDs need 1.95 volts each with a 1,000-ohm resistor, and the string draws about 3ma.
My YELLOW LEDs need 1.95 volts each with a 1,000-ohm resistor, and the string draws about 3ma.
For your own use, start out with a 1,000-ohm, ¼-watt resistor for one to four LEDs (any color), and increase the resistance until you get the brightness you are comfortable with on your own layout.
How many strings of four can you operate on one 2N3904?
Four LEDs in series (string) is the maximum because of the Green LED voltage requirement and the 12-volt supply. 100ma is a safe 2N3904 transistor C-E current. Dividing the 100ma by each string = number of sets of four LEDs. I can safely run over 50 Green LEDs with one 2N3904 and 13 resistors (12 strings of four LEDs and one string of two LEDs).
Red and Yellow LEDs = 32 total with 8 resistors (8 strings of four LEDs = 96ma)
How Bright should the LEDs be?
The normal safe operating current for a LED is 20ma, but that’s for a flashlight where maximum brightness is wanted. Remember, if you are three feet away from a HO scale traffic light, it’s the same as if you are 261 feet from a traffic light on a real city street. It’s your layout and it’s your judgment call. If you require your HO vehicle drivers to wear Elvis sunglasses at night, so be it.
Number of Single-sided Traffic Light Poles?
If each traffic light pole has three different color LEDs, then the RED and YELLOW LEDs determine the number of poles your layout can have (with the circuit in Fig. 6) because of those LED’s current requirement (3ma) and each 2N3904 safe current limit (100ma). In this case: 33 poles per N-S roads (99ma per 2N3904) and 33 poles for the E-W. That gives a total of 198 LEDs (33 per 2N3904 x six 2N3904s), or about 16 four-way intersections with two poles left over for one-way streets. That’s a big town in a big layout! Other circuitry can be used to increase that number and still use one Arduino.
Here is the Wired Breadboard:
The breadboard is wired for two 4-way traffic lights (24 LEDs total), and the Arduino Pro Mini is in the lower left corner. The resistors are all ¼ watt, and the LEDs are 3mm. I have no way to make a video or I would show the actual traffic light sequence.
What the Arduino Sketch does:
The sketch (program) first tells the Arduino what I/Os are to be used and that they are also to be used as outputs. It then turns all the Red LEDs on for two seconds. This part of the sketch only does this when the Arduino is first powered up, or when its reset button is pushed.
The sketch then loops through 12 simple steps for (US) coordinated traffic lights:
Loop beginning:
1. Turn all lights Red
2. Delay for xxxx seconds
2a. (UK lights only) Turn on North-South Yellow lights
2b. (UK lights only) Delay xxxx seconds
2c. (UK lights only) Turn off North-South Yellow lights
3. Turn off the North-South Red lights and turn on the North-South Green lights
4. Delay for xxxx seconds
5. Turn off the North-South Green lights and turn on the North-South Yellow lights
6. Delay xxxx seconds
7. Turn off the North-South Yellow lights and turn on the North-South Red lights. East-West Red lights are already on.
8. Delay xxxx seconds
8a. (UK lights only) Turn on East-West Yellow lights
8b. (UK lights only) Delay xxxx seconds
8c. (UK lights only) Turn off East-West Yellow lights
9. Turn off the East-West Red lights and turn on the East-West Green lights
10. Delay xxxx seconds
11. Turn off the East-West Green lights and turn on the East-West Yellow lights
12. Delay xxxx seconds
Repeat loop.
Note: for UK users the light sequences in the program have hash marks ( // ) that need to be deleted where indicated in the sketch to activate them. US users don’t need to do anything.
Any “Delay xxxx seconds” can be changed to accommodate local vehicle traffic on your layout, where 1,000 = one second.
There is a fine line between not enough comments in software and too much. I tend to cross that line because I want to know what I was thinking a year from now if I revisit the software. Those comments will automatically be stripped when loaded into the Arduino via the USB cable.
Follow Geoff’s instructions to copy and paste the sketch into the Arduino operating software.
Here is the sketch:
/* Arduino Automobile Traffic Lights sketch
This sketch works for both the U.S. and U.K. traffic light sequence. Although written for a single intersection, it can also be used with a two-lane highway under repair, a T-bone intersection, or any number of coordinated intersections. Coordinated means traffic on all N-S streets move at the same time, and all E-W street traffic move at the same time.
U.S. automotive traffic signal RED-GREEN-YELLOW color protocol is used. Optionally, the United Kingdom traffic signal RED-YELLOW-GREEN-YELLOW protocol can be used by removing slash marks in the two locations of the program where indicated.
The delay times can be changed to meet local conditions: “delay(1000);” means delay operation for one second.
This program requires a total of only 6 Arduino I/O pins for any number of coordinated intersections.
ODD numbered LEDs (LED-1, LED-3, LED-5, etc.) are used to control North-South traffic.
EVEN numbered LEDs (LED-2, LED-4, LED-6, etc.) are used to control East-West traffic.
For an East-West two-lane road with construction blockage, the southern lane of the road is considered the Even lane and the northern lane is considered the Odd lane (see Fig.1)
Size: 1,390 bytes for U.S.; 1,434 bytes for U.K.
Written by Gene Warren and placed into the public domain on 15 December 2014 */
// ODD numbered LEDS for North-South traffic on Odd Street
int redN = 2; // I/O pin 2, Red-1, Red-3
int yellowN = 4; // I/O pin 4, Yellow-1, Yellow-3
int greenN = 6; // I/O pin 6, Green-1, Green-3
// EVEN numbered LEDs for East-West traffic on Even Street
int redE = 8; // I/O pin 8, Red-2, Red-4
int yellowE = 10; // I/O pin 10, Yellow-2, Yellow-4
int greenE = 12; // I/O pin 12, Green-2, Green-4
void setup() {
// set the appropriate pins as outputs
pinMode(redN, OUTPUT);
pinMode(yellowN, OUTPUT);
pinMode(greenN, OUTPUT);
pinMode(redE, OUTPUT);
pinMode(yellowE, OUTPUT);
pinMode(greenE, OUTPUT);
/* Preset BOTH streets to a stop condition to initialize. This portion of the program is only run once at the Arduino startup. */
digitalWrite(redN, HIGH); // Turn ON Red-1, Red-3 for North-South traffic on Odd Street
digitalWrite(yellowN, LOW); // Turn off Yellow-1, Yellow-3 for North-South traffic on Odd Street
digitalWrite(greenN, LOW); // Turn off Green-1, Green-3 for North-South traffic on Odd Street
digitalWrite(redE, HIGH); // Turn ON Red-2, Red-4 for East-West traffic on Even Street
digitalWrite(yellowE, LOW); // Turn off Yellow-2, Yellow-4 for East-West traffic on Even Street
digitalWrite(greenE, LOW); // Turn off Green-2, Green-4 for East-West traffic on Even Street
// Both directions now have a red light to start the Traffic Control Sequence
delay(2000); // Two second delay at startup
}
/* Point A. -----------------------------------------------------
Start the Traffic Control Sequence:
A HIGH at the I/O pin will turn the appropriate LED ON; a LOW will turn it OFF. To begin, start with traffic flowing North-South. All traffic has been properly halted.
Program looping will jump in here. */
void loop() {
// North-South flowing traffic on Odd Street
// START North-South flowing traffic (Green-1, Green-3)
/* For the United Kingdom and some other countries, a yellow light will also precede the green light. Remove the slash marks for the following two lines for the U.K; keep them for the U.S.*/
// digitalWrite(yellowN, HIGH); /* Turn ON YELLOW lights for traffic flowing N-S (Yellow-1, Yellow-3) */
// delay(5000); // Keep it on for 5 seconds
digitalWrite(yellowN, LOW); // Turn off U.K. yellow lights if used; no effect for U.S. yellow lights
digitalWrite(redN, LOW); // Turn OFF RED lights for traffic flowing N-S
digitalWrite(greenN, HIGH); // Turn ON Green lights for traffic flowing N-S
// Hold green light for 10 seconds
delay(10000);
// Time to caution N-S flowing traffic with Yellow-1, Yellow-3 LEDs
digitalWrite(greenN, LOW); // Turn off N-S Green lights
digitalWrite(yellowN, HIGH); // Turn ON N-S Yellow lights
delay(5000); // North-South flowing traffic has 5 seconds to screech to a halt
// Stop North-South flowing traffic with Red-1, Red-3 LEDs
digitalWrite(yellowN, LOW); // Turn Off N-S YELLOW lights
digitalWrite(redN, HIGH); // Turn ON N-S RED lights
// Stop both directions to clear out the North-South traveling rubberneckers and slowpokes
// North-South flowing Red light is now on
// East-West flowing Red lights (Red-2, Red-4) controlling Even Street are already on
delay(5000); // Allow 5 additional seconds to clear the intersection
// East-West flowing traffic on Even Street
/* The following two lines are for the United Kingdom traffic lights. Remove the preceding slash marks to activate the commands. */
// digitalWrite(yellowE, HIGH); // turn ON Yellow-2, Yellow-4 (Red-2, Red-4 are already on)
// delay(5000); // keep it on for 5 seconds
// Allow East-West traffic on Even Street to proceed (Green-2, Green-4)
digitalWrite(yellowE, LOW); // Turn off Yellow Lights for U.K., if used
digitalWrite(redE, LOW); // Turn off Red Lights
digitalWrite(greenE, HIGH); // Turn ON Green lights
delay(10000); //Allow 10 seconds for traffic to flow East-West
// Caution E-W traffic on Even Street (Yellow-2, Yellow-4)
digitalWrite(greenE, LOW); // E-W Green lights goes off
digitalWrite(yellowE, HIGH); // E-W Yellow lights comes ON
delay(5000); // Even Street traffic has 5 seconds to screech to a halt
// Stop E-W traffic on Even Street (Red-2, Red-4)
digitalWrite(yellowE, LOW); // Turn Off E-W Yellow lights
digitalWrite(redE, HIGH); // Turn ON E-W Red lights
// Stop BOTH directions to clear out the rubberneckers and slowpokes in the intersection
// N-S red lights are already on
delay(5000); // Allow 5 seconds to clear the intersection
/* At this point all RED LEDs (Odd Red-1, Red-3, Even Red-2, Red-4) have been on for 5 seconds, and the program will loop under the same conditions as when the loop first started.
Loop the Traffic Control Sequence back to Point A until either the Arduino loses power or its reset button is pushed. */
} // -------------------------------------------------------------
Comments:
Draw out your streets and put traffic pole on each corner as I have done in Figs. 1-5. Number the N-S lights as odd LEDs and the E-W LEDs as even to make your wiring easier. Any hanging four-way traffic light is considered four poles, one on each intersection corner. Then determine which Arduino output and 2N3904 to use.
I would keep all the resistors on any built board and not scattered all over the layout. Troubleshooting will be so much easier.
I may have been a little heavy with the math but felt it was necessary, especially when describing the electronics. If you understand how I got from A to B, you can get there too.
This is a one-trick-pony, meaning the Arduino can’t be used for much of anything else while the traffic light are operating, unless you want to turn something on when a light changes. A “walk/don’t walk” pedestrian light can easily be incorporated into the scheme of things. Yes, more Arduino inputs/outputs are available, but your application still shouldn’t interrupt vehicle traffic flow.
Some may think that the computational power of the Arduino Pro Mini is being wasted. Perhaps, but I think of the Arduino Pro Mini as a $2.01 digital chip that is simply doing what I want.
Have Fun!
Gene Warren