I’m just getting familiar with the Arduino system and I have a problem with timers, which I don’t understand. I know that you can fade in and out an LED with a timer(PWM) very nicely, but here I am concerned with how two timers behave that should actually trigger slightly different.
I have a Mega2560, it has 6 timers. I use timers 3&4, but I have tried 1&3 as well. This had the same success.
Both timers are configured exactly the same.
Both timers have an exact copy of the ISR. The only difference is that one timer addresses port 11 and the other port 12.
I have now made a LED between port 11 and 12. This results in beats when the timers do not run exactly the same speed.
I use for
Timer3 an OCR3A of 99 and
Timer4 an OCR4A of 100.
This causes the LED to fade up and down slowly.
Then I swap the times every 5 seconds. Actually the same beat should appear, but that doesn’t happen to me. In the swapped assignment, the LED then remains at a brightness as if both counters were running EXACTLY the same. Or it slowly becomes light and stays light or it slowly becomes dark and stays dark. Only at the next time the times are changed it runs again.
This happens with me in all pairings.
time3=time4-1 if time4 < approx. 600
If the times are longer it works as expected (starts flickering of course). It also works if the difference between the two times is at least 2.
Why?
I made a Video of it and the sketch is completely under here.
#define ledPin3 12
#define ledPin4 11
const int time3 = 99;
const int time4 = 100;
void setup()
{
pinMode(ledPin3, OUTPUT); // Ausgabe LED festlegen
pinMode(ledPin4, OUTPUT); // Ausgabe LED festlegen
noInterrupts(); // Alle Interrupts temporär abschalten
// Timer 3
TCCR3A = 0;
TCCR3B = 0;
TCNT3 = 0; // Register mit 0 initialisieren
OCR3A = time3; // Output Compare Register vorbelegen
TCCR3B |= (1 << CS32); // 256 als Prescale-Wert spezifizieren
TIMSK3 |= (1 << OCIE3A); // Timer Compare Interrupt aktivieren
// Timer 4
TCCR4A = 0;
TCCR4B = 0;
TCNT4 = 0; // Register mit 0 initialisieren
OCR4A = time4; // Output Compare Register vorbelegen
TCCR4B |= (1 << CS42); // 256 als Prescale-Wert spezifizieren
TIMSK4 |= (1 << OCIE4A); // Timer Compare Interrupt aktivieren
interrupts(); // alle Interrupts scharf schalten
}
// Hier kommt die selbstdefinierte Interruptbehandlungsroutine
// für den Timer Compare Interrupt
ISR(TIMER3_COMPA_vect)
{
TCNT3 = 0; // Register mit 0 initialisieren
digitalWrite(ledPin3, digitalRead(ledPin3) ^ 1); // LED ein und aus
}
ISR(TIMER4_COMPA_vect)
{
TCNT4 = 0; // Register mit 0 initialisieren
digitalWrite(ledPin4, digitalRead(ledPin4) ^ 1); // LED ein und aus
}
void loop()
{
OCR3A = time3; // Output Compare Register vorbelegen
OCR4A = time4; // Output Compare Register vorbelegen
delay (5000);
OCR3A = time4; // Output Compare Register vorbelegen
OCR4A = time3; // Output Compare Register vorbelegen
delay (5000);
}
Edit-Reason: Typo