// https://wokwi.com/projects/375974332983806977
// https://forum.arduino.cc/t/traffic-light-time-to-green-count-down/1168737
#include <LiquidCrystal_I2C.h>
const uint8_t redPin = 4 ;
const uint8_t ledPin = 7 ;
bool lastRedState = HIGH ;
uint16_t counter = 0 ;
uint32_t lastSecs = 0 ;
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup() {
Serial.begin(115200);
pinMode(redPin, INPUT_PULLUP);
pinMode(ledPin, OUTPUT );
lcd.init( );
lcd.backlight();
setupTrafficLights();
}
void loop() {
serviceTrafficLights();
// to only run the traffic lights, just return; right here
bool redState = !digitalRead( redPin ) ; // true logic now
uint32_t secs = millis() / 1000 ;
if ( redState == LOW ) {
digitalWrite(ledPin, HIGH);
if ( secs != lastSecs ) {
lastSecs = secs ;
if ( counter > 0 ) counter-- ;
}
if ( lastRedState == HIGH ) {
lastRedState = redState ;
counter = 15 ; // should be 130. Life too short
}
static uint16_t onDisaply = 999; // impossible previous value
// if ((counter < 100) && (counter != onDisaply)) {
if ((counter < 10) && (counter != onDisaply)) {
lcd.clear();
lcd.print( counter );
onDisaply = counter;
}
}
else {
// clear up
lcd.clear() ;
digitalWrite(ledPin, LOW);
lastRedState = HIGH ;
}
}
// code to create a set of traffic lights to inform the coutdown process
// non-blocked traffic light sequencer
// "Usual UK system of Red Red/Amber Green Amber "
// three outputs for the simulated traffic lights
const uint8_t redLight = 8;
const uint8_t yellowLight = 9;
const uint8_t greenLight = 10;
enum {RED, REDAMBER, GREEN, AMBER};
const unsigned long times[4] = {15000, 4000, 12000, 4000}; // in milliseconds here
void setupTrafficLights()
{
pinMode(redLight, OUTPUT);
pinMode(yellowLight, OUTPUT);
pinMode(greenLight, OUTPUT);
}
void serviceTrafficLights()
{
static unsigned char phase = 0;
static unsigned long waitFrom;
unsigned long now = millis();
if (waitFrom && now - waitFrom < times[phase]) return;
phase++; if (phase >= 4) phase = 0;
waitFrom = now;
switch(phase) {
case RED :
digitalWrite(redLight, HIGH);
digitalWrite(yellowLight, LOW);
digitalWrite(greenLight, LOW);
break;
case REDAMBER :
digitalWrite(redLight, HIGH);
digitalWrite(yellowLight, HIGH);
digitalWrite(greenLight, LOW);
break;
case GREEN :
digitalWrite(redLight, LOW);
digitalWrite(yellowLight, LOW);
digitalWrite(greenLight, HIGH);
break;
case AMBER :
digitalWrite(redLight, LOW);
digitalWrite(yellowLight, HIGH);
digitalWrite(greenLight, LOW);
break;
default :
// yes, this did show up, so
Serial.println("logic error somewhere");
}
}
Using theRED traffic light as input
reflects input to countdown