Turn LED strip on when cars finish race

Hi.

So background info first:
There are three tracks on which there are LED strips. At the ends of each track is a little bump sensor. Cars go down and hit the bump sensor. Pretty simple.

What I need help with:
I want the LED strip on the track that finishes first to turn green when the car hits the bump, yellow for the track that gets second, and red for last. I need help with the logic for this. I don't need the whole program just some help with the part that checks when the cars finish.

So what have you thought of so far?

this is the function that I run when I start the race, I think I could do a lot of nested if statements to check which cars finish in what order but there has to be a better way. Ends are the bump sensors and the lanes are the led lights.

void race() {

    // Countdown with lights then sets to yellow
    lane1("red");
    lane2("red");
    lane3("red");
    delay(1000);
    lane1("yellow");
    lane2("yellow");
    lane3("yellow");
    delay(1000);
    lane1("green");
    lane2("green");
    lane3("green");
    delay(3000);
    lane1("yellow");
    lane2("yellow");
    lane3("yellow");

    // Checks if cars are fishing
    while (digitalRead(end1, LOW) || digitalRead(end2, LOW) || digitalRead(end3, LOW)) {
    // Help needed here.
    }
}

Check the documentation of digitalRead() - it takes only one parameter, and returns the state of the pin:

Is LOW the state which indicates that a car has finished?

1 Like

Ahh, my bad. My goal for that was to run until all the bump switches were HIGH since that would mean all the cars finished and it didn't need to run anymore. The code inside the while would check which cars finished to in what order to change the LEDs. HIGH means the car has hit the bump switch and finished.

Would this work?

while ((digitalRead(end1)==LOW) || (digitalRead(end3)==LOW) || (digitalRead(end3)==LOW)) {
    //Code to change LED lights in the order that the cars finish
}

I built around your code to have start lights and individual bumpers to signal each lane finish. There is a lot of room for improvement.

Modified to have an order of placing.

// https://forum.arduino.cc/t/turn-led-strip-on-when-cars-finish-race/1175747/

int redLED1 = 5, yellowLED1 = 6, greenLED1 = 7; // LEDs for lane 1
int redLED2 = 8, yellowLED2 = 9, greenLED2 = 10;
int redLED3 = 11, yellowLED3 = 12, greenLED3 = 13;
int end1 = 4, end2 = 3, end3 = 2; // bumper buttons for 1, 2, and 3
int place = 1; // finish order

void setup() {
  Serial.begin(115200); // configure serial monitor

  pinMode(redLED1, OUTPUT); // set redLED1 pin to OUTPUT
  pinMode(yellowLED1, OUTPUT);
  pinMode(greenLED1, OUTPUT);

  pinMode(redLED2, OUTPUT);
  pinMode(yellowLED2, OUTPUT);
  pinMode(greenLED2, OUTPUT);

  pinMode(redLED3, OUTPUT);
  pinMode(yellowLED3, OUTPUT);
  pinMode(greenLED3, OUTPUT);

  pinMode(end1, INPUT_PULLUP); // set end1 pin to INPUT with PULLUP resistor
  pinMode(end2, INPUT_PULLUP);
  pinMode(end3, INPUT_PULLUP);

  welcome(); // call the welcome(); function once
  race(); // call the race(); function once
}

void loop() {
  bumper();
}

void race() {
  // Countdown with lights then sets to yellow
  lane1("red"); // call function lane1(); with red as the argument
  lane2("red");
  lane3("red");
  delay(1000); // wait for one second
  lane1("yellow");
  lane2("yellow");
  lane3("yellow");
  delay(1000);
  lane1("green");
  lane2("green");
  lane3("green");
  delay(3000);
  lane1("yellow");
  lane2("yellow");
  lane3("yellow");
}

void lane1(char color[]) { // recieve an array of characters for the color
  if (color == "red") { // when red is passed to this function
    digitalWrite(redLED1, HIGH); // turn red LED on
    digitalWrite(yellowLED1, LOW); // turn yellow LED off
    digitalWrite(greenLED1, LOW); // turn green LED off
  }
  if (color == "yellow") {
    digitalWrite(redLED1, LOW);
    digitalWrite(yellowLED1, HIGH);
    digitalWrite(greenLED1, LOW);
  }
  if (color == "green") {
    digitalWrite(redLED1, LOW);
    digitalWrite(yellowLED1, LOW);
    digitalWrite(greenLED1, HIGH);
  }
}

void lane2(char color[]) {
  if (color == "red") {
    digitalWrite(redLED2, HIGH);
    digitalWrite(yellowLED2, LOW);
    digitalWrite(greenLED2, LOW);
  }
  if (color == "yellow") {
    digitalWrite(redLED2, LOW);
    digitalWrite(yellowLED2, HIGH);
    digitalWrite(greenLED2, LOW);
  }
  if (color == "green") {
    digitalWrite(redLED2, LOW);
    digitalWrite(yellowLED2, LOW);
    digitalWrite(greenLED2, HIGH);
  }
}

void lane3(char color[]) {
  if (color == "red") {
    digitalWrite(redLED3, HIGH);
    digitalWrite(yellowLED3, LOW);
    digitalWrite(greenLED3, LOW);
  }
  if (color == "yellow") {
    digitalWrite(redLED3, LOW);
    digitalWrite(yellowLED3, HIGH);
    digitalWrite(greenLED3, LOW);
  }
  if (color == "green") {
    digitalWrite(redLED3, LOW);
    digitalWrite(yellowLED3, LOW);
    digitalWrite(greenLED3, HIGH);
  }
}

void bumper() {
  if (place < 4) { // if all lanes finished, no need to read buttons
    while ((digitalRead(end1) == LOW) || (digitalRead(end2) == LOW) || (digitalRead(end3) == LOW)) {
      //Code to change LED lights in the order that the cars finish

      if (!digitalRead(end1)) { // if bumper 1 is pressed
        delay(150);
        digitalWrite(redLED1, HIGH); // light LED 1
        Serial.print("Lane 1 Place: ");
        Serial.println(place++); // increment Place
      }

      if (!digitalRead(end2)) {
        delay(150);
        digitalWrite(redLED2, HIGH);
        Serial.print("Lane 2 Place: ");
        Serial.println(place++);
      }

      if (!digitalRead(end3)) {
        delay(150);
        digitalWrite(redLED3, HIGH);
        Serial.print("Lane 3 Place: ");
        Serial.println(place++);
      }
    }
  }
}

void welcome() {
  Serial.println("Wait for final yellow. Press a button.");
}

diagram.json for wokwi.com

{
  "version": 1,
  "author": "Anonymous maker",
  "editor": "wokwi",
  "parts": [
    { "type": "wokwi-arduino-nano", "id": "nano", "top": 33.6, "left": -0.5, "attrs": {} },
    {
      "type": "wokwi-pushbutton",
      "id": "btn1",
      "top": -61,
      "left": 182.4,
      "attrs": { "color": "green" }
    },
    {
      "type": "wokwi-pushbutton",
      "id": "btn2",
      "top": -109,
      "left": 182.4,
      "attrs": { "color": "green" }
    },
    {
      "type": "wokwi-pushbutton",
      "id": "btn3",
      "top": -157,
      "left": 182.4,
      "attrs": { "color": "green" }
    },
    {
      "type": "wokwi-led",
      "id": "led1",
      "top": -186,
      "left": -149.8,
      "attrs": { "color": "green" }
    },
    {
      "type": "wokwi-resistor",
      "id": "r1",
      "top": -149.65,
      "left": -201.6,
      "attrs": { "value": "330" }
    },
    {
      "type": "wokwi-led",
      "id": "led2",
      "top": -176.4,
      "left": -130.6,
      "attrs": { "color": "yellow" }
    },
    {
      "type": "wokwi-resistor",
      "id": "r2",
      "top": -140.05,
      "left": -201.6,
      "attrs": { "value": "330" }
    },
    {
      "type": "wokwi-led",
      "id": "led3",
      "top": -166.8,
      "left": -111.4,
      "attrs": { "color": "red" }
    },
    {
      "type": "wokwi-resistor",
      "id": "r3",
      "top": -130.45,
      "left": -201.6,
      "attrs": { "value": "330" }
    },
    {
      "type": "wokwi-led",
      "id": "led4",
      "top": -128.4,
      "left": -149.8,
      "attrs": { "color": "green" }
    },
    {
      "type": "wokwi-resistor",
      "id": "r4",
      "top": -92.05,
      "left": -201.6,
      "attrs": { "value": "330" }
    },
    {
      "type": "wokwi-led",
      "id": "led5",
      "top": -118.8,
      "left": -130.6,
      "attrs": { "color": "yellow" }
    },
    {
      "type": "wokwi-resistor",
      "id": "r5",
      "top": -82.45,
      "left": -201.6,
      "attrs": { "value": "330" }
    },
    {
      "type": "wokwi-led",
      "id": "led6",
      "top": -109.2,
      "left": -111.4,
      "attrs": { "color": "red" }
    },
    {
      "type": "wokwi-resistor",
      "id": "r6",
      "top": -72.85,
      "left": -201.6,
      "attrs": { "value": "330" }
    },
    {
      "type": "wokwi-led",
      "id": "led7",
      "top": -70.8,
      "left": -149.8,
      "attrs": { "color": "green" }
    },
    {
      "type": "wokwi-resistor",
      "id": "r7",
      "top": -34.45,
      "left": -201.6,
      "attrs": { "value": "330" }
    },
    {
      "type": "wokwi-led",
      "id": "led8",
      "top": -61.2,
      "left": -130.6,
      "attrs": { "color": "yellow" }
    },
    {
      "type": "wokwi-resistor",
      "id": "r8",
      "top": -24.85,
      "left": -201.6,
      "attrs": { "value": "330" }
    },
    {
      "type": "wokwi-led",
      "id": "led9",
      "top": -51.6,
      "left": -111.4,
      "attrs": { "color": "red" }
    },
    {
      "type": "wokwi-resistor",
      "id": "r9",
      "top": -15.25,
      "left": -201.6,
      "attrs": { "value": "330" }
    }
  ],
  "connections": [
    [ "nano:GND.2", "btn1:2.l", "black", [ "v0" ] ],
    [ "btn1:1.l", "nano:2", "green", [ "h0" ] ],
    [ "nano:GND.2", "btn2:2.l", "black", [ "v0" ] ],
    [ "nano:3", "btn2:1.l", "green", [ "v0" ] ],
    [ "nano:GND.2", "btn3:2.l", "black", [ "v0" ] ],
    [ "led1:C", "r1:2", "green", [ "v0" ] ],
    [ "led2:C", "r2:2", "green", [ "v0" ] ],
    [ "led3:C", "r3:2", "green", [ "v0" ] ],
    [ "led4:C", "r4:2", "green", [ "v0" ] ],
    [ "led5:C", "r5:2", "green", [ "v0" ] ],
    [ "led6:C", "r6:2", "green", [ "v0" ] ],
    [ "led7:C", "r7:2", "green", [ "v0" ] ],
    [ "led8:C", "r8:2", "green", [ "v0" ] ],
    [ "led9:C", "r9:2", "green", [ "v0" ] ],
    [ "nano:4", "btn3:1.l", "green", [ "v0" ] ],
    [ "nano:5", "led3:A", "green", [ "v0" ] ],
    [ "nano:6", "led2:A", "green", [ "v0" ] ],
    [ "nano:7", "led1:A", "green", [ "v0" ] ],
    [ "nano:GND.2", "r9:1", "black", [ "v-38.4", "h-326.4", "v-9.6" ] ],
    [ "r9:1", "r8:1", "green", [ "v0" ] ],
    [ "r8:1", "r7:1", "green", [ "v0" ] ],
    [ "r7:1", "r6:1", "green", [ "v0" ] ],
    [ "r6:1", "r5:1", "green", [ "v0" ] ],
    [ "r5:1", "r4:1", "green", [ "v0" ] ],
    [ "r4:1", "r3:1", "green", [ "v0" ] ],
    [ "r3:1", "r2:1", "green", [ "v0" ] ],
    [ "r2:1", "r1:1", "green", [ "v0" ] ],
    [ "nano:13", "led7:A", "green", [ "v9.6", "h-9.6", "v-134.4" ] ],
    [ "nano:12", "led8:A", "green", [ "v0" ] ],
    [ "nano:11", "led9:A", "green", [ "v0" ] ],
    [ "nano:10", "led4:A", "green", [ "v0" ] ],
    [ "nano:9", "led5:A", "green", [ "v0" ] ],
    [ "nano:8", "led6:A", "green", [ "v0" ] ]
  ],
  "dependencies": {}
}

Briefly:

Initialize a counter to 1.
Initialize each lane's finish position to 0.

In loop(), if a lane's position value is zero check the lane's bump switch. If the switch IS made a, load the counter value to that lane's position value and b, increment the counter. If the switch is NOT made skip the previous two actions.

Continue checking lanes whose position value is zero.

If lane position value is zero its LEDs are off. If not zero, use the position value to select the correct color code to send to the LEDs.

Thanks for the help, I think this will work but I realize I should have provided more background info just so my code makes sense. At the top there are three solenoids, one for each track that is controlled by a single relay. Along the track is an LED strip on each lane. I am only using the Red, Blue and 12v pins and the Red and Blue pins are controlled by relays (this was a bad decision but it wasn't mine to make so I have to deal with it). At the end there are bump sensors on each lane. The entire thing is controlled by a button that starts it. That is the complete setup. This is why I don't have a yellow LED and instead make yellow by turning on green and red. I also added protection against multiple finishers on a single lane since the cars might hit the button and bounce off then hit it again when it rolls back down. I think this will work:

// Button pin
const int button = buttonPin;

// Solenoid Pin
const int solenoid = solenoidPin;

// RGB light Pins
const int red1 = red1Pin; const int green1 = green1Pin; const int end1 = end1Pin; //Lane 1
const int red2 = red2Pin; const int green2 = green2Pin; const int end2 = end2Pin; //Lane 2
const int red3 = red3Pin; const int green3 = green3Pin; const int end3 = end3Pin; //Lane 3

int place = 1;

bool racing = false;
bool lane1Finished = false;
bool lane2Finished = false;
bool lane3Finished = false;

void setup() {
    pinMode(button, INPUT);

    pinMode(solenoid, OUTPUT)
    
    pinMode(red1, OUTPUT);
    pinMode(red2, OUTPUT);
    pinMode(red3, OUTPUT);
    pinMode(green1, OUTPUT);
    pinMode(green2, OUTPUT);
    pinMode(green3, OUTPUT);

    pinMode(end1, INPUT);
    pinMode(end2, INPUT);
    pinMode(end3, INPUT);
}



// Cycles from red to yellow to green then waits for cars to finish.
void race() {

    // Countdown with lights then sets to yellow
    lane1("red");
    lane2("red");
    lane3("red");
    delay(1000);
    lane1("yellow");
    lane2("yellow");
    lane3("yellow");
    delay(1000);
    lane1("green");
    lane2("green");
    lane3("green");
    digitalWrite(solenoid, HIGH);
    delay(3000);
    lane1("yellow");
    lane2("yellow");
    lane3("yellow");
    digitalWrite(solenoid, LOW);

    end();
}

void loop() {
    if ((digitalRead(button) == HIGH) && !(racing)) { //Starts race if not in a race and if start button pushed
        race();
    }
}

void end() {
    if (place < 4) { // if all lanes finished, no need to read buttons
        while ((digitalRead(end1) == LOW) || (digitalRead(end2) == LOW) || (digitalRead(end3) == LOW)) {
            if (!digitalRead(end1) && !(lane1Finished)/*prevents a lane from finishing multiple times*/) {
            if(place==1) {
                lane1("green");
                place++;
            }
            else if(place == 2) {
                lane1("yellow");
                place++;
            }
            else if(place == 3) {
                lane1("red");
                place++;
            }
            lane1Finished = true;
        }

        if (!digitalRead(end2) && !(lane2Finished)) {
            if(place==1) {
                lane2("green");
                place++;
            }
            else if(place == 2) {
                lane2("yellow");
                place++;
            }
            else if(place == 3) {
                lane2("red");
                place++;
            }
            lane2Finished = true;
        }

        if (!digitalRead(end3) && !(lane3Finished)) {
            if(place==1) {
                lane3("green");
                place++;
            }
            else if(place == 2) {
                lane3("yellow");
                place++;
            }
            else if(place == 3) {
                lane3("red");
                place++;
            }
            lane3Finished = true;
        }
    }
  }
}

// Takes color as input and sets lane to color
void lane1(char color[]) {
    if (color == "red") {
        digitalWrite(red1, HIGH);
        digitalWrite(green1, LOW);
    }
    if (color == "yellow") {
        digitalWrite(red1, HIGH);
        digitalWrite(green1, HIGH);
    }
    if (color == "green") {
        digitalWrite(red1, LOW);
        digitalWrite(green1, HIGH);
    }
}
void lane2(char color[]) {
    if (color == "red") {
        digitalWrite(red2, HIGH);
        digitalWrite(green2, LOW);
    }
    if (color == "yellow") {
        digitalWrite(red2, HIGH);
        digitalWrite(green2, HIGH);
    }
    if (color == "green") {
        digitalWrite(red2, LOW);
        digitalWrite(green2, HIGH);
    }
}
void lane3(char color[]) {
    if (color == "red") {
        digitalWrite(red3, HIGH);
        digitalWrite(green3, LOW);
    }
    if (color == "yellow") {
        digitalWrite(red3, HIGH);
        digitalWrite(green3, HIGH);
    }
    if (color == "green") {
        digitalWrite(red3, LOW);
        digitalWrite(green3, HIGH);
    }
}

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