Go Down

Topic: attiny85 sleep mode (Read 12096 times) previous topic - next topic

magictrips

hallo,

ich komme mit folgendem sketch leider nur auf 350µA, es sollen aber erheblich weniger möglich sein:


#include <avr/power.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
.
.
.
.   

    power_all_disable();
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    sleep_enable();
    sleep_mode();
    sleep_disable();


woran kann das liegen bzw was fehlt noch ?

auf dem ic steht attiny85 20pu

und unten
ac2      hqa
b         1p
1448     e3

uxomm

#1
May 29, 2015, 03:06 am Last Edit: May 29, 2015, 03:28 am by uxomm
Versuch es mal so:
Code: [Select]
#include <avr/sleep.h>    // Sleep Modes
#include <avr/power.h>    // Power management
.
.
.
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
ADCSRA = 0;            // ADC ausschalten
power_all_disable (); 
sleep_enable();
sleep_cpu();             // µC schläft               
.
.
.

Die Frage ist auch, wie der ATtiny wieder aufwacht. Interrups wären eine Möglichkeit. Bei deinem Code ist zwar <avr/interrupt.h> eingebunden, aber ich sehe keine ISR. Es ist ja auch nicht der gesamte Code (übrigens: verwende bitte Code Tags - klick auf </> über dem :) ).

Einen interessanten Artikel (engl.) zum Thema "Stromsparen" und Sleep gibt es hier : 
http://www.gammon.com.au/power

Und Spezielles für ATtiny:
ATtiny85 sleep mode and wake on pin change (0,5 µA)
http://www.gammon.com.au/forum/?id=11488&reply=9#reply9

ATtiny85 sleep mode, wake on pin change interrupt or watchdog timer (6,66 µA)
http://gammon.com.au/forum/?id=11497&reply=6#reply6


Always decouple electronic circuitry.

magictrips

danke schön ! werds mir mal durchlesen......

ne ist nicht der ganze code.......
ist jetzt nur zum ausprobieren....
aufwachen soll der später mit hilfe von watchdog.

ich wollte nur wissen, ob die befehle, die ich verwende ausreichend/richtig sind ?

weil ich hab mein amperemeter in reihe zum vcc und komme damit nur auf 350µA und nicht auf die 6,6µA oder gar 0,5µA von denen ich öffters lese......



noch mal eine frage nebenbei zu den möglichkeiten:
die power.h beinhaltet etliche funktionen des µC, die man seperat an/abstellen kann oder alle mit "power_all_disable (); "

die sleep.h
hat die drei funktionen (hab dann noch 350µA):
sleep_enable();
sleep_cpu();   
sleep_disable();
da hab ich aber nicht so ganz verstanden, was die machen (hatte schon was darüber gelesen).
nur wird anscheinend oft enable und disable zum abschalten verwendet ?


dann kann man noch die BOD abstellen? (hat mir aber keine (für mich) messbare ersparnis gebracht):
sleep_bod_disable();
funktioniert aber nicht bei allen attiny versionen ?


und dann habe ich auch noch den befehl gefunden, bei dme ich nicht weiß, was er macht(ich vermute er schaltet interrupts an und ab?:
GIMSK |= _BV(INT0);                       //enable INT0
GIMSK = 0x00;                  //disable INT0


und du hast auch noch den ADC abgeschaltet:
ADCSRA = 0;            // ADC ausschalten
ist der nicht auch in der power.h enthalten ?

wenn ich den ADC ausschalte spare ich 320µA ! (der attiny verbaucht dann nur noch strom im (für mich) nicht mehr messbaren bereich (: )
nur bekomme ich den ADC im laufenden program nicht wieder angeschaltet....
mit ADCSRA = 1; ?


und welche sachen kann ich während des normalen betriebs abschalten um energie zu sparen ?
wenn ich nur einen dht22 (oder einen ic2 sensor) und ein 433mhz sender am atiny hab ?
den ADC brauche ich doch nur, wenn ich die analogen eingänge oder pwm nutze oder ?
die BOD brauche ich doch auch nicht ?

combie

Quote
nur bekomme ich den ADC im laufenden program nicht wieder angeschaltet....
mit ADCSRA = 1; ?
Vor dem Abschalten des ADC muss geprüft werden, ob die Wandlung abgeschlossen ist.
Wird er mitten in der Wandlung abgeschaltet, ist er meist tot bis zum nächsten Stromausfall.
Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

magictrips

hmmm und wie macht man das ?

also ich hab grad emal nachgesehen.
in der power.h ist der ADC auch enthalten, ich kann ihn über diese aber nicht abstellen...

funktioniert nur mit

"cbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter
sbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter "

oder

ADCSRA = 0;            // ADC ausschalten

Doc_Arduino

#5
May 30, 2015, 06:31 pm Last Edit: May 30, 2015, 06:31 pm by Doc_Arduino
Hallo,

was macht denn
<avr/power.h>


zusätzlich oder anders?

Ich verwende nur
<avr/sleep.h>


und habe mich daran gehalten.  http://playground.arduino.cc/Learning/ArduinoSleepCode
mit   set_sleep_mode(SLEEP_MODE_PWR_DOWN);
setze ich auch den tiefsten Modus.
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

magictrips

die power.h soll wohl so einiges machen:

http://www.nongnu.org/avr-libc/user-manual/group__avr__power.html

allerdings hab ich nicht so das gefühl, das die viel bringt.....

die soll wie gesagt auch den ADC abstellen, aber irgendwie klappts mit ihr nicht......

ich hab aber auch noch das gefunden:

Code: [Select]
ACSR = B10000000; // Analogen Comparator abschalten, ACD bit7 zu 1
DIDR0 = DIDR0 | B00111111; // Digitale Eingangspuffer ausschalten, analoge Eingangs Pins 0-5 auf 1



ich hätte da aber noch eine frage....
und zwar versetze ich den tiny in schlafmodus und lasse ihn dann durch den watchdog aufwecken....
der watchdog kann aber nur bis zu 8sec.
also kommt der tiny sofrt wieder in schlafmodus, durch ein counter usw.

wenn ich jetzt zB möchte, das der tiny 10sec schläft
gibt es jetzt zB folgende möglichkeiten:

1. ich wecke ihn mit dem watchdog einmal nach 8sec und dann gehts wieder in sleep-modus und dann wecke ich ihn wieder nach 2sec = 10sec..

2. oder ich stelle den watchdog auf 1sec ein und er wird nach eienr sec wache und fällt direkt wieder in sleep-modus. das dann 10 mal.

ich frage mich, ob die zweite methode "spührbar" mehr akkukapazität aufbraucht, als die erste oder ob es kein bzw kaum ein unterschied macht ??
weil die zweite finde ich programmiertechnisch angenehmer, wenn man mit variablen zeiten arbeitet....
bei der zweiten wäre der tiny doch dann immer für den bruchteil einer sekunde wach und geht dann wieder schlafen ?
mein messgerät zeigt über die gesamte dauer 0,01mA an.....
aber messgeräte sind auch träge und das ist das kleinst mögliche, das mein messgerät anzeigen kann (;

sschultewolter

Warum nicht einfach immer das vielfache von 8 nehmen? (8, 16, ...). Einfach bei jedem Aufwecken durch den WDT eine Variable hochsetzen. Wenn die Variable bei 2 angekommen ist, wieder auf 0 setzen und Aktion ausführen (bei 16s). Spürbar verbraucht keine der Methoden Akkukapazität.

Da bringt es deutlich mehr, denn Attiny auf 1MHz zu takten. Die Messungen mit deinem Multimeter kannst in dem Bereich nicht zwingend mehr gebrauchen. Mein Fluke179 hat eine Auflösung von 0,01mA, weniger macht es nicht. Das ist für sowas viel zu ungenau, vorallem wenn du wirklich im µA Bereich runterwillst. Vermutlich braucht die externe Beschaltung das xFache an Strom.
Orginal Atmel AVRISP mkII zu verkaufen. Anfrage per PN ;)

Serenifly

#8
Jun 02, 2015, 03:28 pm Last Edit: Jun 02, 2015, 03:32 pm by Serenifly
Code: [Select]

ACSR = B10000000; // Analogen Comparator abschalten, ACD bit7 zu 1

Lesbarer wird es wenn man die Namen der Bits verwendet. Worauf es im ACSR Register ankommt ist das ACD Bit (Analog Comparator Disable)

Also:
Code: [Select]

ACSR = _BV(ACD);

oder
Code: [Select]

ACSR = (1 << ACD);


Bewirkt das gleiche, aber man muss sich nicht wundern welches Bit man da jetzt gesetzt hat. Wobei der Komparator standardmäßig ausgeschaltet sein sollte.

Aber das gleiche gilt für das ADC Status Register ADCSRA und das ADEN Bit. Mit ADCSRA = _BV(ADEN) setzt man das Bit. So hat man den Namen des Registers und des Bits in der Anweisung.

Die Register-Beschreibung gibt es im Datenblatt:
http://www.atmel.com/Images/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf
Seite 120 für das Komparator Status Register. 136 für den ADC

Doc_Arduino

Hallo,

Du kannst doch zwischen
16ms, 32ms, 64ms, 125ms, 250ms, 500ms, 1sec. 2sec, 4sec und 8sec. wählen. Wenn Du unbedingt im 10sec. Rhythmus was tun möchtest, wäre der kleinste Nenner 2 Sekunden. Und dieses kurze aufwachen, Variable hochzählen und wieder schlafen legen ist die übliche Methode. Das passiert alles innerhalb von "paar Takten", fältt absolut nicht ins Gewicht. Da mußte Dir keinen Kopf machen.




Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

magictrips

@ alle: danke schön !

@serenifly: stimmt......diese verschiedenen schreibweisen haben mich anfangs auch etwas verwirrt....
ich hab mich jetzt auf (1<< .....) festgelegt.

das: DIDR0 = DIDR0 | B00111111;
geht ja auch so: DIDR0 = (1 << ADC0D) | (1 << ADC2D) | (1 << ADC3D) | (1 << ADC1D) | (1 << AIN1D) | (1 << AIN0D);


@ sschultewolter und doc:
wenn es wirklich nur einen bruchteil mehr "verbraucht" (sagen wir mal 1-2tage bei 100tagen).
dann ist mir das lieber den watchdog auf 1sec festzulegen, weil ich eventuell den schlafinterval mit einem 3er dip-schalter festlegen möchte keine pause, 5sec, 10sec, 30sec, 60sec, 5min, 10min, 30min, 1std oder so, mal sehen und da läßt sich mit einer watchdog-sekunde super rechnen, ohne viel programmieraufwand (;
5 watchdog sec wären auch noch gut, aber die gibts ja nicht (;
2 ging auch noch, wenn ich statt 5sec 4 nehme, aber bei 4 und 8 watchdogsekunden wirds eng....

sschultewolter

Vermutlich wird dein größtes Problem die Spannungsregelung/Batterieladung in Bezug auf Selbstentladung ein.
Orginal Atmel AVRISP mkII zu verkaufen. Anfrage per PN ;)

magictrips

das denke ich auch (;
oder der co2-sensor, der dauerhaft geheizt werden muss....
bzw die "aufwärmphase" die ja beim dht22 3sec beträgt ?
ich glaub, da muss ich mich nach was sparsamerem umsehen (;

ich hab wo gelesen, das es auch etwas einsparen soll, alle ports auf INPUT zu stellen......
ich hab mal was rumgespielt und mit INPUT hatte ich da keine wirkliche einsparung, aber wenn ich alle ports auf OUTPUT gestellt hatte, hat das ca 2ma ausgemacht, im aufgeweckten zustand.

Serenifly

Auf der Nick Gammon Seite wird gezeigt was wie viel bringt. Viele dieser Details sind im µA Bereich. Das misst du wie gesagt mit einem normalen Multimeter nicht mehr richtig.

magictrips

ok, danke ! habs soweit ans laufen bekommen bzw wieder was gelernt (;

eins hab ich aber noch nicht verstanden und zwar das heir: |=

ich hab im sketch zb einmal sowas hier stehen:
ADCSRA = (1 << ADEN);            // ADC ausschalten

und einmal sowas:
ADCSRA |= (1<<ADSC); // Start conversion


das erste setzt ADEN doch auf 1 bit oder ?

und das zweite ? was macht dieser strich vor dem = ?
eine alternative schreibweise ist es nicht oder ? weil ich hab schon versucht den wegzulassen, was dazu geführt hat, dass das program nicht mehr läuft...

Go Up