1

My traffic light code for the Arduino doesn't run. I was wondering if anyone could point out where my issues lie. The red and green LEDs should be on for 15 seconds and the amber on for 5 seconds.

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint-gcc.h>
/*15 second interrupt*/
#define INTERRUPTS 975


/* 
 * col = current colour of light. 
 * 'g', 'a', 'r', 'o'
 */
volatile uint8_t count;
volatile char col;

ISR(TIMER0_OVF_vect)
{
    count++;
    if (count >= INTERRUPTS){
        if (col == 'g'){
            /*switch to amber*/
            col = 'a';
            /*reset counter*/
            count = 0;
            /*timer counter to 171 as we only need 85 clicks for 5s*/
            TCNT0 = 171;
            PORTD = 0b00000010;
        } else if(col == 'a'){
            col = 'r';
            count = 0;
            TCNT0 = 0;
            PORTD = 0b00000100;
        } else if (col == 'r'){
            col = 'o';
            counter = 0;
            TCNT0 = 171;
            PORTD = 0b00000010;
        } else if (col == 'o'){
            col = 'g';
            count = 0;
            TCNT0 = 0;
            PORTD = 0b00000001;
        } else{
            return;
        }
    } else{
        if(col == 'g' || col == 'r'){
            TCNT0 = 0;
        } else if(col == 'a' || col == 'o'){
            TCNT0 = 171;
        }
    }
    return;
}

int main(void)
{
    /* normal mode */
    TCCR0A = 0b00000000;
    /* prescaler = 1024 */
    TCCR0B = 0b00000101;
    /* enable overflow interrupts */
    TIMSK0 = 0b00000001;
    TCNT0 = 0;
    sei();
    /*Initialise output*/
    DDRD = 0b11111111;
    count = 0;
    col = 'g';
    PORTD = 0b00000001;
    while (1){
    }
}
3
#define INTERRUPTS 975

volatile uint8_t count;

if (count >= INTERRUPTS){

count is an 8 bit integer, so the maximum value of it is 255. Therefor count will never be bigger of equal to 975.

Use volatile uint16_t count; instead.

PS instead of messing with the TCNT0 register, I'd use 2 different values of INTERRUPTS to change between 15 and 5 second intervals.

Something like if( count>=975 || ( (col=='g'||col=='r') && count>=325 ) ){

  • How would I time using 2 different values? Won't the 5 second count occur every time so the 15 second interrupt never occurs? – JVDM92 Nov 24 '16 at 16:12
  • Something like if( count>=975 || ( (col=='g'||col=='r') && count>=325 ) ){ – Gerben Nov 24 '16 at 16:22
  • Ok, nice, thanks for the advice. Does everything else look ok, I won't have a board to test it again until Monday. – JVDM92 Nov 24 '16 at 16:28
  • It would be nicer to use an enum rather than a char for the current colour. And then use a switch rather than if () {} else if () .... But those are style points rather than functionality. – Andrew Nov 24 '16 at 16:38
  • Looks okay. Though I'd make it more readable. E.g. use two extra letters and change col to color. – Gerben Nov 24 '16 at 19:08
1

As far that i understand, you set the color using the Ports directly. In case green and red you set PORTD = 0b00000010;

  • Yes, for example to turn on the amber light I directly toggle the port so the amber LED will be turned on. If the color is currently green or red then 0b0000010; will turn on the next LED which is amber in both cases. – JVDM92 Nov 24 '16 at 15:12
  • Ah, yes i see, my fault. – Franklin216 Nov 24 '16 at 15:25
  • Well that's the theory anyway, but it doesn't work for some reason – JVDM92 Nov 24 '16 at 15:52
  • And what does it do instead, is the timer not working, or does the lighth not work? – Franklin216 Nov 25 '16 at 6:48
  • The lights are the issue – JVDM92 Nov 25 '16 at 9:17
1

If you want solution with a timer, I suggest to setup a 35 second cycle (35 = 15+15+5). Then, you will trigger next LED when 0,15,30 seconds passed, and restart cycle at 35 seconds.

Other ways to achieve same effect are: 1. Use classic delay() function.

while (true)
{
    TurnOn(Green);
    delay(15000);
    TurnOn(Red);
    delay(15000);
    TurnOn(Amber);
    delay(5000);
}
  1. use millis() function

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.