Beginner project "Traffic Lights" code check.

Hello

I just started with Arduino a few days ago . My first project "Traffic Lights" works .
I wanted to take it to a next level by adding a button for pedestrians who wish to cross the road .
This is where I am having troubles . Maby somebody can help me by looking at my code .

int red = 13;
int yellow = 12;
int green = 11;
int redv = 10;
int greenv = 9;
int buttonv =2;

void setup(){
pinMode(red,OUTPUT);
pinMode(yellow,OUTPUT);
pinMode(green,OUTPUT);
pinMode(redv,OUTPUT);
pinMode(greenv,OUTPUT);
pinMode(buttonv,INPUT);
}

void loop(){
changeLights();
delay(500);
}

void changeLights(){
  int knop = digitalRead(buttonv);
  if (knop == LOW){
digitalWrite(redv,HIGH);
delay(500);
digitalWrite(green,HIGH);
digitalWrite(greenv,LOW);
delay(3000);
digitalWrite(green,LOW);
digitalWrite(yellow,HIGH);
delay(2000);


digitalWrite(green,LOW);
digitalWrite(yellow,LOW);
digitalWrite(red,HIGH);
delay(500);
digitalWrite(redv,LOW);
digitalWrite(greenv,HIGH);
delay(3000);
digitalWrite(redv,HIGH);
digitalWrite(greenv,LOW);
delay(500);


digitalWrite(yellow,LOW);
digitalWrite(red,LOW);
digitalWrite(green,HIGH);
  }
  
else {
  digitalWrite(green,HIGH);
  digitalWrite(redv,HIGH);
  digitalWrite(greenv,LOW);
  delay(1000);
  digitalWrite(redv,HIGH);
  digitalWrite(green,LOW);
  digitalWrite(yellow,HIGH);
  digitalWrite(greenv,LOW);
  delay(2000);
  digitalWrite(redv,LOW);
  digitalWrite(yellow,LOW);
  digitalWrite(red,HIGH);
  digitalWrite(greenv,HIGH);
  delay(5000);

}
}

Thank you !

Xorviver:
This is where I am having troubles

What troubles?

changeLights();
delay(500);

"Responsiveness to button presses" kind of troubles, I'm guessing.

Off to read the "blink without delay" example with you, and don't come back until you've read it all.

AWOL:
Off to read the "blink without delay" example with you, and don't come back until you've read it all.

Yes and also, pedestrians can come along at any time. So perhaps even learn about attachInterrupt() for that button press. There are pro's and cons to interrupts, but in the case where there are timed events that must play out... it is a nice way to capture and record the event occurring.

So perhaps even learn about attachInterrupt() for that button press.

Why?
We're talking about people and switches here, not sub-microsecond events.

AWOL:
Why?
We're talking about people and switches here, not sub-microsecond events.

Why not?

we are not talking about 5kLOCs for a simple interrupt. and it is good to learn.

Green for a little bit
Yellow for a little bit
Red for a little bit
if (wasInterrupt)
 walk()

easy as pie and less fattening

Hi again !

Thank you for the replies . I looked into the Blink without Delay code . If I understand correctly it is my delay code that is interupting my if/else code .

Thanks !

PS: I'm going to read about attachInterrupt() tonight.

I'm going to read about attachInterrupt() tonight.

As long as you continue to use delay(), I really don't see how it will help.
You'd be better off working through blink without delay.

I really don't see where 5 kLOCs comes into the argument.

A traffic light controller is a classic example of a finite state machine and is an ideal candidate to be implemented using the sort of non-blocking architecture demonstrated in http://forum.arduino.cc/index.php?topic=223286.0

I certainly wouldn't used interrupts for this problem - it's not necessary, doesn't make the solution any easier to implement and just makes it more complicated. A simple finite state machine is all it needs.

PeterH:
A traffic light controller is a classic example of a finite state machine and is an ideal candidate to be implemented using the sort of non-blocking architecture demonstrated in Demonstration code for several things at the same time - Project Guidance - Arduino Forum

I certainly wouldn't used interrupts for this problem - it's not necessary, doesn't make the solution any easier to implement and just makes it more complicated. A simple finite state machine is all it needs.

Yes, your option is a nice way to learn too.

There are likely many 'best' ways to do it.

learning from alternatives is truly rewarding, it provides a rich understanding of the many approaches possible.

so goes arduino, so goes life.

BulldogLowell:
Why not?

we are not talking about 5kLOCs for a simple interrupt. and it is good to learn.

Priorities, priorities.

A self-confessed "newbie" needs first to learn how to write manageable code. The important concept in this case, is to write the code so that it can manage a number of tasks simultaneously; that is "non-blocking". Whilst blocking code may fulfil the initial requirement, it is by nature, non-extensible and prevents the addition of extra functionality where this is easy if the code is properly written in the first place.

Whilst your suggested use of an interrupt to set a flag is workable, it tends to hide a number of problems. A particular concern is that carries the very misleading implication that an interrupt is somehow an appropriate way to "interrupt" the progress of the main program thread - a question often discussed here.

A second problem which again might not be such a concern in this trivial example, is that of "de-bouncing". Using an interrupt on a switch contact - and indeed certain other inputs - creates not just a single interrupt, but a barrage of interrupts due to contact bounce which must be managed in some way but in doing so actually impedes rather than facilitates the main program thread ("loop"). This leads to inappropriate diversions such as adding quite unnecessary complexity in "hardware de-bouncing" or implementing time-dependent functions into interrupt routines, when this is more simply and reliably performed by polling in the main thread.

The more appropriate guidance is therefore to get the program working using good programming practice, and approach interrupts where and when there is a clear need for them, not just to increase the complexity (and there is necessarily a complexity to using interrupts) of the exercise for academic interest.


As to the traffic light problem proper; the first observation is that some comments - not necessarily too many, but some - would help in viewing this code.

I recently undertook this particular exercise in view of the quite common enquiry as to how to do this - usually for a college project; we should tend to expect the same query at a certain time or times each year corresponding to the semesters. I also used it as demonstration for a talk on Arduino-ology to the radio club.

So far, I have included de-bounce on the button (if only because buttons should always be de-bounced :D) including "stuck button", flashing "Don't Walk" and "anti-chicken" functions. I have yet to include the "plonker" but the code should readily accommodate this and extension to a road intersection with inductive road "trips".

Question: Should I demonstrate it here, now, or should we leave the OP to develop his own a while longer?

Here is my Blink code:

boolean toggle1 = 0;
void setup()
{
  pinMode(13, OUTPUT);
  cli();
  //
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;
  OCR1A = 781;// = (16*10^6) / (1*1024) - 1 (must be <65536)
  TCCR1B |= (1 << WGM12);
  TCCR1B |= (1 << CS12) | (1 << CS10);  
  TIMSK1 |= (1 << OCIE1A);
  sei();
}//end setup

ISR(TIMER1_COMPA_vect)
{
  (toggle1 == true) ? digitalWrite(13,HIGH) : digitalWrite(13,LOW);
  toggle1 = !toggle1;
}

void loop()
{
  
}

and my other blink code:

const int ledPin =  13; 
int ledState = LOW; 
long previousMillis = 0;

long interval = 50;  

void setup() 
{
  pinMode(ledPin, OUTPUT);      
}

void loop()
{
  if(millis() - previousMillis > interval) 
  {
    previousMillis = millis();   
    ledState = !ledState;
    digitalWrite(ledPin, ledState);
  }
}

and my other blink code

const int ledPin =  13; 
int ledState = LOW;  

void setup() 
{
  pinMode(ledPin, OUTPUT);      
}

void loop()
{
  digitalWrite(ledPin, ledState);
  delay(50);
  ledState = !ledState;
}

I learned something writing each one, and they all make my on-board led flash like... well... just like a flashing LED.

I don't have to drive the same way to Albuquerque as you in order to have learned ONE WAY to get there.

no fancy graphic, sorry.

:sleeping:

The second one is the way to go.

The first one looks like gobbledegook; it does some job, but it is making things hard. The whole idea of the Arduino IDE is to make things easy and easy to understand.

And it is using interrupts which is a neat way do do something that has absolutely no relationship to any other part of the code unless you use semaphores in the other direction. It is a "background" task.

Good party trick, but not really useful for the traffic lights.

Paul__B:
The second one is the way to go.

well it certainly is one way to go.

The first one looks like gobbledegook; it does some job, but it is making things hard.

sorry you couldn't understand it, but you did make my point, so thanks.

The second approach is the way to go because it is nice and simple, and introduces an approach which scales up to support extremely complicated behaviour. The third approach is even simpler but leads to a dead end since it does not scale up at all well.

Again thanks for the replies .

@Paul__B : Question: Should I demonstrate it here, now, or should we leave the OP to develop his own a while longer?
I would like to figure it out on my own :slight_smile: I will add button debouncing even if it is not needed in this example ,it seems to be a useful addition for future projects .

@BulldogLowell : Thanks for the example codes . The second one looks like what AWOL told me to read about ( Blink without delay ) so I'll start there .

PS: I'll add some comments to the code . :wink: