/*
**************************************
Traffic Light software - version 4
FINAL VERSION
uses the Case statement and millis for
timing functions and not delay()
Transitions between Case statements have
unused transitions removed
The stopping/restarting of the light
sequence button actions are added
**************************************
*/
//Define the traffic light output pin numbers
//Traffic Light A
#define TLARED 2
#define TLAAMBER 3
#define TLAGREEN 4
//Traffic Light B
#define TLBRED 5
#define TLBAMBER 6
#define TLBGREEN 7
//Define the input push button pin numbers
#define STOPSEQUENCE 8
#define RESET_RESTART 9
//Define the state of operation from pushbutton inputs
//Set to 1 if in normal operation, set to 2 if in special operation
static unsigned int OperationState;
//Define the sequence state of the lights - 1 through to 8
static unsigned int state;
//Define the timing variables
static unsigned long previousMillis; // stored previous value of millis
static unsigned long currentMillis; // current value of millis
static unsigned long SEQUENCEDELAY1; //30 second delay timer
static unsigned long SEQUENCEDELAY2; // 2 second delay timer
static unsigned long SEQUENCEDELAY3; // 5 second reduced special mode delay timer
void setup() {
// code in the section of the program runs only once at startup:
// initialize the output pins:
pinMode(TLARED, OUTPUT);
pinMode(TLAAMBER, OUTPUT);
pinMode(TLAGREEN, OUTPUT);
pinMode(TLBRED, OUTPUT);
pinMode(TLBAMBER, OUTPUT);
pinMode(TLBGREEN, OUTPUT);
// initialize the input pins:
pinMode(STOPSEQUENCE, INPUT_PULLUP);
pinMode(RESET_RESTART, INPUT_PULLUP);
// initialise the traffic light sequence state variable
state = 1;
// initialise the operation state variable
OperationState = 1;
//initialise the time delay variables
previousMillis = 0; // set previousMillis to zero
currentMillis = 0; // set currentMillis to zero
SEQUENCEDELAY1 = 2000; // set SEQUENCEDELAY1 to 30 seconds
SEQUENCEDELAY2 = 700; // set SEQUENCEDELAY2 to 2 seconds
SEQUENCEDELAY3 = 300; // set SEQUENCEDELAY3 to 5 seconds
Serial.begin(115200);
}
void loop() {
// traffic light sequence - with Case statements - loops runs continuously:
//check to see which operating mode the lights should be in
if (digitalRead(STOPSEQUENCE) == 0) {
// // stopping of sequence switch pressed - special mode
// need to seqence to red light in both directions safely
OperationState = 2;
}
if (digitalRead(RESET_RESTART) == 0) {
// reset/restart of sequence switch pressed
// resume normal operation
OperationState = 1;
}
static int lastOperationState = -1;
if (lastOperationState != OperationState) {
Serial.print("OperationState is ");
Serial.print(OperationState);
Serial.print("\n");
lastOperationState = OperationState;
}
// gets the current time value
currentMillis = millis();
static int lastPrintedState = -1;
const char *names[] = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight"};
if (lastPrintedState != state) {
Serial.print("state is ");
Serial.print(state);
if (state >=0 && state <= 8) {
Serial.print(" (");
Serial.print(names[state]);
Serial.print(")");
}
Serial.print("\n");
lastPrintedState = state;
}
switch (state) {
case 1:
//sequence step 1
digitalWrite(TLARED, HIGH);
digitalWrite(TLAAMBER, LOW);
digitalWrite(TLAGREEN, LOW);
digitalWrite(TLBRED, HIGH);
digitalWrite(TLBAMBER, LOW);
digitalWrite(TLBGREEN, LOW);
if (OperationState == 1)
// working in normal sequence mode
{
//check the time delay to see if it has expired
if (currentMillis - previousMillis >= SEQUENCEDELAY1) {
state = state + 1;
previousMillis = currentMillis;
}
}
break;
case 2:
//sequence step 2
digitalWrite(TLBAMBER, HIGH);
if (OperationState == 1)
// working in normal sequence mode
{
//check the time delay to see if it has expired
if (currentMillis - previousMillis >= SEQUENCEDELAY2) {
state = state + 1;
previousMillis = currentMillis;
}
}
break;
case 3:
//sequence step 3
digitalWrite(TLBRED, LOW);
digitalWrite(TLBAMBER, LOW);
digitalWrite(TLBGREEN, HIGH);
if (OperationState == 1)
// working in normal sequence mode
{
//check the time delay to see if it has expired
if (currentMillis - previousMillis >= SEQUENCEDELAY1) {
state = state + 1;
previousMillis = currentMillis;
}
}
break;
case 4:
//sequence step 4
digitalWrite(TLBAMBER, HIGH);
digitalWrite(TLBGREEN, LOW);
if (OperationState == 1)
// working in normal sequence mode
{
//check the time delay to see if it has expired
if (currentMillis - previousMillis >= SEQUENCEDELAY2) {
state = state + 1;
previousMillis = currentMillis;
}
}
break;
case 5:
//sequence step 5
digitalWrite(TLBRED, HIGH);
digitalWrite(TLBAMBER, LOW);
if (OperationState == 1)
// working in normal sequence mode
{
//check the time delay to see if it has expired
if (currentMillis - previousMillis >= SEQUENCEDELAY1) {
state = state + 1;
previousMillis = currentMillis;
}
}
break;
case 6:
//sequence step 6
digitalWrite(TLAAMBER, HIGH);
if (OperationState == 1)
// working in normal sequence mode
{
//check the time delay to see if it has expired
if (currentMillis - previousMillis >= SEQUENCEDELAY2) {
state = state + 1;
previousMillis = currentMillis;
}
}
break;
case 7:
//sequence step 7
digitalWrite(TLARED, LOW);
digitalWrite(TLAAMBER, LOW);
digitalWrite(TLAGREEN, HIGH);
if (OperationState == 1)
// working in normal sequence mode
{
//check the time delay to see if it has expired
if (currentMillis - previousMillis >= SEQUENCEDELAY1) {
state = state + 1;
previousMillis = currentMillis;
}
}
break;
case 8:
//sequence step 8
digitalWrite(TLAAMBER, HIGH);
digitalWrite(TLAGREEN, LOW);
if (OperationState == 1)
// working in normal sequence mode
{
//check the time delay to see if it has expired
if (currentMillis - previousMillis >= SEQUENCEDELAY1) {
state = 1; //go back to state 1 - start of sequence
previousMillis = currentMillis;
}
}
break;
}
}