Hardware components | ||||||
| × | 24 | ||||
| × | 12 | ||||
| × | 20 | ||||
| × | 4 | ||||
| × | 4 | ||||
| × | 3 | ||||
| × | 1 | ||||
| × | 4 | ||||
| × | 36 | ||||
| × | 36 | ||||
| × | 4 | ||||
| × | 16 | ||||
| × | 16 | ||||
| × | 1 | ||||
Hand tools and fabrication machines | ||||||
| ||||||
| ||||||
| ||||||
| ||||||
|
Here is a four-sided intersection traffic lights project including green arrows lights for left, up and right with an advanced green cycle (left turn priority) in each direction. The lights are all doubled on the left and right side of the roadway, except for the advanced light alone on the opposite roadway. Each red light is doubled in each of the lamp on the left and the right side for more visibility. We frequently find this kind of configuration in Quebec, Canada, but it is not generalized elsewhere.
When the system starts up (simulating a restart after a power failure), the lights flash red in all four directions for a few seconds. Then the first cycle starts with green on the North-South axis.
A call button for pedestrian lights is present on each of the 4 corners of the intersection. If the button is pressed, then a pedestrian cycle will insert before the next complete change of direction.
I have never produced this version in real life because I don't have green arrow shaped LEDs. It is tested and functional in TinkerCAD. Previously, the real version produced by me used the blinking green light for the advanced green cycle instead for the green arrows. This is also a popular configuration found in Quebec, Canada.
There would also be the possibility of adding a LED panel with countdown to the pedestrian light.
The current drawn at the battery is about 200 mAh so about only 2.5 hours for a typical 9V battery. You are better to connect it on a power supply.
The project use I2C communication between three Arduino to get the possibility of more I/O.
Some lights could have been regrouped to use less I/O but in this configuration, you have all the flexibility to change the lights cycles as you want.
#include <Wire.h>
//Slave 1 Assignation
int EastRed = 0;
int EastYellow = 1;
int EastGreenUp = 2;
int EastGreenRight = 3;
int EastLeftRed = 4;
int EastLeftYellow = 5;
int EastLeftGreen = 6;
int NorthRed = 7;
int NorthYellow = 8;
int NorthGreenUp = 9;
int NorthGreenRight = 10;
int NorthLeftRed = 11;
int NorthLeftYellow = 12;
int NorthLeftGreen = 13;
int WestOrange = 14;
int WestWhite = 15;
int NorthOrange = 16;
int NorthWhite = 17;
//Slave 2 Assignation
int WestRed = 0;
int WestYellow = 1;
int WestGreenUp = 2;
int WestGreenRight = 3;
int WestLeftRed = 4;
int WestLeftYellow = 5;
int WestLeftGreen = 6;
int SouthRed = 7;
int SouthYellow = 8;
int SouthGreenUp = 9;
int SouthGreenRight = 10;
int SouthLeftRed = 11;
int SouthLeftYellow = 12;
int SouthLeftGreen = 13;
int EastOrange = 14;
int EastWhite = 15;
int SouthOrange = 16;
int SouthWhite = 17;
//Time Assignations
int PedestrianCrossingTime = 6000;
int NorthSouthGreenTime = 15000;
int EastWestGreenTime = 15000;
int AdvanceGreenTime = 10000;
int YellowTime = 3000;
int InitialFlashingTime = 5000;
int PedestrianFlashingTime = 4000;
int BufferTime = 1000;
int LongFlashTime = 500;
int ShorthFlashTime = 250;
//Other Assignations
int QtyInitialFlash = InitialFlashingTime / LongFlashTime;
int QtyPedestrianFlash = PedestrianFlashingTime / ShorthFlashTime;
unsigned long ActionTime;
int PedestrianButton = A0;
int ButtonState;
int PedestrianCall = 0;
int i;
byte Slave1Values[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
byte Slave2Values[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
void setup() {
Wire.begin();
delay(50);
//Initial orange permanent lights (pedestrian) on four sides and red flashing lights on four sides
Slave1Values[WestOrange] = 1;
Slave1Values[NorthOrange] = 1;
Slave2Values[EastOrange] = 1;
Slave2Values[SouthOrange] = 1;
for (i = 0; i < QtyInitialFlash / 2; i++) {
Slave1Values[EastRed] = 1;
Slave1Values[EastLeftRed] = 1;
Slave1Values[NorthRed] = 1;
Slave1Values[NorthLeftRed] = 1;
Slave2Values[WestRed] = 1;
Slave2Values[WestLeftRed] = 1;
Slave2Values[SouthRed] = 1;
Slave2Values[SouthLeftRed] = 1;
SlavesActions();
delay(LongFlashTime);
Slave1Values[EastRed] = 0;
Slave1Values[EastLeftRed] = 0;
Slave1Values[NorthRed] = 0;
Slave1Values[NorthLeftRed] = 0;
Slave2Values[WestRed] = 0;
Slave2Values[WestLeftRed] = 0;
Slave2Values[SouthRed] = 0;
Slave2Values[SouthLeftRed] = 0;
SlavesActions();
delay(LongFlashTime);
}
//Initial red on East-West, green on North-South
Slave1Values[EastRed] = 1;
Slave2Values[WestRed] = 1;
Slave1Values[EastLeftRed] = 1;
Slave2Values[WestLeftRed] = 1;
Slave1Values[NorthLeftRed] = 1;
Slave2Values[SouthLeftRed] = 1;
Slave1Values[NorthGreenUp] = 1;
Slave1Values[NorthGreenRight] = 1;
Slave2Values[SouthGreenUp] = 1;
Slave2Values[SouthGreenRight] = 1;
SlavesActions();
}
void SlavesActions() {
Wire.beginTransmission(1);
Wire.write((byte*)Slave1Values, 18);
Wire.endTransmission();
Wire.beginTransmission(2);
Wire.write((byte*)Slave2Values, 18);
Wire.endTransmission();
}
void loop() {
//End of Cycle,Green lights North-South
ActionTime = millis();
do {
PedestrianVerification();
} while (millis() - ActionTime < NorthSouthGreenTime);
//Yellow lights cycle for North
Slave1Values[NorthGreenUp] = 0;
Slave1Values[NorthGreenRight] = 0;
Slave1Values[NorthYellow] = 1;
SlavesActions();
ActionTime = millis();
do {
PedestrianVerification();
} while (millis() - ActionTime < YellowTime);
//Buffer cycle before advance green light South
Slave1Values[NorthYellow] = 0;
Slave1Values[NorthRed] = 1;
SlavesActions();
ActionTime = millis();
do {
PedestrianVerification();
} while (millis() - ActionTime < BufferTime);
//Advance Green light cycle for South
Slave2Values[SouthLeftRed] = 0;
Slave2Values[SouthLeftGreen] = 1;
SlavesActions();
ActionTime = millis();
do {
PedestrianVerification();
} while (millis() - ActionTime < AdvanceGreenTime);
//Yellow light cycle for South
Slave2Values[SouthLeftGreen] = 0;
Slave2Values[SouthGreenUp] = 0;
Slave2Values[SouthGreenRight] = 0;
Slave2Values[SouthLeftYellow] = 1;
Slave2Values[SouthYellow] = 1;
SlavesActions();
ActionTime = millis();
do {
PedestrianVerification();
} while (millis() - ActionTime < YellowTime);
//Buffer Cycle before Green lights East-West
Slave2Values[SouthLeftYellow] = 0;
Slave2Values[SouthYellow] = 0;
Slave2Values[SouthLeftRed] = 1;
Slave2Values[SouthRed] = 1;
SlavesActions();
ActionTime = millis();
do {
PedestrianVerification();
} while (millis() - ActionTime < BufferTime);
//Pedestrian Cycle Verification
if (PedestrianCall == 1) {
PedestrianCycle();
}
//Advance green light cycle for East
Slave1Values[EastLeftRed] = 0;
Slave1Values[EastRed] = 0;
Slave1Values[EastLeftGreen] = 1;
Slave1Values[EastGreenUp] = 1;
Slave1Values[EastGreenRight] = 1;
SlavesActions();
ActionTime = millis();
do {
PedestrianVerification();
} while (millis() - ActionTime < AdvanceGreenTime);
//Yellow light cycle for Left East
Slave1Values[EastLeftGreen] = 0;
Slave1Values[EastLeftYellow] = 1;
SlavesActions();
ActionTime = millis();
do {
PedestrianVerification();
} while (millis() - ActionTime < YellowTime);
//Buffer cycle before green lights East-West
Slave1Values[EastLeftYellow] = 0;
Slave1Values[EastLeftRed] = 1;
SlavesActions();
ActionTime = millis();
do {
PedestrianVerification();
} while (millis() - ActionTime < BufferTime);
//Green lights cycle for East-West
Slave2Values[WestRed] = 0;
Slave2Values[WestGreenUp] = 1;
Slave2Values[WestGreenRight] = 1;
SlavesActions();
ActionTime = millis();
do {
PedestrianVerification();
} while (millis() - ActionTime < EastWestGreenTime);
//Yellow light cycle for East
Slave1Values[EastGreenUp] = 0;
Slave1Values[EastGreenRight] = 0;
Slave1Values[EastYellow] = 1;
SlavesActions();
ActionTime = millis();
do {
PedestrianVerification();
} while (millis() - ActionTime < YellowTime);
//Buffer cycle before advance green light West
Slave1Values[EastYellow] = 0;
Slave1Values[EastRed] = 1;
SlavesActions();
ActionTime = millis();
do {
PedestrianVerification();
} while (millis() - ActionTime < BufferTime);
//Advance Green light cycle for West
Slave2Values[WestLeftRed] = 0;
Slave2Values[WestLeftGreen] = 1;
SlavesActions();
ActionTime = millis();
do {
PedestrianVerification();
} while (millis() - ActionTime < AdvanceGreenTime);
//Yellow light cycle for West
Slave2Values[WestLeftGreen] = 0;
Slave2Values[WestGreenUp] = 0;
Slave2Values[WestGreenRight] = 0;
Slave2Values[WestLeftYellow] = 1;
Slave2Values[WestYellow] = 1;
SlavesActions();
ActionTime = millis();
do {
PedestrianVerification();
} while (millis() - ActionTime < YellowTime);
//Buffer Cycle before Green lights North-South
Slave2Values[WestLeftYellow] = 0;
Slave2Values[WestYellow] = 0;
Slave2Values[WestLeftRed] = 1;
Slave2Values[WestRed] = 1;
SlavesActions();
ActionTime = millis();
do {
PedestrianVerification();
} while (millis() - ActionTime < BufferTime);
//Pedestrian Cycle Verification
if (PedestrianCall == 1) {
PedestrianCycle();
}
//Advance Green light cycle for North
Slave1Values[NorthLeftRed] = 0;
Slave1Values[NorthRed] = 0;
Slave1Values[NorthLeftGreen] = 1;
Slave1Values[NorthGreenUp] = 1;
Slave1Values[NorthGreenRight] = 1;
SlavesActions();
ActionTime = millis();
do {
PedestrianVerification();
} while (millis() - ActionTime < AdvanceGreenTime);
//Yellow light cycle for left North
Slave1Values[NorthLeftGreen] = 0;
Slave1Values[NorthLeftYellow] = 1;
SlavesActions();
ActionTime = millis();
do {
PedestrianVerification();
} while (millis() - ActionTime < YellowTime);
//Buffer Cycle before Green lights North-South
Slave1Values[NorthLeftYellow] = 0;
Slave1Values[NorthLeftRed] = 1;
SlavesActions();
ActionTime = millis();
do {
PedestrianVerification();
} while (millis() - ActionTime < BufferTime);
//Start of Cycle,Green lights North-South
Slave2Values[SouthGreenUp] = 1;
Slave2Values[SouthGreenRight] = 1;
Slave2Values[SouthRed] = 0;
SlavesActions();
}
void PedestrianVerification() {
delay(25);
ButtonState = digitalRead(PedestrianButton);
if (ButtonState == HIGH) {
PedestrianCall = 1;
}
}
void PedestrianCycle() {
//White lights cycle
Slave1Values[WestOrange] = 0;
Slave1Values[NorthOrange] = 0;
Slave2Values[EastOrange] = 0;
Slave2Values[SouthOrange] = 0;
Slave1Values[WestWhite] = 1;
Slave1Values[NorthWhite] = 1;
Slave2Values[EastWhite] = 1;
Slave2Values[SouthWhite] = 1;
SlavesActions();
delay(PedestrianCrossingTime);
Slave1Values[WestWhite] = 0;
Slave1Values[NorthWhite] = 0;
Slave2Values[EastWhite] = 0;
Slave2Values[SouthWhite] = 0;
SlavesActions();
for (i = 0; i < QtyPedestrianFlash / 2; i++) {
Slave1Values[WestOrange] = 1;
Slave1Values[NorthOrange] = 1;
Slave2Values[EastOrange] = 1;
Slave2Values[SouthOrange] = 1;
SlavesActions();
delay(ShorthFlashTime);
Slave1Values[WestOrange] = 0;
Slave1Values[NorthOrange] = 0;
Slave2Values[EastOrange] = 0;
Slave2Values[SouthOrange] = 0;
SlavesActions();
delay(ShorthFlashTime);
}
Slave1Values[WestOrange] = 1;
Slave1Values[NorthOrange] = 1;
Slave2Values[EastOrange] = 1;
Slave2Values[SouthOrange] = 1;
SlavesActions();
delay(BufferTime);
PedestrianCall = 0;
}
#include <Wire.h>
int i = 0;
int Event = 0;
byte SlaveValues[18];
void setup() {
for (i = 0; i <= 13; i++) {
pinMode(i, OUTPUT);
}
pinMode(A0, OUTPUT);
pinMode(A1, OUTPUT);
pinMode(A2, OUTPUT);
pinMode(A3, OUTPUT);
Wire.begin(1);
Wire.onReceive(receiveEvent);
}
void receiveEvent(int howMany) {
for (i = 0; i < howMany; i++)
{
SlaveValues[i] = Wire.read();
}
Event = 1;
}
void loop() {
if (Event == 1) {
if (SlaveValues[0] == 0) {
digitalWrite(0, LOW);
}
else {
digitalWrite(0, HIGH);
}
if (SlaveValues[1] == 0) {
digitalWrite(1, LOW);
}
else {
digitalWrite(1, HIGH);
}
if (SlaveValues[2] == 0) {
digitalWrite(2, LOW);
}
else {
digitalWrite(2, HIGH);
}
if (SlaveValues[3] == 0) {
digitalWrite(3, LOW);
}
else {
digitalWrite(3, HIGH);
}
if (SlaveValues[4] == 0) {
digitalWrite(4, LOW);
}
else {
digitalWrite(4, HIGH);
}
if (SlaveValues[5] == 0) {
digitalWrite(5, LOW);
}
else {
digitalWrite(5, HIGH);
}
if (SlaveValues[6] == 0) {
digitalWrite(6, LOW);
}
else {
digitalWrite(6, HIGH);
}
if (SlaveValues[7] == 0) {
digitalWrite(7, LOW);
}
else {
digitalWrite(7, HIGH);
}
if (SlaveValues[8] == 0) {
digitalWrite(8, LOW);
}
else {
digitalWrite(8, HIGH);
}
if (SlaveValues[9] == 0) {
digitalWrite(9, LOW);
}
else {
digitalWrite(9, HIGH);
}
if (SlaveValues[10] == 0) {
digitalWrite(10, LOW);
}
else {
digitalWrite(10, HIGH);
}
if (SlaveValues[11] == 0) {
digitalWrite(11, LOW);
}
else {
digitalWrite(11, HIGH);
}
if (SlaveValues[12] == 0) {
digitalWrite(12, LOW);
}
else {
digitalWrite(12, HIGH);
}
if (SlaveValues[13] == 0) {
digitalWrite(13, LOW);
}
else {
digitalWrite(13, HIGH);
}
if (SlaveValues[14] == 0) {
digitalWrite(A0, LOW);
}
else {
digitalWrite(A0, HIGH);
}
if (SlaveValues[15] == 0) {
digitalWrite(A1, LOW);
}
else {
digitalWrite(A1, HIGH);
}
if (SlaveValues[16] == 0) {
digitalWrite(A2, LOW);
}
else {
digitalWrite(A2, HIGH);
}
if (SlaveValues[17] == 0) {
digitalWrite(A3, LOW);
}
else {
digitalWrite(A3, HIGH);
}
Event = 0;
}
}
#include <Wire.h>
int i = 0;
int Event = 0;
byte SlaveValues[18];
void setup() {
for (i = 0; i <= 13; i++) {
pinMode(i, OUTPUT);
}
pinMode(A0, OUTPUT);
pinMode(A1, OUTPUT);
pinMode(A2, OUTPUT);
pinMode(A3, OUTPUT);
Wire.begin(2);
Wire.onReceive(receiveEvent);
}
void receiveEvent(int howMany) {
for (i = 0; i < howMany; i++)
{
SlaveValues[i] = Wire.read();
}
Event = 1;
}
void loop() {
if (Event == 1) {
if (SlaveValues[0] == 0) {
digitalWrite(0, LOW);
}
else {
digitalWrite(0, HIGH);
}
if (SlaveValues[1] == 0) {
digitalWrite(1, LOW);
}
else {
digitalWrite(1, HIGH);
}
if (SlaveValues[2] == 0) {
digitalWrite(2, LOW);
}
else {
digitalWrite(2, HIGH);
}
if (SlaveValues[3] == 0) {
digitalWrite(3, LOW);
}
else {
digitalWrite(3, HIGH);
}
if (SlaveValues[4] == 0) {
digitalWrite(4, LOW);
}
else {
digitalWrite(4, HIGH);
}
if (SlaveValues[5] == 0) {
digitalWrite(5, LOW);
}
else {
digitalWrite(5, HIGH);
}
if (SlaveValues[6] == 0) {
digitalWrite(6, LOW);
}
else {
digitalWrite(6, HIGH);
}
if (SlaveValues[7] == 0) {
digitalWrite(7, LOW);
}
else {
digitalWrite(7, HIGH);
}
if (SlaveValues[8] == 0) {
digitalWrite(8, LOW);
}
else {
digitalWrite(8, HIGH);
}
if (SlaveValues[9] == 0) {
digitalWrite(9, LOW);
}
else {
digitalWrite(9, HIGH);
}
if (SlaveValues[10] == 0) {
digitalWrite(10, LOW);
}
else {
digitalWrite(10, HIGH);
}
if (SlaveValues[11] == 0) {
digitalWrite(11, LOW);
}
else {
digitalWrite(11, HIGH);
}
if (SlaveValues[12] == 0) {
digitalWrite(12, LOW);
}
else {
digitalWrite(12, HIGH);
}
if (SlaveValues[13] == 0) {
digitalWrite(13, LOW);
}
else {
digitalWrite(13, HIGH);
}
if (SlaveValues[14] == 0) {
digitalWrite(A0, LOW);
}
else {
digitalWrite(A0, HIGH);
}
if (SlaveValues[15] == 0) {
digitalWrite(A1, LOW);
}
else {
digitalWrite(A1, HIGH);
}
if (SlaveValues[16] == 0) {
digitalWrite(A2, LOW);
}
else {
digitalWrite(A2, HIGH);
}
if (SlaveValues[17] == 0) {
digitalWrite(A3, LOW);
}
else {
digitalWrite(A3, HIGH);
}
Event = 0;
}
}
Comments