SCS
SCS

Reputation: 121

Light doesn't switch properly

I am using an Arduino UNO for a traffic lamp project for my school. I'm using a 4 way relay to switch 240V lamps on and off. The problem is that the lamps don't switch after a certain amount of time. I think the problem is in my code because the led on my relay doesn't switch either.

int red = 12;
int yellow = 11;
int green = 10;

int timer = 0;

int light = 0;

void setup(){
  pinMode(red, OUTPUT);
  pinMode(yellow, OUTPUT);
  pinMode(green, OUTPUT);

  digitalWrite(red, HIGH);
  digitalWrite(yellow, HIGH);
  digitalWrite(green, HIGH);

  light = 1;
  timer = 9;
}

void loop(){
  if(timer == 0){
    nextlight();
  }
  if(timer >= 0){
    timer = timer - 1;
  }

  if(light == 1){
    digitalWrite(yellow, HIGH);
    digitalWrite(green, HIGH);
    delay(50);
    digitalWrite(red, LOW);
  }
  if(light == 2){
    digitalWrite(red, HIGH);
    digitalWrite(green, HIGH);
    delay(50);
    digitalWrite(yellow, LOW);
  }
  if(light == 3){
    digitalWrite(red, HIGH);
    digitalWrite(yellow, HIGH);
    delay(50);
    digitalWrite(green, LOW);
  }

   delay(1000);
}

void nextlight(){
  if(light == 1){
    light = 2;
    timer = 2;
  }
  if(light == 2){
    light = 3;
    timer = 9;
  }
  if(light == 3){
    light = 1;
    timer = 9;
  }
}

Edit: I tried to debug using the light at pin 13, it seems that the program doesnt loop at all. I really dont know why.

Upvotes: 0

Views: 67

Answers (2)

handle
handle

Reputation: 6309

Not the solution, but maybe of help: "simulating" your code gives this sequence, each line shows the state when an output is written with digitalWrite():

Timer, light, yellow, green, red

8 1 HIGH HIGH HIGH
8 1 HIGH HIGH HIGH
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW
8 1 HIGH HIGH LOW

Compare this to what you expect to happen.

Here's the "simulator" (Python)

HIGH = "HIGH"
LOW = "LOW"
yellow = 0
green = 1
red = 2
lights = [HIGH, HIGH, HIGH]


timer = 9
light = 1


def digitalWrite(thelight, newstate):
    lights[thelight] = newstate
    print("{:2} {} {}".format(timer, light, " ".join(lights)))


def nextlight():
    #global light
    if light == 1:
        light = 2
        timer = 2

    if light == 2:
        light = 3
        timer = 9

    if light == 3:
        light = 1
        timer = 9


for n in range( 20 ):
    if timer == 0:
        nextlight()

    if timer >= 0:
        timer = timer - 1

    if light == 1:
        digitalWrite(yellow, HIGH)
        digitalWrite(green, HIGH)
        digitalWrite(red, LOW)

    if light == 2:
        digitalWrite(red, HIGH)
        digitalWrite(green, HIGH)
        digitalWrite(yellow, LOW)

    if light == 3:
        digitalWrite(red, HIGH)
        digitalWrite(yellow, HIGH)
        digitalWrite(green, LOW)

    timer += 1

Maybe you can port your code to JavaScript in a similar fashion (even with delay()s), as it is already built into your browser (so you can run it online, e.g. JSFiddle.com etc.) and the syntax is somewhat similar to C++.


Updated previously missing last condition in nextlight(). See imjosh's answer for some good hints.

Upvotes: 0

imjosh
imjosh

Reputation: 4872

Look at your nextLight function. light will always be 1 which is why it isn't switching.

void nextlight(){
  if(light == 1){
    light = 2;
    timer = 2;
  }
  if(light == 2){
    light = 3;
    timer = 9;
  }
  if(light == 3){
    light = 1;
    timer = 9;
  }
}

So, if light == 1, light = 2. Then, if light == 2, light = 3. Then, if light == 3... light = 1 and then the function returns. So no matter what, light is always 1.

So, you either need some else ifs or just return inside each block which is what I think I'd do:

void nextlight(){
  if(light == 1){
    light = 2;
    timer = 2;
    return;
  }
  if(light == 2){
    light = 3;
    timer = 9;
    return;
  }
  if(light == 3){
    light = 1;
    timer = 9;
    return;
  }
}

You have the same problem here which will mess up your timing a bit:

  if(timer == 0){
    nextlight();
  }
  if(timer >= 0){
    timer = timer - 1;
  }

So, this instead:

  if(timer == 0){
    nextlight();
  }
  else {
    timer = timer - 1;
  }

Upvotes: 3

Related Questions