Forum: Mikrocontroller und Digitale Elektronik Atmega328p mit Arduino Software bleibt nicht im SLEEP_MODE_IDLE


von Josef K. (zumlin)


Lesenswert?

Hi,

ich habe mich leider dafür entschieden ein kleines Projekt mit den 
Arduino Libs zu schreiben. Prinzipiell bin ich davon sehr enttäuscht, 
aber das soll hier mal kein Thema sein :)

Prinzipiell läuft mein Programm und jetzt will ich noch Energie sparen. 
Da ich von eingehender UART Kommunikation und von Pin Toggles aufgeweckt 
werden möchte, wollte ich den SLEEP_MODE_IDLE Schlafmodus aktivieren, 
doch leider werde ich daraus sofort wieder aufgeweckt. Nur wovon?

Hier mal ein kleiner Auszug aus meinem Code, der relevant sein könnte:
1
#include <avr/sleep.h>
2
#include <avr/power.h>
3
4
// ...
5
6
void setup(void)
7
{
8
  /* additional interrupts */
9
  PCICR  |= (1<<0);            // enable PCINT0
10
  PCMSK0 |= (1<<0);            // Set PB0 interrupt for INT0
11
  PCICR  |= (1<<1);            // enable PCINT1
12
  PCMSK1 |= (1<<1);            // set PC1 interrupt for INT1
13
  PCICR  |= (1<<2);            // enable PCINT2
14
  PCMSK2 |= (1<<3);            // set PD3 interrupt for INT2
15
16
  // ...
17
18
  interrupts();
19
  
20
  /* Serial interface */
21
  Serial.begin(9600); 
22
}
23
24
void main(void)
25
{
26
  while(true) {  
27
    // ...
28
    //pollen auf UART empfang
29
30
    set_sleep_mode(SLEEP_MODE_IDLE);
31
    sleep_enable(); 
32
            
33
    power_adc_disable();
34
    power_spi_disable();
35
    power_timer0_disable();
36
    power_timer1_disable();
37
    power_timer2_disable();
38
    power_twi_disable();
39
    
40
    sleep_mode();                   // in den Schlafmodus wechseln
41
    
42
    sleep_disable(); 
43
    power_all_enable();
44
  } 
45
}
46
47
ISR(PCINT0_vect)
48
{
49
  //...
50
}
51
52
ISR(PCINT1_vect)
53
{
54
  // ...
55
}
56
57
ISR(PCINT2_vect)
58
{
59
  // ...
60
}

Die UART Kommunikation sollte es nicht sein, da ich immer wieder aus dem 
Schlafmodus geweckt werde, obwohl ich noch kein Zeichen empfangen habe. 
Gesendet habe ich aber schon welche.
Was bleibt noch über? Der Watchdog? Die Timer müssten in so einem 
Arduinoprojekt aktiv sein, aber ich habe diese hoffentlich mit den 
power_ Funktionen vorübergehend ausgeschalten, oder?

Kann man irgendwie heraus bekommen wovon man aus dem Schalfmodus geweckt 
wurde?

von Josef K. (zumlin)


Lesenswert?

Hi nochmal.

Also ich habe jetzt mal in alle Interrupt-Vektoren ein Serial.print 
eingebaut, um evtl zu sehen welcher interrupt den µC wieder aufweckt. 
Leider scheint aber kein Interrupt aufgerufen zu werden.

Kann es sein, dass der Controller nie in den SLEEP_MODE_IDLE wechselt?

von Ingo (Gast)


Lesenswert?

Du kannst ja mal die Interrupts nacheinander abschalten um zu gucken 
welcher ggf klemmt. Ansonsten, wie merkst du das er nicht schlafen will? 
Stromaufnahme mal gemessen?

Hier kann man doch super durch Probieren rausfinden warum es nicht geht, 
also auf geht's.
Oder gehörest du zur Gruppe "ohne Debugger kriege ich nichts hin"?

Ingo

von Josef K. (zumlin)


Lesenswert?

Hi

also das mit den Interrupts abschalten habe ich ja indirekt schon 
ausprobiert, oder? Da ich in jeden Interrupt-Vektor einen kleinen 
Debugcode mit einem Serial.print eingebaut habe, sollte ich diese doch 
im Terminal sehen. So war zumindest meine Annahme. Gibt es Interrupts, 
die ich damit nicht abdecke?

Die Stromaufnahme hab ich nicht gemessen. Ich lasse aber ein LED-Licht 
aus und einschalten, je nachdem ob ich gerade in SLEEP_MODE_IDLE 
wechseln will, oder eine Runde in der While-Schleife drehe. Die LED ist 
scheint permanent ein- und ausgeschalten zu werden.

von Maus (Gast)


Lesenswert?

woher weisst du dass er nicht schläft?

> Stromaufnahme mal gemessen?
genau, und möglichst hinter dem Converter, der eh am meisten Strom 
verbraucht.

von Josef K. (zumlin)


Lesenswert?

Hmm. Ich habe gerade versucht in einen anderen SLEEP_MODE zu wechseln. 
Das scheint zu funktionieren. Schon aus dem SLEEP_MODE_ADC scheine ich 
nicht mehr auf zu wachen.

Bleibt also nur noch SPI und UART als "Aufwachquelle" über. Kann es an 
der externen UART Beschaltung liegen, dass ich nicht im SLEEP_MODE_IDLE 
bleiben kann?

von Maus (Gast)


Lesenswert?

http://www.mikrocontroller.net/articles/Sleep_Mode#Idle_Mode

> Gibt es Interrupts, die ich damit nicht abdecke?
im idle mode laufen die Timer ja weiter.
Beim Arduino läuft glaub ich immer ein Interrupt-Timer für millis() und 
so im Hintergrund.
Ist also schon da bevor du irgend was schreibst.

> Die Stromaufnahme hab ich nicht gemessen
lohnt sich aber

von Verwirrter Anfänger (Gast)


Lesenswert?

Josef Kkk schrieb:
> also das mit den Interrupts abschalten habe ich ja indirekt schon
> ausprobiert, oder? Da ich in jeden Interrupt-Vektor einen kleinen
> Debugcode mit einem Serial.print eingebaut habe, sollte ich diese doch
> im Terminal sehen. So war zumindest meine Annahme. Gibt es Interrupts,
> die ich damit nicht abdecke?

Ich bin mir nicht sicher, ob die Serielle Schnittstelle innerhalb eines 
Interrupts funktioniert. Je nachdem, wie das implementiert ist, könnte 
der Arduino dort hängen bleiben.

Ich glaube hier:
Beitrag "Arduino friert ein: SPI und PinChange Interrupt"
hatte das mit Serial.print() innehralb eines Interrupts nicht 
funktioniert.

von Maus (Gast)


Lesenswert?

ja besser in der ISR eine Variable setzten und dann im Loop seriell 
schreiben oder LED blinken lassen

von Josef K. (zumlin)


Lesenswert?

Timer0 war das Problem. Den Timer vor Sleep stoppen und danach wieder 
aktivieren bringt Abhilfe.
Komisch nur, dass ich nie in mein Timer0 Interrupt Funktion gekommen bin 
oder eine Fehlermeldung beim kompilieren bekommen habe, dass die 
Funktion zwei mal existiert.

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.