Forum: Mikrocontroller und Digitale Elektronik Arduino UNO (ATmega328P) + Watchdog -> Pause funktioniert in Loop nicht?


von Ralf S. (ralf_s480)


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
}

von jaeger (Gast)


Lesenswert?

Deaktivier mal die Interrupts/Schlafmodus und probiers nochmal. Hängt 
immer noch fest? => Probleme mit Interrupt

von jaeger (Gast)


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

von S. Landolt (Gast)


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;

von S. Landolt (Gast)


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"

von Ralf S. (ralf_s480)


Lesenswert?

jaeger schrieb:
>>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

Oh verdammt!

:))))

Wie konnte ich das übersehen.
Danke und sorry für's Blödsinn-posten!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.