Traffic light sketch needs a little help

I hope I uploaded the code correctly, If not my appologies....

I want the green led to be on, unless the IR detector detects something. Once the IR is triggered, the green led should go out and after a second the red led should come on for 5 seconds. after 1 second, the yellow led should come on and stay for 5 seconds, then after a 1 second delay, the yellow led should go off and the green led come back on. This should run in a loop.

I have included my code below. The red and yellow leds lights as they should and cycle through. However the green led ONLY comes on when the cycle goes through and stays lit when the IR is triggered.

Any suggestions as to how to fix the code? Thanks in advance for your help.

// Define pin numbers
const int greenLEDPin = 2;
const int yellowLEDPin = 3;
const int redLEDPin = 4;
const int irSensorPin = 5;

void setup() {
// Initialize the LED pins as outputs
pinMode(greenLEDPin, OUTPUT);
pinMode(yellowLEDPin, OUTPUT);
pinMode(redLEDPin, OUTPUT);

// Initialize the IR sensor pin as input
pinMode(irSensorPin, INPUT);

// Start with the green LED on
digitalWrite(greenLEDPin, HIGH);
digitalWrite(yellowLEDPin, LOW);
digitalWrite(redLEDPin, LOW);
}

void loop() {
// Check if the IR sensor is triggered
if (digitalRead(irSensorPin) == HIGH) {
// Turn off the green LED
digitalWrite(greenLEDPin, LOW);
delay(500); // Wait for 0.5 seconds

// Turn on the red LED
digitalWrite(redLEDPin, HIGH);
delay(5000); // Wait for 5 seconds

// Turn off the red LED
digitalWrite(redLEDPin, LOW);
delay(500); // Wait for 0.5 seconds

// Turn on the yellow LED
digitalWrite(yellowLEDPin, HIGH);
delay(5000); // Wait for 5 seconds

// Turn off the yellow LED
digitalWrite(yellowLEDPin, LOW);
delay(500); // Wait for 0.5 seconds

// Turn on the green LED
digitalWrite(greenLEDPin, HIGH);

}
}
````Use code tags to format code for the forum`

// Define pin numbers
const int greenLEDPin = 2;
const int yellowLEDPin = 3;
const int redLEDPin = 4;
const int irSensorPin = 5;

void setup() {
  // Initialize the LED pins as outputs
  pinMode(greenLEDPin, OUTPUT);
  pinMode(yellowLEDPin, OUTPUT);
  pinMode(redLEDPin, OUTPUT);
  
  // Initialize the IR sensor pin as input
  pinMode(irSensorPin, INPUT);
  
  // Start with the green LED on
  digitalWrite(greenLEDPin, HIGH);
  digitalWrite(yellowLEDPin, LOW);
  digitalWrite(redLEDPin, LOW);
}

void loop() {
  // Check if the IR sensor is triggered
  if (digitalRead(irSensorPin) == HIGH) {
    // Turn off the green LED
    digitalWrite(greenLEDPin, LOW);
    delay(500); // Wait for 0.5 seconds
    
    // Turn on the red LED
    digitalWrite(redLEDPin, HIGH);
    delay(5000); // Wait for 5 seconds
    
    // Turn off the red LED
    digitalWrite(redLEDPin, LOW);
    delay(500); // Wait for 0.5 seconds
    
    // Turn on the yellow LED
    digitalWrite(yellowLEDPin, HIGH);
    delay(5000); // Wait for 5 seconds
    
    // Turn off the yellow LED
    digitalWrite(yellowLEDPin, LOW);
    delay(500); // Wait for 0.5 seconds
    
    // Turn on the green LED
    digitalWrite(greenLEDPin, HIGH);
  }
}

the green led comes on for a split second and then the yellow and red cycle through. don't know if this helps either. The green led will stay on constant if the IR is triggered

Thanks for using CODE TAGS- almost !
@amelia2011 fixed the code block.

Traffic lights are a great project for learning, not simple, but can get really complex really fast !

The key issues to be aware of are sensor/switch debouncing, non-blocking code (using millis), and getting into state machines.

Good luck :+1:

What is your expectation?
How should the programme work correctly?

// Define pin numbers
const int greenLEDPin = 2;
const int yellowLEDPin = 3;
const int redLEDPin = 4;
const int irSensorPin = 5;

void setup() {
  // Initialize the LED pins as outputs
  pinMode(greenLEDPin, OUTPUT);
  pinMode(yellowLEDPin, OUTPUT);
  pinMode(redLEDPin, OUTPUT);
  
  // Initialize the IR sensor pin as input
  pinMode(irSensorPin, INPUT);
  
  // Start with the green LED on
  digitalWrite(greenLEDPin, HIGH);
  digitalWrite(yellowLEDPin, LOW);
  digitalWrite(redLEDPin, LOW);
}

void loop() {
  // Check if the IR sensor is triggered
  if (digitalRead(irSensorPin) == HIGH) {
    // Turn off the green LED
    digitalWrite(greenLEDPin, LOW);
    delay(500); // Wait for 0.5 seconds
    
    // Turn on the red LED
    digitalWrite(redLEDPin, HIGH);
    delay(5000); // Wait for 5 seconds
    
    // Turn off the red LED
    digitalWrite(redLEDPin, LOW);
    delay(500); // Wait for 0.5 seconds
    
    // Turn on the yellow LED
    digitalWrite(yellowLEDPin, HIGH);
    delay(5000); // Wait for 5 seconds
    
    // Turn off the yellow LED
    digitalWrite(yellowLEDPin, LOW);
    delay(500); // Wait for 0.5 seconds
  }
  else
  {    
    // Turn on the green LED -- won't hurt if already on
    digitalWrite(greenLEDPin, HIGH);
  }
}

The program should start with a green light. It should always be on, unless the IR detector is triggered. Once it is triggered, the Red light should come on for 5 seconds and go. After 1 second, the Yellow light should come on for 5 seconds and go off, then after 1 second, the green light should come on and stay on until triggered again by the IR detector.

Thank you for any help you may be able to offer.

IR sensor doesn't bounce and the rest doesn't matter in this case.

See post 6. As long as the IR sensor is triggered It goes through the red and yellow, else it shows green.

1 Like

BUT, they ere prone to counting multiple edges as they go in and out of each state, unless the sensor has its own internal ‘(hysterical😱) edge cleaner’’.

This isn’t perfect, but can reduce mis-triggering in specific use-cases.

1 Like

Thank you for the sketch. I tried it as you sent it, but the sketch still only operates the red and yellow, going back and forth between the two... UNLESS, I trigger the IR sensor for 5 seconds or so. Then the green led comes on and stays on as long as the IR is triggered... as soon as I take my hand away from it, it goes back to cycling between the red and yellow.

It should always be green, UNTIL the IR detector is triggered. Then the sequence should start red, then yellow. then back to green.

Thank you for your help, it is greatly appreciated.

What IR sensor are you using? Part number, photo?

1 Like

Not sure if it uploaded or not, but it is one of the small blue IR detectors with the clear and black leds with the 3 pins. They are on Amazon. Hope this helps

  // Check if the IR sensor is triggered
  if (digitalRead(irSensorPin) == HIGH) {

What happens if you change that HIGH to LOW?

I am not so sure, I don't know where you put your hand.

That sensor is IR-reflect and may blink at high frequency.
How did you test the sensor?

1 Like

Apparently that kind of IR detector has a LOW output when it is triggered. It's HIGH when there's no signal. So test for == LOW, not == HIGH.

And just to throw a cat in among the chickens, try this:

// Define pin numbers
const int greenLEDPin = 2;
const int yellowLEDPin = 3;
const int redLEDPin = 4;
const int irSensorPin = 5;

const int onTime = 5000;
const int offTime = 500;

typedef enum {
   GREEN,
   TURNING_RED,
   RED,
   TURNING_YELLOW,
   YELLOW,
   TURNING_GREEN
} LightState;

LightState lightState;

unsigned long changed = 0;

void setup() {
   // Initialize the LED pins as outputs
   pinMode(greenLEDPin, OUTPUT);
   pinMode(yellowLEDPin, OUTPUT);
   pinMode(redLEDPin, OUTPUT);

   // Initialize the IR sensor pin as input
   pinMode(irSensorPin, INPUT);

   // Start with the green LED on
   lightState = GREEN;
   digitalWrite(greenLEDPin, HIGH);
   digitalWrite(yellowLEDPin, LOW);
   digitalWrite(redLEDPin, LOW);
}

void loop() {
   switch( lightState ) {
      
      case GREEN:
         // Check if the IR sensor is triggered
         if( digitalRead(irSensorPin) == LOW ) {
            // Turn off the green LED
            digitalWrite(greenLEDPin, LOW);
            lightState = TURNING_RED;
            changed = millis();
         }
         break;
         
      case TURNING_RED:
         if( millis() - changed > offTime ) {
            // Turn on the red LED
            digitalWrite(redLEDPin, HIGH);
            lightState = RED;
            changed = millis();
         }
         break;
         
      case RED:
         if( millis() - changed > onTime ) {
            // Turn off the red LED
            digitalWrite(redLEDPin, LOW);
            lightState = TURNING_YELLOW;
            changed = millis();
         }
         break;
         
      case TURNING_YELLOW:
         if( millis() - changed > offTime ) {
            // Turn on the yellow LED
            digitalWrite(yellowLEDPin, HIGH);
            lightState = YELLOW;
            changed = millis();
         }
         break;
         
      case YELLOW:
         if( millis() - changed > onTime ) {
            // Turn off the yellow LED
            digitalWrite(yellowLEDPin, LOW);
            lightState = TURNING_GREEN;
            changed = millis();
         }
         break;
         
      case TURNING_GREEN:
         if( millis() - changed > offTime ) {
            // Turn on the green LED
            digitalWrite(greenLEDPin, HIGH);
            lightState = GREEN;
         }
         break;
   }
}

Please note that if the IR signal is still active when TURNING_GREEN changes to GREEN, the green LED will only be on for an instant before turning off as TURNING_RED is immediately entered.

The addition of an additional state (or would it be states? would there be any?) to keep the green LED on for a minimum period is left as an exercise for the student. <insert evil grin>

1 Like

That would be so much slower than contact switch bounce and only happen in certain conditions where yes, a very long stable state time (compared to 2 to 20 ms) would be required between changes.
IMO testing the working sensor and sensed to get the real would be the best thing to do. Much would depend on just what one wants to detect, for example; pits or dots on a turning wheel.

1 Like

I have understood the LED sequence.

And what is it about your sketch that doesn't work the way you wanted it to?

1 Like

I appreciate your experience and input here, but in my experience - using opto ‘sensors’, they don’t bounce as such, but background mechanical vibration can easily cause repeat triggers at the transition point.

This appears to be the schematic of the IR module the OP is using.

Vibration that would be special case as to not reflect then reflect again which I have yet to see but I can see how that could happen.

I am more wondering about holding a hand in the way... is that reflecting IR to the sensor or just blocking the IR? I did notice the turn pot on the board for adjusting sensitivity.

1 Like

The sensors have worked well with the other sketches. I am wondering if this sketch has the sensor triggered as a LOW, instead of HIGH.