Atmega328p mit Arduino Software bleibt nicht im SLEEP_MODE_IDLE

OP #3071314
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?
OP #3079891
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?
Gast #3079917
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
OP #3079950
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.
OP #3079964
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?
Gast #3080059
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren