Introduction: Mock Traffic Light

New age traffic lights have sensors underneath the road to change the lights when cars arrive in another direction. I'm going to recreate this with 2 Arduinos. One is connected to the road which has buttons that represent the sensors. The other has sets of green/yellow/red LEDS for traffic lights. When a button is pressed, the info will be sent to the other Arduino, which will check if cars are still coming from one direction, if not then the light will change, if so it will wait a cycle check again, until the flow of traffic stops and the lights will change.

Step 1: Transmitting Arduino

I used an Arduino Uno and an NRF24L01(radio chip) for this part of the project. I used the following pin codes to connect them:

CE > D8

CSN > D10

SCK > D13

MO > D11

MI > D12

RO > Not used

GND > GND

VCC > 5V

Additionally I connected up 2 buttons to two inputs to represent the pressure pads.

Step 2: Transmitting Code

This code is pretty simple: it sets up the two buttons as inputs and also sets up the NRF24L01. Then it cycles every 0.1 seconds and checks if (1) the main street is being driven on (2) the side street is being driven on (3) neither is active. It then sends that data out.

/*
NRF24L01      Arduino
CE       >     D8
CSN      >     D10
SCK      >     D13
MO       >     D11
MI       >     D12
RO       >     Not used 
GND      >     GND
VCC      >     5V
 */
#include 
#include 
const int button_main = 2;
const int button_side = 3;
// Singleton instance of the radio driver
RH_NRF24 nrf24;
void setup() 
{
  pinMode(button_main, INPUT);
  pinMode(button_side, INPUT);
  Serial.begin(9600);
  if (!nrf24.init())
    Serial.println("init failed");
  // Defaults after init are 2.402 GHz (channel 2), 2Mbps, 0dBm
  if (!nrf24.setChannel(125))
    Serial.println("setChannel failed");
  if (!nrf24.setRF(RH_NRF24::DataRate2Mbps, RH_NRF24::TransmitPower0dBm))
    Serial.println("setRF failed");    
}
void loop()
{
  if (digitalRead(button_main) == HIGH)
  {
  uint8_t data[] = "Main";
  nrf24.send(data, sizeof(data));
  }
  delay(20); //prevents data overflow when button is held (theoretically)
  else if (digitalRead(button_side) == HIGH)
  {
  uint8_t data[] = "S";
  nrf24.send(data, sizeof(data));
  }
  else 
  {
  uint8_t data[] = "No";
  nrf24.send(data, sizeof(data));
  }
  delay(100); //prevents data overflow when button is held (theoretically)
}

Step 3: Receiving Arduino

The receiving arduino and the NRF24L01 are wired in the same manner as the transmitter. However, for this design I have 6 LEDs each connected to a pinout that represent the traffic lights.

Step 4: Receiving Code

This code is a bit more complex. The code first sets up the LEDs as outputs and sets up the NRF24L01. Then it checks the code it received. If the code says that the main street was pressed and the main street is already green lighted, it resets the main street counter. If the main street is not green lighted, it checks if noone is on the side street. If so, then it changes the light. It also does the same for the side street. If neither was pressed, it increases the counter for both. The light changes from green to yellow to red with a 1 second delay, then turns the other to green

/*
NRF24L01      Arduino
CE       >     D8
CSN      >     D10
SCK      >     D13
MO       >     D11
MI       >     D12
RO       >     Not used 
GND      >     GND
VCC      >     5V
 */
#include 
#include 
const int m_r = 2;
const int m_y = 3;
const int m_g = 4;
const int s_r = 5;
const int s_y = 6;
const int s_g = 7;
bool side = false;
bool main = true;
int m_count = 0;
int s_count = 0
RH_NRF24 nrf24;
void setup()
{
  pinMode(m_r, OUTPUT);
  pinMode(m_y, OUTPUT);
  pinMode(m_g, OUTPUT);
  pinMode(s_r, OUTPUT);
  pinMode(s_y, OUTPUT);
  pinMode(s_g, OUTPUT);
  digitalWrite(m_g, HIGH);
  digitalWrite(s_r, HIGH);
  Serial.begin(9600);
  if (!nrf24.init())
    Serial.println("init failed");
  if (!nrf24.setChannel(125))           //set channel to 125
    Serial.println("setChannel failed");
  if (!nrf24.setRF(RH_NRF24::DataRate2Mbps, RH_NRF24::TransmitPower0dBm))
    Serial.println("setRF failed");
}
void loop()
{
  if (nrf24.available())
  {
    uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];   
    uint8_t len = sizeof(buf);
    if (nrf24.recv(buf, &len))             //read message
    {
      Serial.print("got request: ");
      Serial.println((char*)buf);
     if(len > 2)
     {
        if(main == true)
        {
          m_count = 0;
        }
        if(main != true)
        {
          if (s_count > 30)
          {
            side_to_main();
          }
        }
        s_count++;
     }
     else if(len == 2)
     {
       m_count++;
       s_count++;
     }
     else if (len==1)
     {
        if(side == true)
        {
          s_count = 0;
        }
        if(side != true)
        {
          if (m_count > 30)
          {
            main_to_side();
          }
        }
        m_count++;
     }
     
    }
  }
}
void main_to_side()
{
     digitalWrite(m_g, LOW);
     digitalWrite(m_y, HIGH);
     delay 1000;
     digitalWrite(m_y, LOW);
     digitalWrite(m_r, HIGH);
     delay 1000;
     digitalWrite(s_g, HIGH);
     bool side = true;
     bool main = false; 
}
void side_to_main()
{
     digitalWrite(s_g, LOW);
     digitalWrite(s_y, HIGH);
     delay 1000;
     digitalWrite(s_y, LOW);
     digitalWrite(s_r, HIGH);
     delay 1000;
     digitalWrite(m_g, HIGH);
      bool side = false;
     bool main = true; 
}

Step 5: Arduino in Action