Arduino UNO (ATmega328P) + Watchdog -> Pause funktioniert in Loop nicht?

OP #5157065
Lesenswert?
• ▲
▼
Hallo!

Ich hab ein ganz ganz misteriöses Problem:
Ich hab mir eine Routine gebastelt, die den uC für x Sekunden in 
Tiefschlaf legt. Das funktioniert ganz prächtig, auch beliebig oft 
hintereinander.
(gibt ja genug Code-Beispiele im Netz)

Wenn ich aber die Funktion in einer Schleife mehrmals hintereinander 
aufrufe, dann macht der uC entweder gar keine Pause oder hängt fest.

Hier ein kurzes Beispiel.
Wenn man die Zeile "for (int i=..." auskommentiert, dann macht der uC 
ganz brav seine Pausen. Mit der Schleife aktiv hängt er sich auf.

HILFE!
Danke!
1
#define pinLED 13
2

3
#define CSleep2Seconds  0b00000111  // 1<<WDP0 | 1<<WDP1 | 1<<WDP2
4

5
void setup()
6
{
7
    pinMode(pinLED, OUTPUT);
8
}
9

10
void loop()
11
{
12
    // If you comment out the line below, 
13
    //   everything works.
14
    // If you leave the for-loop active, the uC hangs...  
15
    for (int i=0; i++; i<3) 
16
    
17
    {
18
        SleepWatchdog(CSleep2Seconds);    //  Enter sleep mode
19
        digitalWrite(pinLED, !digitalRead(pinLED));
20
        delay(100);
21
        digitalWrite(pinLED, !digitalRead(pinLED));
22
    } 
23
}
24

25
// ##################
26
// ###  Watchdog timer functions
27
// ##################
28

29
#include <avr/sleep.h>
30
#include <avr/power.h>
31
#include <avr/wdt.h>
32

33
// Enter the arduino into sleep mode
34
void SleepWatchdog(int interval)
35
{
36
    // This order of commands is important and cannot be combined
37
    MCUSR &= ~(1<<WDRF);  // Clear the reset flag
38
    WDTCSR |= (1<<WDCE) | (1<<WDE);  // Set Change Enable bit and Enable Watchdog System Reset Mode.
39
    WDTCSR = interval;     // set watchdog timeout prescaler value
40
    WDTCSR |= _BV(WDIE);   // Enable the WD interrupt (note no reset)
41

42
    set_sleep_mode (SLEEP_MODE_PWR_DOWN); 
43
    sleep_enable();
44
    sleep_mode();   // Now enter sleep mode
45
  
46
    /* The program will continue from here after the WDT timeout*/
47

48
    sleep_disable(); // First thing to do is disable sleep
49
    power_all_enable();  // Re-enable the peripherals
50
}
51

52
ISR(WDT_vect)
53
{
54
    wdt_disable();    // Avoid that timer is called over and over again
55
}
Gast #5157101
Lesenswert?
• ▲
▼
>for (int i=0; i++; i<3)

Nicht gesehen. Ich ziehe meine Aussage zurück.

Du hast anscheinend keine Ahnung was for-Schleifen sind. Diese Zeile ist 
total falsch. Lies nochmal wie man  For-Schleifen macht
Gast #5157161
Lesenswert?
• ▲
▼
>  WDTCSR |= (1<<WDCE) | (1<<WDE);
> WDTCSR = interval;     // set watchdog timeout prescaler value
> WDTCSR |= _BV(WDIE);   // Enable the WD interrupt (note no reset)

Das stimmt so wohl nicht, statt der beiden letzten Zeilen versuchen:
1
  WDTCSR = (1<<WDIE) + interval;
Gast #5157170
Lesenswert?
• ▲
▼
Bin jetzt doch nicht ganz sicher, ich dachte, bei zwei Zeilen reicht es 
c bzw. Arduino nicht:
"Bit 4 – WDCE: Watchdog Change Enable: Once written to one, hardware 
will clear WDCE after four clock cycles"

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.