Skip to content

Instantly share code, notes, and snippets.

@formix
Last active March 4, 2021 15:09
Show Gist options
  • Save formix/259f2d80f50000487d52030b81c5352f to your computer and use it in GitHub Desktop.
Save formix/259f2d80f50000487d52030b81c5352f to your computer and use it in GitHub Desktop.
This is a traffic light finite state machine demonstration / challenge. Debug it and do the challenges at the end of the code.
// Copyright 2020 Jean-Philippe Gravel <jeanphilippe.gravel@gmail.com>
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
// Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// make unsigned long declaration shorter.
#define ulong unsigned long
// state values of the finite state machine
#define STATE_TRAFFIC_NS 1
#define STATE_TRAFFIC_NS_YELLOW 2
#define STATE_PEDESTRIANS 4
#define STATE_TRAFFIC_EW 8
#define STATE_TRAFFIC_EW_YELLOW 16
// arduino pin definition
// EAST/WEST lights
#define PIN_RED_EW 13
#define PIN_YELLOW_EW 12
#define PIN_GREEN_EW 11
// NORTH/SOUTH lights
#define PIN_RED_NS 10
#define PIN_YELLOW_NS 9
#define PIN_GREEN_NS 8
// pedestrians all directions
#define PIN_PEDESTRIANS 7
// global variable declaration.
int _state;
ulong _begin_time;
void setup() {
pinMode(PIN_RED_NS, OUTPUT);
pinMode(PIN_YELLOW_NS, OUTPUT);
pinMode(PIN_GREEN_NS, OUTPUT);
pinMode(PIN_PEDESTRIANS, OUTPUT);
pinMode(PIN_RED_EW, OUTPUT);
pinMode(PIN_YELLOW_EW, OUTPUT);
pinMode(PIN_GREEN_EW, OUTPUT);
_state = STATE_PEDESTRIANS;
_begin_time = millis();
}
void loop() {
ulong end_time = millis();
ulong elapsed = end_time - _begin_time;
switch(_state) {
case STATE_TRAFFIC_NS:
digitalWrite(PIN_GREEN_NS, HIGH);
digitalWrite(PIN_YELLOW_NS, LOW);
digitalWrite(PIN_RED_NS, LOW);
digitalWrite(PIN_PEDESTRIANS, LOW);
digitalWrite(PIN_GREEN_EW, LOW);
digitalWrite(PIN_YELLOW_EW, LOW);
digitalWrite(PIN_RED_EW, HIGH);
if (elapsed > 60000) {
_state = STATE_TRAFFIC_NS_YELLOW;
_begin_time = end_time;
}
break;
case STATE_TRAFFIC_NS_YELLOW:
digitalWrite(PIN_GREEN_NS, LOW);
digitalWrite(PIN_YELLOW_NS, HIGH);
digitalWrite(PIN_RED_NS, LOW);
digitalWrite(PIN_PEDESTRIANS, LOW);
digitalWrite(PIN_GREEN_EW, LOW);
digitalWrite(PIN_YELLOW_EW, LOW);
digitalWrite(PIN_RED_EW, HIGH);
if (elapsed > 10000) {
_state = STATE_PEDESTRIANS;
_begin_time = end_time;
}
break;
case STATE_PEDESTRIANS:
digitalWrite(PIN_GREEN_NS, LOW);
digitalWrite(PIN_YELLOW_NS, LOW);
digitalWrite(PIN_RED_NS, HIGH);
digitalWrite(PIN_PEDESTRIANS, HIGH);
digitalWrite(PIN_GREEN_EW, LOW);
digitalWrite(PIN_YELLOW_EW, LOW);
digitalWrite(PIN_RED_EW, HIGH);
if (elapsed > 60000) {
_state = STATE_TRAFFIC_EW;
_begin_time = end_time;
}
break;
case STATE_TRAFFIC_EW:
digitalWrite(PIN_GREEN_NS, LOW);
digitalWrite(PIN_YELLOW_NS, LOW);
digitalWrite(PIN_RED_NS, HIGH);
digitalWrite(PIN_PEDESTRIANS, LOW);
digitalWrite(PIN_GREEN_EW, HIGH);
digitalWrite(PIN_YELLOW_EW, LOW);
digitalWrite(PIN_RED_EW, LOW);
if (elapsed > 60000) {
_state = STATE_TRAFFIC_EW_YELLOW;
_begin_time = end_time;
}
break;
case STATE_TRAFFIC_EW_YELLOW:
digitalWrite(PIN_GREEN_NS, LOW);
digitalWrite(PIN_YELLOW_NS, LOW);
digitalWrite(PIN_RED_NS, HIGH);
digitalWrite(PIN_PEDESTRIANS, LOW);
digitalWrite(PIN_GREEN_EW, LOW);
digitalWrite(PIN_YELLOW_EW, HIGH);
digitalWrite(PIN_RED_EW, LOW);
if (elapsed > 10000) {
_state = STATE_TRAFFIC_NS;
_begin_time = end_time;
}
break;
}
// Challenge #0: This code is untested. Make sure it runs as expected
// before stepping into challenge 1. Fix any issue you
// find until the complete light cycle works. This is not
// a catch, it could work as is... or not.
//
// Challenge #1: Make the pedestrian light flash at 2 hertz for
// the last 15 seconds of its cycle.
//
// Challenge #2: Do not enter the STATE_PEDESTRIANS state unless
// a pedestrian crossing request button is pressed.
//
// Challenge #3: Add a car detection input to on both north and south lanes.
// After the standard 1 minute EAST/WEST traffic time counter
// elapsed, keep the east-west traffic running until a car
// is detected on the north OR south lane. Cycle into
// STATE_TRAFFIC_NS for one minute and continue the cycle.
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment