I am building a traffic light controller without using delay(). I am planning to use either timer or hardware interrupts - I am not sure which would be appropriate for this project.
For the traffic controller lab, we need to use interrupts to cause the following:
Green LED for 6 seconds
Yellow LED for 2 seconds
Red LED for 8 seconds
I am using the ATMEGA 328P on the NANO, which has three timer-counters (TCNT0/1/2). I know how to write code to set up the interrupt (pre-scaler, mode, ISR) but I am unsure on how I can use it for the above application.
Must I use all three timers for the three LEDs, or can just one timer suffice?
How can I program it so that the interrupt for one LED is called right after another LED? Should I think of this as a frequency problem ?
Perhaps most importantly, should I even bother to use timer/ counters? Is this task more geared towards hardware interrupts?
+1
In this project, tasks are executed strictly one after another, there are no competitive processes.
Therefore the project don't need even millis, it can be happily developed with delays.
And it definitely don't need hardware timers and interrupts.
Deeply appreciate the prompt responses. I am sorry - I should have mentioned that I plan to have other tasks running in the background. That's why I need interrupts and not delay().
This task is a precursor to a bigger project. I am building a home security system with a bunch of PIR and ultrasonic sensors. There's a matrix keypad for password entry. There's an alarm (buzzer) that goes off along with a red LED flashing. Green LED shows the system is disarmed. Yellow LED shows the system is armed.
I am a bit of a beginner, but don't we need interrupts at one point ? Do let me know
The below code is to set up a single timer interrupt mechanism for a single LED. I am trying to get it for three LEDs.
const int led_pin = PB5 ;// pin D13 on the NANO is PB5 on ATMEGA328P
const int led_pin2 = PB0; // pin D8 on the NANO is PB0 on ATMEGA328P
const uint16_t t1_load = 0;
const uint16_t t1_comp = 31250; // for a time period of 0.5 s (aka f = 2Hz)
void setup() {
// put your setup code here, to run once:
// set pin to be output
DDRB |= (1 << led_pin);
//disable all interrupts for now
//cli();
// reset timer1 control reg. A
TCCR1A = 0;
//TCCR1B =0;
// set prescalers to 1024
TCCR1B =TCCR1B | (1<<CS12); //& ~(1<<CS11) &~(1<<CS10);
TCCR1B &= ~(1<<CS11);
TCCR1B &= ~(1<<CS10);
// set timer to zero, and store max value in OCR
TCNT1 = t1_load;
OCR1A = t1_comp;
// enable timer1 compare interrupt
TIMSK1 = (1 <<OCIE1A);
// enable all interrupts
sei();
}
void loop() {
// put your main code here, to run repeatedly:
// green();
// yellow();
// red();
// use XOR to toggle
//PORTB ^= (1<< led_pin);
delay(500);
}
ISR(TIMER1_COMPA_vect){
//reset TCNT to zero
TCNT1 = t1_load;
//toggle
PORTB ^= (1<< led_pin);
}
//const int led = PB5;
// void setup() {
// // set PINB5 (ATMEGA) to OUTPUT
// DDRB |= (1<<PB5);
// }
// void loop() {
// // toggle
// PORTB ^= (1<<PB5);
// delay(500);
// }
Thank you Jackson, I shall look into this. I only hope that your suggestions will also apply when I get into building the bigger project (see later post). Many peripherals are going to attached... hope that won't slow anything down.
thanks. I understand there will be no competitive processes. However, for my bigger project (home security system - see later post), instead of continuously polling many sensors and the matrix keypad inside loop(), is it not better to use interrupts?
Take a step back and think about the requirements and constraints
Do you intend to put the microcontroller to sleep much of the time because for example it’s all battery operated and you want to save as much as you can?
If not - What will your code be doing whilst nothing is happening?
How fast does the system need to react ie do the events you track are super short - a few microseconds or are do the signal last tens of ms?