// STREET OUTLAWFULLy
// by c goulding aka groundFungus
#include <Wire.h>
#include <hd44780.h> // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h>
hd44780_I2Cexp lcd;
const byte leftStagedLedPin = 2;
const byte rightStagedLedPin = 3;
const byte y1ledPin = 4;
const byte y2ledPin = 5;
const byte y3ledPin = 6;
const byte gLeftLedPin = 7;
const byte rLeftLedPin = 8;
const byte leftWinLedPin = 9;
const byte gRightLedPin = 10;
const byte rRightLedPin = 11;
const byte rightWinLedPin = 12;
const byte lPedalButtonPin = A1; // trans brake left
const byte rPedalButtonPin = A2; // trans brake right
const byte startButtonPin = A0; // start sequence
unsigned long yellowInterval = 0; // time between yellow lights
unsigned long yellowIntervalMax = 800;
unsigned long yellowIntervalMin = 200;
unsigned long stageInterval = 0; // time from stage to firs yellow
unsigned long stageIntervalMax = 3000;
unsigned long stageIntervalMin = 500;
unsigned long rtTimer = 0; // reaction time
float reactionTime = 0.00;
void setup()
{
Serial.begin(115200);
Serial.println(F("christmas tree starting"));
lcd.begin(16, 2);
lcd.print("Tree Starting");
lcd.setCursor(0, 1);
lcd.print("Bulb Check");
pinMode(leftStagedLedPin, OUTPUT);
pinMode(rightStagedLedPin, OUTPUT);
pinMode(y1ledPin, OUTPUT);
pinMode(y2ledPin, OUTPUT);
pinMode(y3ledPin, OUTPUT);
pinMode(gLeftLedPin, OUTPUT);
pinMode(rLeftLedPin, OUTPUT);
pinMode(leftWinLedPin, OUTPUT);
pinMode(gRightLedPin, OUTPUT);
pinMode(rRightLedPin, OUTPUT);
pinMode(rightWinLedPin, OUTPUT);
pinMode(lPedalButtonPin, INPUT_PULLUP);
pinMode(rPedalButtonPin, INPUT_PULLUP);
pinMode(startButtonPin, INPUT_PULLUP);
randomSeed(analogRead(A3));
// bulb test
digitalWrite(y1ledPin, HIGH);
digitalWrite(y2ledPin, HIGH);
digitalWrite(y3ledPin, HIGH);
delay(2000);
digitalWrite(y1ledPin, LOW);
digitalWrite(y2ledPin, LOW);
digitalWrite(y3ledPin, LOW);
delay(2000);
digitalWrite(rRightLedPin, HIGH);
digitalWrite(rLeftLedPin, HIGH);
digitalWrite(gLeftLedPin, HIGH);
digitalWrite(gRightLedPin, HIGH);
digitalWrite(leftStagedLedPin, HIGH);
digitalWrite(rightStagedLedPin, HIGH);
digitalWrite(leftWinLedPin, HIGH);
digitalWrite(rightWinLedPin, HIGH);
delay(1000);
digitalWrite(rRightLedPin, LOW);
digitalWrite(rLeftLedPin, LOW);
digitalWrite(gLeftLedPin, LOW);
digitalWrite(gRightLedPin, LOW);
digitalWrite(leftStagedLedPin, LOW);
digitalWrite(rightStagedLedPin, LOW);
digitalWrite(leftWinLedPin, LOW);
digitalWrite(rightWinLedPin, LOW);
Serial.println(F("Tree ready Press START button"));
lcd.clear();
lcd.print(F("Tree ready"));
lcd.setCursor(0, 1);
lcd.print(F("Press START"));
}
void loop()
{
static byte mode = 0;
static unsigned long timer = 0;
if (mode == 0)
{
static bool lastStartButtonState = HIGH;
bool startButtonState = digitalRead(startButtonPin);
if (startButtonState != lastStartButtonState)
{
if (startButtonState == LOW)
{
Serial.println("stage ... press your transbrake to stage");
lcd.clear();
lcd.print("stage your car");
lcd.setCursor(0, 1);
lcd.print("press transbrake");
digitalWrite(rRightLedPin, LOW);
digitalWrite(rLeftLedPin, LOW);
digitalWrite(gLeftLedPin, LOW);
digitalWrite(gRightLedPin, LOW);
digitalWrite(leftStagedLedPin, LOW);
digitalWrite(rightStagedLedPin, LOW);
digitalWrite(leftWinLedPin, LOW);
digitalWrite(rightWinLedPin, LOW);
mode = 1;
}
lastStartButtonState = startButtonState;
}
}
if (mode == 1)
{
bool rightStage = digitalRead(rPedalButtonPin);
bool leftStage = digitalRead(lPedalButtonPin);
if (leftStage == LOW)
{
digitalWrite(leftStagedLedPin, HIGH);
}
if (rightStage == LOW)
{
digitalWrite(rightStagedLedPin, HIGH);
}
if (leftStage == LOW && rightStage == LOW)
{
timer = millis();
stageInterval = random(stageIntervalMin, stageIntervalMax);
Serial.println("Staged GO ON GREEN");
lcd.clear();
lcd.print("Staged");
lcd.setCursor(0, 1);
lcd.print("GO ON GREEN");
mode = 2;
}
}
if (mode == 2)
{
if (millis() - timer > stageInterval)
{
digitalWrite(leftStagedLedPin, LOW);
digitalWrite(rightStagedLedPin, LOW);
yellowInterval = random(yellowIntervalMin, yellowIntervalMax);
timer = millis();
mode = 3;
}
}
// yellow light #1
if (mode == 3)
{
digitalWrite(y1ledPin, HIGH);
if (millis() - timer >= yellowInterval)
{
digitalWrite(y1ledPin, LOW);
timer = millis();
mode = 4;
}
// left red light
if (digitalRead(lPedalButtonPin) == HIGH)
{
digitalWrite(y1ledPin, LOW);
digitalWrite(rLeftLedPin, HIGH);
lcd.clear();
lcd.print(" JUMP *******");
lcd.setCursor(0, 1);
lcd.print(" ");
mode = 0;
}
//right red light
if (digitalRead(rPedalButtonPin) == HIGH)
{
digitalWrite(y1ledPin, LOW);
digitalWrite(rRightLedPin, HIGH);
lcd.clear();
lcd.print("******* JUMP ");
lcd.setCursor(0, 1);
lcd.print(" ");
mode = 0;
}
}
// yellow light #2
if (mode == 4)
{
digitalWrite(y2ledPin, HIGH);
if (millis() - timer >= yellowInterval)
{
digitalWrite(y2ledPin, LOW);
timer = millis();
mode = 5;
}
// left red light
if (digitalRead(lPedalButtonPin) == HIGH)
{
digitalWrite(y2ledPin, LOW);
digitalWrite(rLeftLedPin, HIGH);
lcd.clear();
lcd.print(" JUMP *******");
lcd.setCursor(0, 1);
lcd.print(" ");
mode = 0;
}
if (digitalRead(rPedalButtonPin) == HIGH)
{
digitalWrite(y2ledPin, LOW);
digitalWrite(rRightLedPin, HIGH);
lcd.clear();
lcd.print("******* JUMP ");
lcd.setCursor(0, 1);
lcd.print(" ");
mode = 0;
}
}
// yellow light #3
if (mode == 5)
{
digitalWrite(y3ledPin, HIGH);
if (millis() - timer >= yellowInterval)
{
digitalWrite(y3ledPin, LOW);
timer = millis();
mode = 6;
}
// left red light
if (digitalRead(lPedalButtonPin) == HIGH)
{
digitalWrite(y3ledPin, LOW);
digitalWrite(rLeftLedPin, HIGH);
lcd.clear();
lcd.print(" JUMP *******");
lcd.setCursor(0, 1);
lcd.print(" ");
mode = 0;
}
if (digitalRead(rPedalButtonPin) == HIGH)
{
digitalWrite(y3ledPin, LOW);
digitalWrite(rRightLedPin, HIGH);
lcd.clear();
lcd.print("******* JUMP ");
lcd.setCursor(0, 1);
lcd.print(" ");
mode = 0;
}
}
// yellow light #4
if (mode == 6)
{
digitalWrite(y1ledPin, LOW);
if (millis() - timer >= yellowInterval)
{
digitalWrite(y1ledPin, LOW);
timer = millis();
mode = 7;
}
// left red light
if (digitalRead(lPedalButtonPin) == HIGH)
{
digitalWrite(y1ledPin, LOW);
digitalWrite(rLeftLedPin, HIGH);
lcd.clear();
lcd.print(" JUMP *******");
lcd.setCursor(0, 1);
lcd.print(" ");
mode = 0;
}
//right red light
if (digitalRead(rPedalButtonPin) == HIGH)
{
digitalWrite(y1ledPin, LOW);
digitalWrite(rRightLedPin, HIGH);
lcd.clear();
lcd.print("******* JUMP ");
lcd.setCursor(0, 1);
lcd.print(" ");
mode = 0;
}
}
// yellow light #5
if (mode == 7)
{
digitalWrite(y1ledPin, LOW);
if (millis() - timer >= yellowInterval)
{
digitalWrite(y1ledPin, LOW);
timer = millis();
mode = 8;
}
// left red light
if (digitalRead(lPedalButtonPin) == HIGH)
{
digitalWrite(y1ledPin, LOW);
digitalWrite(rLeftLedPin, HIGH);
lcd.clear();
lcd.print(" JUMP *******");
lcd.setCursor(0, 1);
lcd.print(" ");
mode = 0;
}
//right red light
if (digitalRead(rPedalButtonPin) == HIGH)
{
digitalWrite(y1ledPin, LOW);
digitalWrite(rRightLedPin, HIGH);
lcd.clear();
lcd.print("******* JUMP ");
lcd.setCursor(0, 1);
lcd.print(" ");
mode = 0;
}
}
// yellow light #6
if (mode == 8)
{
digitalWrite(y1ledPin, LOW);
if (millis() - timer >= yellowInterval)
{
digitalWrite(y1ledPin, LOW);
timer = millis();
mode = 9;
}
// left red light
if (digitalRead(lPedalButtonPin) == HIGH)
{
digitalWrite(y1ledPin, LOW);
digitalWrite(rLeftLedPin, HIGH);
lcd.clear();
lcd.print(" JUMP *******");
lcd.setCursor(0, 1);
lcd.print(" ");
mode = 0;
}
//right red light
if (digitalRead(rPedalButtonPin) == HIGH)
{
digitalWrite(y1ledPin, LOW);
digitalWrite(rRightLedPin, HIGH);
lcd.clear();
lcd.print("******* JUMP ");
lcd.setCursor(0, 1);
lcd.print(" ");
mode = 0;
}
}
// green lights
if (mode == 9)
{
digitalWrite(gLeftLedPin, HIGH);
digitalWrite(gRightLedPin, HIGH);
rtTimer = micros();
mode = 10;
}
if (mode == 10)
{
bool lPedalButtonState = digitalRead(lPedalButtonPin);
unsigned long lfNow = micros();
bool rPedalButtonState = digitalRead(rPedalButtonPin);
unsigned long rtNow = micros();
if (lPedalButtonState == HIGH)
{
digitalWrite(leftWinLedPin, HIGH);
digitalWrite(rightWinLedPin, LOW);
reactionTime = (lfNow - rtTimer) / 1000.00;
Serial.print("LEFT lane <<< WIN >>> reaction time = ");
Serial.print(reactionTime, 1);
Serial.println(" ms");
lcd.clear();
lcd.print(" WIN *******");
lcd.setCursor(0, 1);
lcd.print("RT ");
lcd.print(reactionTime, 1);
lcd.print(" >>>>");
mode = 0;
}
if (rPedalButtonState == HIGH)
{
digitalWrite(leftWinLedPin, LOW);
digitalWrite(rightWinLedPin, HIGH);
reactionTime = (rtNow - rtTimer) / 1000.00;
Serial.print("RIGHT lane <<< WIN >>> reaction time = ");
Serial.print(reactionTime, 1);
Serial.println(" ms");
lcd.clear();
lcd.print("******* WIN ");
lcd.setCursor(0, 1);
lcd.print("RT ");
lcd.print(reactionTime, 1);
lcd.print(" >>>>");
mode = 0;
}
}
}