Ultrasonic Traffic-Light

I've been having some trouble with this "Ultrasonic Traffic-Light" and can't figure out why. I've browsed through forums, but can't find any that helps so decided to ask by a forum myself.

const int trig = 3;
const int echo = 4;

int stop = 0;
int slow = 1;
int go= 2;

long duration;
int distance;


void setup() {
  
  pinMode(stop, OUTPUT);
  pinMode(slow, OUTPUT);
  pinMode(go, OUTPUT);
 
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
  Serial.begin(9600);
  
  
}

void loop() {
  digitalWrite(trig, LOW);
  delay(10);
  digitalWrite(trig, HIGH);
  delay(10);
  digitalWrite(trig, LOW);

  duration = pulseIn(echo, HIGH);
  distance = duration*0.034/2;

  Serial.print("DISTANCE: ");
  Serial.println(distance);
  
  if(distance > 105){
    digitalWrite(go, HIGH);
    digitalWrite(stop, LOW);
  
  }
  else(digitalWrite(stop, HIGH)); {
    

  
  }

}

I just can get the red led (stop) to turn of when the green led(go) is on. The green led works as intended, it's just the red one that I'm having trouble with. Any help is appreciated.

Please post schematics. A wiring mistake can never be handle by the code.

1 Like

Try with

if(distance > 105){
    digitalWrite(go, HIGH);
    digitalWrite(stop, LOW);
} else {
    digitalWrite(go, LOW);
    digitalWrite(stop, HIGH);
}

You could use functions to make the code more readable and an enum to describe the state of the system. Something like

const byte trigPin = 3;
const byte echoPin = 4;

const byte redPin = 5;
const byte yellowPin = 6;
const byte greenPin = 7;

const float goThreshold = 105.0;
const float slowThreshold = 50.0;

enum State { STOP, SLOW, GO };
State state = STOP;

float distance() {
  long duration;
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  duration = pulseIn(echoPin, HIGH, 20000);
  return duration * 0.034 / 2.0;
}

void setLights() {
  digitalWrite(redPin, (state == STOP) ? HIGH : LOW);
  digitalWrite(yellowPin, (state == SLOW) ? HIGH : LOW);
  digitalWrite(greenPin, (state == GO) ? HIGH : LOW);
}

void setup() {
  pinMode(redPin, OUTPUT);
  pinMode(yellowPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  setLights();
}

void loop() {
  float dist = distance();
  State newState;

  if (dist > goThreshold) {
    newState = GO;
  } else if (dist > slowThreshold) {
    newState = SLOW;
  } else {
    newState = STOP;
  }

  if (newState != state) {
    state = newState;
    setLights();
  }

  delay(50);
}
1 Like

Hi, @hhhmsroboticsclub
Welcome to the forum.

What Arduino controller are you using?

Have you looked a NewPing library to do your range finding?

https://docs.arduino.cc/libraries/newping/

Tom.... :smiley: :+1: :coffee: :australia:

It worked, but I would've liked if you could label your stuff, similar to what you recommended. I say this because I would've liked to figure out what you did differently. Otherwise, thanks so much for your help!

Compare your code with @J-M-L 's and you'll notice what he did differently.

At least that's what I do, and it works for me.

I add:
To see if it helps you, I'm leaving you the code of @J-M-L commented by Copilot

// Define ultrasonic sensor pins
const byte trigPin = 3;     // Trigger pin for the ultrasonic sensor
const byte echoPin = 4;     // Echo pin for the ultrasonic sensor

// Define LED pins for traffic light simulation
const byte redPin = 5;      // Red LED pin (STOP)
const byte yellowPin = 6;   // Yellow LED pin (SLOW)
const byte greenPin = 7;    // Green LED pin (GO)

// Define distance thresholds in centimeters
const float goThreshold = 105.0;    // Distance above which the light turns green
const float slowThreshold = 50.0;   // Distance above which the light turns yellow

// Define traffic light states
enum State { STOP, SLOW, GO };
State state = STOP;         // Initial state is STOP

// Function to measure distance using the ultrasonic sensor
float distance() {
  long duration;

  // Send a 10µs pulse to trigger the sensor
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Measure the time it takes for the echo to return (timeout after 20ms)
  duration = pulseIn(echoPin, HIGH, 20000);

  // Convert duration to distance in centimeters
  return duration * 0.034 / 2.0;
}

// Function to update LED states based on current traffic state
void setLights() {
  digitalWrite(redPin, (state == STOP) ? HIGH : LOW);     // Turn on red LED if STOP
  digitalWrite(yellowPin, (state == SLOW) ? HIGH : LOW);  // Turn on yellow LED if SLOW
  digitalWrite(greenPin, (state == GO) ? HIGH : LOW);     // Turn on green LED if GO
}

// Arduino setup function (runs once at startup)
void setup() {
  // Set LED pins as outputs
  pinMode(redPin, OUTPUT);
  pinMode(yellowPin, OUTPUT);
  pinMode(greenPin, OUTPUT);

  // Set ultrasonic sensor pins
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  // Initialize LEDs based on initial state
  setLights();
}

// Arduino loop function (runs repeatedly)
void loop() {
  float dist = distance();   // Measure current distance
  State newState;

  // Determine traffic light state based on distance
  if (dist > goThreshold) {
    newState = GO;
  } else if (dist > slowThreshold) {
    newState = SLOW;
  } else {
    newState = STOP;
  }

  // Update state and LEDs only if the state has changed
  if (newState != state) {
    state = newState;
    setLights();
  }

  delay(50);  // Small delay to reduce flickering and CPU load
}

cool thanks! :smiley:

Curious to understand why this is solved by post 5…

Did you end up rewriting your code with that library ?


Can you explain what you don’t understand in my code ?

My bad, I accidentally clicked solution on the wrong one. Your's did work and I appreciate your help! (:smile: