timer2 benötigt 4 mal zu lange

Hallo liebe Arduino Community,

dies ist mein erster Forum-Post, deshalb bitte ich um Verzeihung, falls ich irgendwelche Standards nicht einhalte. Weisen Sie mich gerne daraus hin.

Nun zu meiner Frage:
Für ein Projekt brauche ich zwei Timer. Einer der Timer soll erst nach einer halben Stunde, der andere innerhalb von Sekunden ausgelöst werden. Da während die Timer laufen der Arduino nicht blockiert werden soll, möchte ich die Timer-Interrupts nutzen. Für den längeren Timer nutze ich also timer1 und für den kürzeren timer2. Den timer1 habe ich auf 1Hz eingestellt und den timer2 auf 1000Hz. Logischerweise, sollte also timer1 ein Interrupt für eine Sekunde und timer2 1000 Interrupts für eine Sekunde benötigen. Nun funktioniert timer1 einwandfrei, timer2 benötigt hingegen mehr als 4 mal zu lange.

Nach etwas Überlegung kam mir vielleicht die Idee, dass die ISR-Funktion des timer2 zu lange benötigt, doch selbst nach der Ausführung von nur einer Zeile (timer2++;) besteht das Problem ohne Veränderung.

Meine Quelle für die Timer war https://www.instructables.com/id/Arduino-Timer-Interrupts/ .
Den Prescaler und das Compare-Register habe ich mit Arduino Timer Interrupts Calculator berechnet.

Herzliche Grüße und vielen Dank
Habetuz

void startTimer2(int thousendsOfASecond) {
  cli();
  compare2 = thousendsOfASecond;
  timer2 = 0;
  TCCR2A = 0; // set entire TCCR2A register to 0
  TCCR2B = 0; // same for TCCR2B
  TCNT2  = 0; // initialize counter value to 0
  // set compare match register for 1000 Hz increments
  OCR2A = 249; // = 16000000 / (64 * 1000) - 1 (must be <256)
  // turn on CTC mode
  TCCR2B |= (1 << WGM21);
  // Set CS22, CS21 and CS20 bits for 64 prescaler
  TCCR2B |= (1 << CS22) | (0 << CS21) | (0 << CS20);
  // enable timer compare interrupt
  TIMSK2 |= (1 << OCIE2A);
  sei();
}

ISR(TIMER2_COMPA_vect){
  timer2 ++;
}

Für diese langen Zeitabstände brauchst Du keine Timerinterrupts, das kannst Du im loopü mit millis() problemlos nebenbei erledigen. Schau Dir BlinkWithoutDelay in den Beispielen und die Nachtwächtererklärung an oder die MoBaTools.

Gruß Tommy

Meine Quelle für die Timer war https://www.instructables.com/id/Arduino-Timer-Interrupts/ .
Den Prescaler und das Compare-Register habe ich mit Arduino Timer Interrupts Calculator berechnet.

Die richtige Quelle ist das Datenblatt!

Ich mache es extra nochmal in Rot:
Die richtige Quelle ist das Datenblatt!

Und nicht irgendein ungeprüftes Zeugs aus dem Netz.

TCCR2B |= (1 << WGM21); // blödsinn
TCCR2A |= (1 << WGM21); // besser

habetuz:
.. Einer der Timer soll erst nach einer halben Stunde, der andere innerhalb von Sekunden ausgelöst werden. Da während die Timer laufen der Arduino nicht blockiert werden soll, möchte ich die Timer-Interrupts nutzen. ...

Wie Tommy schreibt, sind Interrupts für derlei Zeiträume nicht nötig. Um in loop() mit millis() blockadefrei zu programmieren, guckst Du am besten das Modell des endlichen Automaten an.

Gruß

Gregor

gregorss:
Um in loop() mit millis() blockadefrei zu programmieren, guckst Du am besten das Modell des endlichen Automaten an.

Ein endlicher Automat hat aber nichts mit blockadefreier Programmierung zu tun. Man kann auch so einen Automaten mit delay's realisieren.
Wesentlicher ist das von Tommy angesprochene Beispiel 'BlinkWithoutDelay'. Das man das dann auch inmnerhalb eines Automaten verwenden kann ( und sollte ), um ihn blockadefrei zu machen, ist eine andere Geschichte.

MicroBahner:
Ein endlicher Automat hat aber nichts mit blockadefreier Programmierung zu tun. Man kann auch so einen Automaten mit delay's realisieren.

Das mag ja sein. Das Modell des endlichen Automaten halte ich hier aber wie bei vielen anderen Sachen für die beste und flexibelste aller Möglichkeiten, das zu realisieren, was der OP möchte.

Gruß

Gregor

Vielen Dank an Alle.

Da ich in meinem Projekt auch Digital-Pin-Interrupts nutze, hatte ich die Idee auch Zeit-Interrupts zu nutzen und war deshalb völlig blind für andere Lösungen.

Ich habe mein Programm jetzt mit einer Timer-Klasse, die millis() nutzt, erweitert und so funktoniert auch alles einwandfrei und viel unkomplizierter.

Grüße
Habetuz

habetuz:
Da ich in meinem Projekt auch Digital-Pin-Interrupts nutze

Auch externe Interrupts werden von Anfängern gerne verwendet wenn es gar nicht nötig ist. Taster oder Schalter z.B. fragt man nicht mit Interrupts ab, da das sehr langsam abläuft.

Hi

Und ein Prellen zu extremer Belastung führt - jedes 'Zucken' am Eingangspin löst den Interrupt aus - Das kann sehr viel Rechenlast ins System spülen.
Beim Pollen schaut man einfach, ob der letzte Wechsel länger als die Prellzeit her ist und zählt dann hoch, sonst macht man - Nichts.

MfG