7 segment timer for traffic lights

I saw a code of a 7 segment display timer for a traffic lights. The previous state the person made use to a button which when press will show a timer for the red light then after counting it will go back to the green light. So I modified it so as not to make use of a button but to display the timer automatic. But the problem I'm facing now is that I'm finding it hard for the timer to count for the red light then yellow then green light. Help me please thanks

const int buttonPin = 1;
const int clock = 2;
const int data = 3;
const uint8_t red = 12;
const uint8_t green = 13;
const uint8_t yellow = 11; 
const unsigned long sprintDuration = 15000; // change time
const unsigned long sprintDurations = 20000;
uint8_t digits[] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f }; 
int i;
int state=0;
void setup() 
{
  pinMode(buttonPin, INPUT);
  pinMode(clock, OUTPUT);
  pinMode(data, OUTPUT);
  pinMode(red, OUTPUT);
  pinMode(green, OUTPUT);
  pinMode(yellow, OUTPUT);
  setupInterrupt();
  start();
  writeValue(0x8f);
  stop();
  write(0x00, 0x00, 0x00, 0x00);
}

byte tcnt2;
unsigned long time = 0;
unsigned long tm = 0;
void setupInterrupt()
{
  TIMSK2 &= ~(1<<TOIE2);    
  TCCR2A &= ~((1<<WGM21) | (1<<WGM20));   
  TCCR2B &= ~(1<<WGM22);     
  ASSR &= ~(1<<AS2);  
  TIMSK2 &= ~(1<<OCIE2A);    
  TCCR2B |= (1<<CS22)  | (1<<CS20); 
  TCCR2B &= ~(1<<CS21); 
  tcnt2 = 131;     
  TCNT2 = tcnt2;   
  TIMSK2 |= (1<<TOIE2);   
}
ISR(TIMER2_OVF_vect) {   
  TCNT2 = tcnt2; 
  if(time > 0)
  {
    time--;
  }
  else if (time == 0){
    time = sprintDuration; 
  } 
}
void loop() 
{
  displayTime();
}
void displayTime()
{
 unsigned long t = (unsigned long)(time/1000);  
  uint8_t minutes = (byte)((t / 60) % 60);
  uint8_t seconds = (byte)(t % 60);
  switch (state)
  {
    case 0:
     digitalWrite(red, HIGH);
    digitalWrite(green, LOW);
    digitalWrite(yellow, LOW);
    case 1:
    digitalWrite(red, LOW);
    digitalWrite(green, HIGH);
    digitalWrite(yellow, LOW);
    break;
    default:
    break;
  }
  
   write(digits[minutes / 10], digits[minutes % 10] | ((seconds & 0x01) << 7) , digits[seconds / 10], digits[seconds % 10]);
}
void write(uint8_t first, uint8_t second, uint8_t third, uint8_t fourth)
{
  start();
  writeValue(0x40);
  stop();  
  start(); 
  writeValue(0xc0);
  writeValue(first);
  writeValue(second);
  writeValue(third);
  writeValue(fourth);

  stop();
}
void start()
{
  digitalWrite(clock,HIGH);
  digitalWrite(data,HIGH);
  delayMicroseconds(5);
  
  digitalWrite(data,LOW); 
  digitalWrite(clock,LOW); 
  delayMicroseconds(5);
} 
void stop()
{
  digitalWrite(clock,LOW);
  digitalWrite(data,LOW);
  delayMicroseconds(5);
  
  digitalWrite(clock,HIGH);
  digitalWrite(data,HIGH); 
  delayMicroseconds(5);
}
bool writeValue(uint8_t value)
{
  for(uint8_t i = 0; i < 8; i++)
  {
    digitalWrite(clock, LOW);
    delayMicroseconds(5);   
    digitalWrite(data, (value & (1 << i)) >> i);
    delayMicroseconds(5);
    digitalWrite(clock, HIGH);
    delayMicroseconds(5);
  } 
  digitalWrite(clock,LOW);
  delayMicroseconds(5);   
  pinMode(data,INPUT);
  digitalWrite(clock,HIGH);     
  delayMicroseconds(5);   
  bool ack = digitalRead(data) == 0;
  pinMode(data,OUTPUT); 
  return ack;
}
  switch (state)
  {
    case 0:
      digitalWrite(red, HIGH);
      digitalWrite(green, LOW);
      digitalWrite(yellow, LOW);
    case 1:
      digitalWrite(red, LOW);
      digitalWrite(green, HIGH);
      digitalWrite(yellow, LOW);
      break;

There is no break; at the end of case 0 so the code for case 1 will be executed as well when case 0 is true

Once it's true it only execute the red light only without the green light showing

Because you have no break; at the end of case 0, when state is zero your code does this

switch (state)
  {
    case 0:
      digitalWrite(red, HIGH);
      digitalWrite(green, LOW);
      digitalWrite(yellow, LOW);
      digitalWrite(red, LOW);
      digitalWrite(green, HIGH);
      digitalWrite(yellow, LOW);
      break;

Is that what you want it to do ?

I will try it to see if it will work

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.