Traffic light time to Green - Count down

Hi, Sorry if this is in the wrong place and Mods please feel free to move it if need be.

I need some help with working out... A) If this is possible and if it is...B) How the script would be written?

I am constructing a 2/3 size real working pair of traffic lights, to be used to enable cars etc to pass through a narrow section of private roadway, where only one vehicle at a time can pass through. Usual UK system of Red-Red/Amber-Green to Amber then Red. The timing of the lights operation is all done and I have a set already working correctly, but I would like to add to each traffic light head a two digit count down display which advises any waiting vehicle that the Green will become available in XX seconds (Decreasing from 99 to 0). I hope to use a couple of Uno's I have - one in each head and trigger their timing via the traffic lights red aspect initially being lit. The counter displays are two digit seven segment common Cathode 0.56". So timing starts on the red being lit, but has to begin at 130 seconds as that is the time interval from initially going to red then that light eventually going to green. So the count down digits won't light until the timer has reached 99 seconds then counts down to 0 and the green aspect lights and the counting display turns off and resets ready for the red to trigger it again.

Is such possible? If so, can anyone offer guidance on the script needed?

Many thanks for reading the above and hopefully helping.

Of course it is possible. You have a counter running from 130 to 0 and you want to display something only when the counter is less than 100. The only thing I'd question is if a 0.56" display is large enough for a driver to be able to read it. Show your program if you need additional input.

Possible, yes - whether it's a good idea is more questionable:

Drivers are bad enough at jumping lights as it is - this might encourage them...

:thinking:

1 Like

Why? One UNO is easily enough to do all the work - and I think it will be boring for him :wink:

The lights need drivers anyhow and cannot be connected to the UNO direectly.

One at each end, I'd guess?

Hello BrianL

This is a nice project for the weekend.

I think this display is very, very small.

As mentioned by your side, the road is on private property.
Here there is the possibility of flashing the red light of the traffic lights:

Gentlemen, start your engines!

The control of the traffic light phases can be realised by a simple led sequencer.

Have a nice day and enjoy coding in C++.

It's using the UK sequence - so the Red+Amber phase already serves that purpose.

Why not?
In many countries almost all traffic lights are equipped with such counters.
Screenshot from 2023-09-15 15-27-00

Because of the reason I stated!

But Isn't that a countdown of the remaining green time?

OP is asking about the countdown of the remaining red time.

counters count both green and red colors:
Screenshot from 2023-09-15 15-45-44

In the photo - 13 seconds of remaining time for pedestrians, 15 seconds of waiting for drivers. 2 sec safety gap between switches .

Well, thanks to all who replied. Two Uno's - as stated in my opening post - one in each traffic light head (otherwise loads of cabling needed head to head!) While i appreciate my display may be a bit small its only for the front vehicle to view!
So How / what is the code for a count down timer from 130 seconds to zero with display commencing at 99 seconds. Reset and wait for next red to be feed to start sequence again? I have no idea? Is there one already available or does it need a new script?

Edit to correct typo.

Hello BrianL

Do you will go to design a wireless system to sychronize the traffic light stages?

If you post that sketch, it will allow us to taylor our responses to be at an appropriate level.

Have you written anything that deals with the display? Did you say which display exactly you have or pin to acquire?

I wonder along with @paulpaulson how you will synchronize the two stations, and I wonder how far apart they are, and whether there is a direct line of sight betwixt them.

a7

Hi

I do not have sketch, hence my question. Is one readily available that perhaps could be modified?
Timing for each heads would only be started when that heads red aspect is initially lit. Once at green the Uno would reset and wait for the next red.

The two Uno's, if used, do not need to be synced, as above, the timing is only started when that head has its red LED aspect initally lit.

The two heads will be approx. 120-150 Yds apart on an 80 degree road bend with a building on the corner obscuring views and the road width of approx. a Transit style van. Hence the need for traffic management.

The traffic lights are already working (On test only) via a 4 core cable to each head from the lights control centre. Cable core 1 = Red feed, Core 2 Amber feed, Core 3 Green feed and Core 4 Return - 24 volt DC.
I just thought adding a countdown display might be useful, but its not essential. My idea was that a vehicle waiting at the red traffic light may not know how long they have to wait.

#Please note this a small private access road, with a few cars / vans etc an hour. But one vehicle leaving can cause issues currently if it meets an unseen (due to the corner and building ) an incoming vehicle. Hence the need for traffic lights that cycle through their sequence every 130 seconds.

Enjoy the weekend and have fun.

The traffic lights are already installed and working. Theses are cabled together and are synchronised by an existing mechanism. You simply want to add something which detects when a red light switches on (transition from amber to red) and start a counter. That counter will show the remaining time of the red light but suppress the display of the counter if it is greater than 99. If that is correct then you do not need any additional synchronisation.

EDIT

If you are able to make a physical connection to the red light, then it is best to use a opto-coupler. That reduces the risk of 24 volts appearing on an Arduino pin. How are you going to power the Uno? With a buck converter from the 24 volt circuit ?

Are you think that somewhere is a sketch for every task in the world?

No But if a countdown script is already done, why reinvent the wheel?

You may find something that you can use here in this simulation: Traffic Light Countdown - Wokwi ESP32, STM32, Arduino Simulator
This simulator runs at maybe 33% normal speed so some patience is required.
The solution itself is quite crude but may give you a start. It really needs a second Uno in there to simulate the existing traffic lights.

I slightly modified @6v6gt's code to be non-blocking. This allows standing up a traffic lights sequencer beside that code to make a fully automatic demo.

Since life is so short, I severely cut down all the time constants. It should work fine with the numbers changed to reflect real life timing.

In the wokwi, there is one function call in loop() and one in setup() to implement the traffic lights. In the schematic, the squiggly orange wire is the only connection between the countdown stuff and the traffic lights sequencer.

Play with it here:


Wokwi_badge traffic and lights


Code. I had to change the sense of the input to @6v6gt's algorithm. I also notice that just looking at the red light results in some potential flaws arising. Here, for example, I note that the countdown number remains at zero, and on display, during the RED/AMBER period.

// 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");
  }
}

a7