EC-Example-TrafficLight

From ArduinoInfo
Jump to navigation Jump to search

Traffic Light Example - EasyConnect

This example shows how to make and code a traffic light with RED-YELLOW-GREEN lights and a WHITE Walk Light.

The timing and sequencing of a traffic light is done with a "State Machine", which is a way to organize things like this so it doesn't get too confusing. It also reduces the chance of errors.

CODE Example: Traffic Light

Cut and Paste this into a blank Arduino IDE Window

/* YourSmartDuino-EM  TRAFFIC SIGNAL: Example 8
  - WHAT IT DOES: ***
  - Uses the KEYES Easy-Plug Modules
  - V3. 2/18/2019
   Questions: terry@yourduino.com
  - SEE the comments after "//" on each line below
  - CONNECTIONS: KEYES Easy-Plug Control Board V2.0
    NOTE: Different Software examples use a different sets of modules.
  /*-----( Import needed libraries )-----*/
 // ----------------------------------------------------------------------------
/*LiquidCrystal compability:
Since this hd44780 library is LiquidCrystal API compatible, most existing LiquidCrystal
sketches should work with hd44780 hd44780_I2Cexp i/o class once the
includes are changed to use hd44780 and the lcd object constructor is
changed to use the hd44780_I2Cexp i/o class.
*/
#include <Wire.h>
#include <hd44780.h>                       // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header

/*----------------( Declare Constants and Pin Numbers )-------------------*/
//----( DIGITAL Pins)----

//----- ( 2 pins in socket labelled D3 D4 can be used for Ultrasonic )-----
#define ULTRA_TRIG_PIN    3   // Connect to socket labelled "D3D4 
#define ULTRA_ECHO_PIN    4
#define BUZZER_PIN        5
#define RED_LIGHT         6  // Traffic Lights for specific example
#define YELLOW_LIGHT      7
#define GREEN_LIGHT       8
#define WALK_LIGHT        9

#define ONBOARD_LED_PIN   13

//----( DIGITAL INPUT Pins)----
#define REQUEST_WALK_PIN  A0    // Digital request traffic wal
#define SWITCH_PIN        A3   // Used for a variety of On-OFF Devices


//------( LOCAL DEFINITIONS )---------

#define ON       1
#define OFF      0

#define MAX_DISTANCE 300     // Maximum distance we want to ping for (in centimeters).
#define US_ROUNDTRIP_CM 58.2 // Ultrasonic Sensor constant

//-----( Traffic Control System States and definitions )-------
#define GREEN_STATE      0
#define CAUTION_STATE    1
#define RED_STATE        2
#define WALKING_STATE    3
#define WALK_FAST_STATE  4

#define MaxGreenSeconds  20
#define MinGreenSeconds  10
#define YellowSeconds     5
#define MaxRedSeconds    10
#define VehicleCloseCm   10  // Vehicle in sidestreet at light

/*--------------------( Declare objects )-------------------------*/
hd44780_I2Cexp lcd; // declare lcd object: auto locate & auto config expander chip 


/*------------------------( Declare Variables )-----------------------------------*/
//***
boolean  ShowedON  = false;
boolean  ShowedOFF = false;

int     TrafficControlState = 0; // ---( For Traffic Light Control example )----
int     StateDelaySeconds;       // Variable set for Traffic Light sequence states
boolean VehicleDetected     = false; //Set by Ultrasonic Distance Sensor
boolean TrafficSenseCall    = false;
boolean WalkerSenseCall     = false;

long duration_uS; // Duration used to calculate distance by Ultrasonic Sensor
int DistCM;       // Measured distance in CM

void setup()   /******************* SETUP: RUNS ONCE *************************/
{
  Serial.begin(115200);        // Start up the Serial Monitor

  lcd.begin(16, 2);  // initialize the lcd for 16 chars 2 lines, turn on backlight
  lcd.noBacklight();
  delay(500);
  lcd.backlight(); // finish with backlight on

  lcd.setCursor(0, 0); //Start at character 0 on line 0
  lcd.print(F("EasyConnect By"));
  lcd.setCursor(0, 1); //Start at character 0 on line 0
  lcd.print(F("YourDuino.com"));
  //
  pinMode(ULTRA_TRIG_PIN, OUTPUT);
  pinMode(ULTRA_ECHO_PIN, INPUT);

  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(REQUEST_WALK_PIN, INPUT_PULLUP);

  pinMode(GREEN_LIGHT, OUTPUT);
  pinMode(YELLOW_LIGHT, OUTPUT);
  pinMode(RED_LIGHT, OUTPUT);
  pinMode(WALK_LIGHT, OUTPUT);
  Serial.println("Option 18: TRAFFIC SIGNAL");
  lcd.setCursor(0, 0); //Start at character 0 on line 0
  //-----------1234567890123456----------
  lcd.print(F("8:TRAFFIC LIGHT "));
  StateDelaySeconds = MaxGreenSeconds;

  TrafficSenseCall = false;
  WalkerSenseCall = false;
  delay(2000);
}//--(end setup )---


void loop()   /********************** LOOP: RUNS CONSTANTLY ************************/
{
  lcd.setCursor(0, 1); //Start at character 0 on line
  //-------------------1234567890123456----------
  lcd.print(F("                "));
  lcd.setCursor(0, 1); //Start at character 0 on line
  lcd.print(F("STATE="));
  lcd.print(TrafficControlState);
  delay(100);


  if (SideStreetVehicleSense() == true)
  {
    TrafficSenseCall = true;
  }

  if (digitalRead(REQUEST_WALK_PIN) == 0)
  {
    WalkerSenseCall = true;
  }


  switch (TrafficControlState)

  {
    case GREEN_STATE:
      {
        Serial.println("GREEN");
        lcd.setCursor(8, 1); //Start at character 9 on line
        lcd.print(F("GREEN"));
        digitalWrite(GREEN_LIGHT, ON);
        digitalWrite(RED_LIGHT, OFF);
        if (StateDelaySeconds >= 0)
        {
          lcd.setCursor(14, 1); //Start at character 14 on line
          lcd.print(StateDelaySeconds);
          delay(1000);
          Serial.println(StateDelaySeconds);
          StateDelaySeconds -= 1;
        }
        else
        {
          StateDelaySeconds = YellowSeconds;
          TrafficControlState = CAUTION_STATE;
        }

        if (  (TrafficSenseCall | WalkerSenseCall)
              & (StateDelaySeconds < MinGreenSeconds) )
        {
          Serial.println("Vehicle/Walker Sensed");
          TrafficSenseCall = false;
          StateDelaySeconds = YellowSeconds;
          TrafficControlState = CAUTION_STATE;
        }

      }//End GREEN_STATE

      break;

    case CAUTION_STATE:
      {
        Serial.println("YELLOW");
        lcd.setCursor(8, 1); //Start at character 9 on line
        lcd.print(F("YELLOW"));
        digitalWrite(GREEN_LIGHT, OFF);
        digitalWrite(YELLOW_LIGHT, ON);
        if (StateDelaySeconds >= 0)
        {
          lcd.setCursor(15, 1); //Start at character 14 on line
          lcd.print(StateDelaySeconds);
          delay(1000);
          Serial.println(StateDelaySeconds);
          StateDelaySeconds -= 1;
        }
        else
        {
          StateDelaySeconds = MaxRedSeconds;
          TrafficControlState = RED_STATE;
        }
        TrafficSenseCall = false;

      }//End CAUTION_STATE
      break;

    case RED_STATE:
      {
        Serial.println("RED");
        lcd.setCursor(8, 1); //Start at character 9 on line
        lcd.print(F("RED"));
        digitalWrite(RED_LIGHT, ON);
        digitalWrite(YELLOW_LIGHT, OFF);
        if (StateDelaySeconds >= 0)
        {
          delay(1000);
          Serial.println(StateDelaySeconds);
          StateDelaySeconds -= 1;
        }
        else
        {
          StateDelaySeconds = MaxGreenSeconds;
          TrafficControlState = GREEN_STATE;
        }

        if (WalkerSenseCall)
        {
          Serial.println("Walker Sensed");
          WalkerSenseCall = false;
          TrafficControlState = WALKING_STATE;
        }

      }
      break;


    case WALKING_STATE:

      {
        Serial.println("WALKING");
        lcd.setCursor(8, 1); //Start at character 9 on line
        lcd.print(F("WALKING"));
        digitalWrite(BUZZER_PIN, ON);
        delay(100);
        digitalWrite(BUZZER_PIN, OFF);
        delay(100);
        digitalWrite(BUZZER_PIN, ON);
        delay(100);
        digitalWrite(BUZZER_PIN, OFF);        
        delay(700);
        digitalWrite(WALK_LIGHT, ON);
        delay(5000);
        digitalWrite(WALK_LIGHT, OFF);
        StateDelaySeconds = 4;
        TrafficControlState = WALK_FAST_STATE;

      }
      break;

    case WALK_FAST_STATE:
      {
        Serial.println("WALK FAST");
        lcd.setCursor(8, 1); //Start at character 9 on line
        lcd.print(F("RUN ! !"));

        if (StateDelaySeconds >= 0)
        {
          delay(500);
          digitalWrite(WALK_LIGHT, ON);
          digitalWrite(BUZZER_PIN, ON);
          delay(500);
          digitalWrite(WALK_LIGHT, OFF);
          digitalWrite(BUZZER_PIN, OFF);
          Serial.println(StateDelaySeconds);
          StateDelaySeconds -= 1;
        }
        else
        {
          delay(2000);
          StateDelaySeconds = MaxGreenSeconds;
          TrafficControlState = GREEN_STATE;
          WalkerSenseCall = false;
        }

      }
      break;


      delay(500);
  } //End Switch on TrafficControlState


}//--(end main loop )---


/*--------------------( Declare User-written Functions )------------------------*/
boolean SideStreetVehicleSense()
{
  /* The following trigPin/echoPin cycle is used to determine the
    distance of the nearest object by bouncing soundwaves off of it. */
  digitalWrite(ULTRA_TRIG_PIN, LOW);  // Pulse the Trigger  pin High and then Low
  delayMicroseconds(2);
  digitalWrite(ULTRA_TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(ULTRA_TRIG_PIN, LOW);

  duration_uS = pulseIn(ULTRA_ECHO_PIN, HIGH);

  //Calculate the distance (in cm) based on the speed of sound.
  DistCM = duration_uS / US_ROUNDTRIP_CM; // Calculate distance in CM

  Serial.print("DistCM = ");
  Serial.println(DistCM);
  if (DistCM <= VehicleCloseCm)
    return true;
  else
    return false;

}// END CheckSideStreet


//*********( THE END )***********