Forum: Mikrocontroller und Digitale Elektronik SLEEP und Watchdog mit Attiny 841


von Paul (Gast)


Lesenswert?

Hallo
Möchte an einem Attiny 841 die Funktion Sleep und Watchdog in betrieb 
nehmen und feststellen wie sich der Strom verhält. Verwende diesen Code 
dazu:
1
#define F_CPU 16000000UL    // Angabe der Frequenz, wichtig für die Zeit
2
#include "util/delay.h"      // Einbindung Datei Pause
3
#include "avr/io.h"        // Einbindung Datei Ausgänge
4
#include "avr/wdt.h"      // Einbindung Watchdog Bibliothek, vereinfacht WDT
5
#include "avr/sleep.h"
6
#include "avr/interrupt.h"
7
8
void watchdogSetup()      // Einrichtung Watchdog
9
  {
10
  wdt_reset();        // führt Watchdog Reset durch vor Ablauf der Zeit
11
  WDTCSR |= (1<<WDP3)|(0<<WDP2)|(0<<WDP1)|(0<<WDP0);  // Zeit
12
  WDTCSR |= (1 <<WDIE)|(0<<WDE);    // Aktivierung Watchdog Interrups nicht Reset  
13
  // WDTCSR - Register des Watchdog
14
  // WDIF - Watchdog Interuptflag
15
  // WDIE - Watchdog Interrupt Enable - ist Bit gesetzt dann löst Time-Out Interrupt aus mit Tabelle
16
  // WDE - ist Bit gesetzt dann löst Time-Out ein Reset aus mit Tabelle
17
  // WDP0, WDP1, WDP2, WDP3 Einstellung Zeit gemäss Tabelle
18
  }
19
  
20
void sleepSetup()      // Einrichtung Watchdog
21
  {
22
    MCUCR |= (1<<SE);    // Schaltet SLEEP ein
23
    //set_sleep_mode(SLEEP_MODE_IDLE);
24
    //set_sleep_mode(SLEEP_MODE_ADC);
25
    //set_sleep_mode(SLEEP_MODE_PWR_DOWN);
26
    set_sleep_mode(SLEEP_MODE_STANDBY);
27
    sleep_mode();
28
  }
29
  
30
ISR(WDT_vect)
31
  {
32
    PORTA ^= (1<<PINA5);    // toggelt LED 2
33
    WDTCSR |= (1<<WDIE);
34
  }
35
36
int main(void)
37
  {
38
  watchdogSetup();
39
  sleepSetup();
40
  DDRA=0b00100001;      // DDR A auf Ausgang schalten
41
  PORTA=0b00100001;      // Port A auf aus
42
  sei();            // Interrupt ein
43
  while(1)          // Programmschleife
44
    {
45
    PORTA &=~(1<<PINA0);  // LED 3 ein
46
    _delay_ms(3000);    // Pause 
47
    
48
    PORTA |=(1<<PINA0);    // LED 3 aus
49
    _delay_ms(3000);    // Pause 
50
    }
51
  }
Egal welche sleep .. ich aufrufe, die Stromaufnahme liegt zwischen ca. 
37mA und 39mA. Gemäss DB müsste der Strom geringer werden je nach 
Fungtion. Macht es aber nicht. Warum? Was vergessen?
LG Paul

: Verschoben durch Moderator
von Georg M. (g_m)


Lesenswert?

Paul schrieb:
> Egal welche sleep .. ich aufrufe, die Stromaufnahme liegt zwischen ca.
> 37mA und 39mA.

Wahrscheinlich µA.

Siehe: 7.3 Minimizing Power Consumption

von Sebastian R. (sebastian_r569)


Lesenswert?

Die Außenbeschaltung macht auch noch mal viel aus. Dazu die 
Taktfrequenz, Betriebsspannung,...

von Paul (Gast)


Lesenswert?

Es bleibt bei ca. 37 - 39mA, leider nicht kleiner.
Aussenbeschaltung ist mit Quarz bei 5V.

von Georg M. (g_m)


Lesenswert?

while er nicht sleept

von Janosch K. (Gast)


Lesenswert?

musste dazu nicht ein ASM Befehl genannt werden sleep oder so?! oder ist 
das beim tiny anders?

von Janosch K. (Gast)


Lesenswert?

versuch mal
asm("sleep");

von Janosch K. (Gast)


Lesenswert?

oder eben
_asm__ __volatile_ ("sleep" ::);

von Georg M. (g_m)


Angehängte Dateien:

Lesenswert?

Paul schrieb:
> ca. 37 - 39mA

Wie ist das überhaupt möglich?

von Georg M. (g_m)


Lesenswert?

Janosch K. schrieb:
> musste dazu nicht ein ASM Befehl genannt werden sleep oder so?! oder ist
> das beim tiny anders?

Der Befehl heißt sleep_mode(); und muss irgendwo in der Endlosschleife 
while(1) vorkommen.

von Paul (Gast)


Lesenswert?

Habe auf dem Brett noch eine LED drauf als Anzeige für die 5V, damit ich 
nicht vergesse wenn es eingeschaltet ist. Muss noch mal messen ob das 
2mA oder 20mA ist

von Paul (Gast)


Lesenswert?

Habe noch mal gemessen. Die Anzeige 5V braucht 13mA, die Anzeige am PIN 
des Att 841 braucht 1,6mA.

von Paul (Gast)


Lesenswert?

Hallo
Habe einiges verändert
1
void sleepSetup()      // Einrichtung sleep
2
  {
3
    MCUCR |= (1<<SE);    // Schaltet SLEEP ein
4
    //set_sleep_mode(SLEEP_MODE_IDLE);
5
    //set_sleep_mode(SLEEP_MODE_ADC);
6
    //set_sleep_mode(SLEEP_MODE_PWR_DOWN);
7
    set_sleep_mode(SLEEP_MODE_STANDBY);
8
    //sleep_mode(); 
9
    cli();
10
    sleep_enable();
11
      sei();
12
    sleep_cpu();
13
    sleep_disable();  
14
  }
dadurch verändert sich die Stromaufnahme zwischen 20mA und 37mA.
Wenn ich da von noch die LED Anzeige für die 5V abziehe (13mA) liegt die 
Stromaufnahme zwischen 7mA und 24mA. Das klingt schon besser.
Ist das aber korrekt so?
sleep_mode(); soll ja sleep_enable, sleep_cpu und sleep_disable 
entsprechen.
Was soll asm darin machen?

Georg M. schrieb:
> Der Befehl heißt sleep_mode(); und muss irgendwo in der Endlosschleife
> while(1) vorkommen.

Wo soll denn sleep_mode den hin? Bin jetzt ein wenig verwirrt was 
richtig ist.

von Amp (Gast)


Lesenswert?

nach dem aufwachen geht der doch gar nicht mehr in den sleep mode

von Heiner (Gast)


Lesenswert?

Amp schrieb:
> nach dem aufwachen geht der doch gar nicht mehr in den sleep mode

+ 1 😂

Kommt davon, wenn man einfach Code zusammenkopiert 🤷‍♂️

SCNR 😉

von Paul (Gast)


Lesenswert?

Heiner schrieb:
> Kommt davon, wenn man einfach Code zusammenkopiert 🤷‍♂️

Immer der selbe. Wenn man Hilfe fragt kommt immer so ein Kommentar dazu.
Leider finde ich im Netz nichs zu sleep und Attiny 841. Es gibt 
Unterschiede zwischen den einzelnen Attiny.

von Heiner (Gast)


Lesenswert?

Paul


https://www.avrfreaks.net/forum/attiny841-draws-too-much-current-during-sleep-mode

Schau da mal

Und es gibt schon Info über Attiny 841 und sleep Mode

Ne Suchmaschine kannste ja wohl bedienen

von Heiner (Gast)


Lesenswert?


von Auch ein Gast (Gast)


Lesenswert?

Ist das die Kiste mit den Zetteln drin?

Beitrag #6985067 wurde von einem Moderator gelöscht.
von Paul (Gast)


Lesenswert?

Es ist ein Projekt / Code um sleep mit Watchdog auf einem Attiny 841 zu 
betreiben.

von Heiner (Gast)


Lesenswert?

Paul schrieb:
> Es ist ein Projekt / Code um sleep mit Watchdog auf einem Attiny
> 841 zu
> betreiben.

Da hat Paul aber recht - dann gehört es auch in das Forum, das Paul 
gewählt hatte.
Weshalb wurde es HIERHER verschoben? Etwa weil MaWin sich echauffiert 
hat? Hat MaWin so viel Einfluss auf die Moderatoren 🤔

SCNR

von Amp (Gast)


Lesenswert?

Ins

Paul schrieb:
> Es ist ein Projekt / Code um sleep mit Watchdog auf einem Attiny
> 841 zu
> betreiben.

in Projekte/code gehören keine Fragen. Nur fertige Projekte, die man 
vorstellen will und die anderen etwas geben. :-)

von Peter D. (peda)


Lesenswert?

In die Mainloop gehört nur das sleep_cpu();
Alles andere wird einmalig im Main-Init gemacht.

Hint:
Immer den kompletten geänderten Code anhängen, statt Schnipselchen 
einfügen.
Dann muß man sich nicht immer wieder alles zusammen suchen.

von Peter D. (peda)


Lesenswert?

sleep_disable(); ist eine überflüssige Funktion. Sie bewirkt absolut 
nichts sinnvolles.

von Heiner (Gast)


Lesenswert?

Heiner schrieb:
> Paul schrieb:
>> Es ist ein Projekt / Code um sleep mit Watchdog auf einem Attiny
>> 841 zu
>> betreiben.
>
> Da hat Paul aber recht - dann gehört es auch in das Forum, das Paul
> gewählt hatte.
> Weshalb wurde es HIERHER verschoben? Etwa weil MaWin sich echauffiert
> hat? Hat MaWin so viel Einfluss auf die Moderatoren 🤔
>
> SCNR


Sorry, mein Fehler!! Bei "Projekte & Code" steht ja eindeutig:
"Hier könnt ihr eure Projekte, Schaltungen oder Codeschnipsel vorstellen 
und diskutieren. Bitte hier keine Fragen posten!"

@MaWin - sorry!!

von S. Landolt (Gast)


Angehängte Dateien:

Lesenswert?

an Paul:

Das ursprüngliche Programm leicht korrigiert, zwar für ATtiny84A, aber 
so groß werden die Unterschiede für die Fragestellung hier wohl nicht 
sein.
  Die LED an A5 blinkt sehr gemächlich, die Stromaufnahme bei 3.0 V 
beträgt im Power-down 4.2 uA, im Stand-by 70 uA (ohne LED natürlich).

von Paul (Gast)


Lesenswert?

Der Code sieht jetzt so aus:
1
#define F_CPU 16000000UL    // Angabe der Frequenz, wichtig für die Zeit
2
#include "util/delay.h"      // Einbindung Datei Pause
3
#include "avr/io.h"        // Einbindung Datei Ausgänge
4
#include "avr/wdt.h"      // Einbindung Watchdog Bibliothek, vereinfacht WDT
5
#include "avr/sleep.h"
6
#include "avr/interrupt.h"
7
8
void watchdogSetup()      // Einrichtung Watchdog
9
  {
10
  wdt_reset();        // führt Watchdog Reset durch vor Ablauf der Zeit
11
  WDTCSR |= (1<<WDP3)|(0<<WDP2)|(0<<WDP1)|(0<<WDP0);  // Zeit
12
  WDTCSR |= (1<<WDIE)|(0<<WDE);    // Aktivierung Watchdog Interrups nicht Reset  
13
  // WDTCSR - Register des Watchdog
14
  // WDIF - Watchdog Interuptflag
15
  // WDIE - Watchdog Interrupt Enable - ist Bit gesetzt dann löst Time-Out Interrupt aus mit Tabelle
16
  // WDE - ist Bit gesetzt dann löst Time-Out ein Reset aus mit Tabelle
17
  // WDP0, WDP1, WDP2, WDP3 Einstellung Zeit gemäss Tabelle
18
  }
19
  
20
void sleepSetup()      // Einrichtung sleep
21
  {
22
  //set_sleep_mode(SLEEP_MODE_IDLE);
23
  //set_sleep_mode(SLEEP_MODE_ADC);
24
  //set_sleep_mode(SLEEP_MODE_PWR_DOWN);
25
  set_sleep_mode(SLEEP_MODE_STANDBY);
26
  }
27
  
28
ISR(WDT_vect)
29
  {
30
    //PORTA ^= (1<<PINA5);    // toggelt LED 2
31
    WDTCSR |= (1<<WDIE);
32
  }
33
34
int main(void)
35
  {
36
  watchdogSetup();
37
  sleepSetup();
38
  DDRA=0b00100001;      // DDR A auf Ausgang schalten
39
  PORTA=0b00100001;      // Port A auf aus
40
  sei();            // Interrupt ein
41
  while(1)          // Programmschleife
42
    {
43
    PORTA &=~(1<<PINA0);  // LED 3 ein
44
    _delay_ms(3000);    // Pause 
45
    
46
    PORTA |=(1<<PINA0);    // LED 3 aus
47
    _delay_ms(3000);    // Pause 
48
    sleep_mode();
49
    }
50
  }
Habe zur Messung die LED A5 ausgeschaltet.
Habe die sleep.h genau angesehen und mit den verschiedenen sleep 
Einstellungen die Stromaufnahme gemessen. Ergebnis:
IDLE - 23,5 / 30,4 mA -14mA = 9,5 / 16,4 mA
ADC - 21,3 / 30,2 mA -14mA = 7,3 / 16,2 mA
PWR - 15,1 / 30,2 mA -14mA = 1,1 / 16,2 mA
Standby - 15,7 / 30,3 mA -14mA = 1,7 / 16,3 mA
Bei den 14 mA handelt es sich um die Statik Anzeige 5V mit einer LED Rot 
und Rv 219 Ohm bei 5V.
Eine Einsparung ist ja deutlich zu sehen. Es bringt ja auch einiges. 
Leider konnte ich mit den Messungen nicht auf uA Bereich kommen. Es ist 
ja noch eine Randbeschaltung am Ati 841.
Bei den beiden genannten Beispiel handelt es sich um den gleichen Code 
mit dem gleichen Problem:
Lebensdauer der Batterie im Sleep Modus. Scheint vom gleichen Autor.
Was ist noch an Einsparung möglich?

von S. Landolt (Gast)


Lesenswert?

Zu den Messwerten sage ich lieber nichts.
Nur soviel: haben Sie mein Programm zumindest angeschaut? Dort ist die 
main-while im wesentlichen leer; bei Ihnen hingegen läuft der uC 2* 3000 
ms lang mit 16 MHz - wie wollen Sie da auf uA kommen?

von Paul (Gast)


Lesenswert?

Habe noch mal die Schaltung angesehen. Habe zwei Spannungsteiler mit 
2x4,7k, U/2 und das Poti jeweils von 5V zu GND vergessen. Rechnerisch 
muss dann noch mal 1mA abgezogen werden. Da liege ich noch weiter unten, 
vielleicht im uA Bereich. Da reicht meine Messtechnik wahrscheinlich 
nicht weit genug.

S. Landolt schrieb:
> bei Ihnen hingegen läuft der uC 2* 3000
> ms lang mit 16 MHz - wie wollen Sie da auf uA kommen?

Die LED nutze ich zur Anzeige der Funktion. Bei deinem Programm ist 
nichts drin, hab ich gesehen. Habe ich den sleep_mode angegeben.
Wie kann ich den die CPU "abstellen" um noch mehr zu sparen und eine 
Anzeige zu haben?

von Paul (Gast)


Lesenswert?

Bin mir nicht sicher ob das rein muss:
MCUCR |= (1<<SE);    // Schaltet SLEEP ein
Das Programm läuft mit dieser Anweisung und auch ohne.

von S. Landolt (Gast)


Lesenswert?

Also meine Intention war, dass Sie sich mein Programm kurz anschauen und 
versuchen, es bei sich laufen zu lassen (zumindest die A5-LED blinkt); 
dabei Ihre Stromwerte mit meinen vergleichen.
  Und wenn Sie dann gar nicht weiterkommen, dieses Programm als Gerüst 
nehmen und nach Ihren speziellen Bedürfnissen ergänzen.

von Peter D. (peda)


Lesenswert?

Paul schrieb:
> _delay_ms(3000);    // Pause
>     sleep_mode();

Das ist völliger Quatsch.
Erst 3s lang full Power verbraten und dann in Sleep gehen.
Was soll das?

von S. Landolt (Gast)


Lesenswert?

an Paul, PS:
Es handelt sich dabei ja um Ihr eigenes Programm, nur vernünftig 
lauffähig gemacht.

von Paul (Gast)


Lesenswert?

Habe die Anzeige LED A0 und Pause auskommentiert.
Die Stromaufnahme liegt jetzt bei 0,84mA und 2,53mA. Dabei sind die 
Spannungsteiler berücksichtigt. Die Statusanzeige habe ich ebenfalls 
entfernt. Es wird nur noch die LED A5 geschaltet.
Ansonsten ist es das Programm von dir, genau so wie angegeben.

von S. Landolt (Gast)


Lesenswert?

Okay - wenn wir davon ausgehen, dass Ihr ATtiny841 nicht wesentlich 
schlechter ist als mein ATtiny84A, dann müssen die Differenzen von der 
Beschaltung herrühren. Da weiß ich nicht weiter.

von Heiner (Gast)


Lesenswert?

S. Landolt schrieb:
> Okay - wenn wir davon ausgehen, dass Ihr ATtiny841 nicht wesentlich
> schlechter ist als mein ATtiny84A, dann müssen die Differenzen von der
> Beschaltung herrühren. Da weiß ich nicht weiter.

@Paul
ein Schaltplan würde evtl weiterhelfen...

von Paul (Gast)


Lesenswert?

Habe noch mal alle Arten gemessen. Bei
PWR_DOWN komme ich auf 0,27 - 1,96 mA
Standby komme ich auf 0,84 - 2,54 mA
Damit ist ja PWR_Down besser als Standby. Komme langsam in deinen 
Bereich.
Habe die Schaltung noch mal kontrolliert. Es sind noch 2 Widerstände von 
4,7k drin, die 2 Eingänge nach Vcc legen um ein definiertes 
Eingangssignal zu haben für Taster. Da fliessen wahrscheinlich auch ein 
"paar" mA rein.
Ansonsten bin ich jetzt mit den Ergebnissen vollkommen zufrieden. 
Gegenüber der ersten Messung von teilweise 40mA hat es sich drastisch 
reduziert.
Danke für eure Hilfe.

von Chris S. (schris)


Lesenswert?

Wenn debugwire nicht abgeschaltet wird, dann funktioniert slieep nicht 
bei diesem mcu da debugwire die Abschaltung der verschiedenen Clocks 
verhindert.

von Paul (Gast)


Lesenswert?

Welches Bit meinst du damit genau?

von Peter D. (peda)


Lesenswert?

Chris S. schrieb:
> Wenn debugwire nicht abgeschaltet wird, dann funktioniert slieep nicht

Ist per Default abgeschaltet, da sonst ISP nicht geht.

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.