Forum: Mikrocontroller und Digitale Elektronik ATtiny schlafen schicken


von Gokhlayeh (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
meine Anwendung währe so was in der Art:
Da ist ein ATtiny25 ohne externen Takt.
Er wird mit 3-4 AAA Batterien versorgt.
Der µC ist im Tiefschlaf und wird einmal die Stunde vom Timer geweckt.
Dann macht er ein paar Messungen und schaltet dann eventuel ein 
bistabiles Relais um, schaltet alle Port ab, stellt sich den Wecker 
wieder auf eine Stunde und schläft wieder ein.

Wie kann ich so eine Routine machen die den Wecker auf eine Stunde 
stellt ihn schlafen legt und nach einer Stunde wieder aufweckt?
Hat jemand ein einfaches Beispielprogramm?

von Peter II (Gast)


Lesenswert?

Gokhlayeh schrieb:
> Wie kann ich so eine Routine machen die den Wecker auf eine Stunde
> stellt ihn schlafen legt und nach einer Stunde wieder aufweckt?
> Hat jemand ein einfaches Beispielprogramm?

geht nicht, es keinen Timer der so lange läuft. Du kannst aber ein paar 
sekunden lang schlafen, dann schauen wie "spät" es ist und wenn nichts 
zu tun ist dann gleich wieder schlafen.

Alles was man dazubraucht steht im Datenblatt. Aber sehr genau wird es 
mit dem Internen Takt nicht.

von spess53 (Gast)


Lesenswert?

Hi

>geht nicht, es keinen Timer der so lange läuft. Du kannst aber ein paar
>sekunden lang schlafen, dann schauen wie "spät" es ist und wenn nichts
>zu tun ist dann gleich wieder schlafen.

Beim ATTiny25 sollte man schon, wenn ich mich nicht verrechnet habe, auf 
einen Timeroverflow von 2,8 min kommen (6,4MHz, Clock Divider 256 und 
Timer-Prescaler 16364). Eine Stunde in einem Ritt ist mit einem Timer 
nicht möglich.
Eine Möglichkeit wäre:

http://www.atmel.com/dyn/resources/prod_documents/doc1268.pdf

MfG Spess

von Peter D. (peda)


Lesenswert?

Du kannst den Watchdoginterrupt nehmen und auf 8s setzen. Und dann ne 
Variable zählen, bis 1h rum ist.

Du kannst den ATtiny25 aber auch langasm takten, um Strom zu sparen, 
z.B. mit nem 32kHz Quarz.

Peter

von Gokhlayeh (Gast)


Lesenswert?

Vielen Dank für die tollen Tip's  :-)

Leider fehlen mir die Basics wie Timerinterrupts aus dem Tiefschlaf 
etc.
Vieleicht hat ja doch noch jemand ein einfaches (10-20 Zeilen) 
Beispielprogramm in C

Den Artikel (Long Delay Generation Using the AVR Microcontroller) muss 
ich mal durcharbeiten.

Peter Dannegger schrieb:
> Du kannst den ATtiny25 aber auch langasm takten, um Strom zu sparen,
> z.B. mit nem 32kHz Quarz.

Leider keine Portleitung mehr frei.

Würde CLKDIV8 helfen?

von (prx) A. K. (prx)


Lesenswert?

Peter Dannegger schrieb:

> Du kannst den Watchdoginterrupt nehmen und auf 8s setzen. Und dann ne
> Variable zählen, bis 1h rum ist.

Geht aber nur, wenn die genannte Stunde auch mal eine Viertelstunde mehr 
oder weniger sein darf. Der ist zumindest dem Datasheet nach grässlich 
ungenau.

von (prx) A. K. (prx)


Lesenswert?

Gokhlayeh schrieb:

> Leider keine Portleitung mehr frei.
> Würde CLKDIV8 helfen?

Gewissermassen, insbesondere mit dem Watchdog-Oszillator als Taktquelle. 
Wobei CLKDIV8 heute meist ein Speziallfall eines programmierbaren 
Registers ist. Voll ausgefahren kannst du dem AVR dann fast schon Befehl 
für Befehl live zusehen. ;-)

Denk aber dran, dass ISP mit maximal 1/4 des Taktes arbeitet.

von Gokhlayeh (Gast)


Lesenswert?

Ne,
sowas mit Watchdogtimer ist weit über meinen Möglichkeiten.
Was ich mir vorstellen kann, ist ein Timerinterrupt,
der jede Sekunde aufwacht eine Variable hochzählt, bei 3600 ist dann 
eine Stunde rum und Action  ;-)

Hat jemand so ein Template für mich, das wär toll!

von Peter II (Gast)


Lesenswert?

Gokhlayeh schrieb:
> Hat jemand so ein Template für mich, das wär toll!

NEIN - fang selber an zu Programmieren, wenn du nicht weiter kommst dann 
stellt konkrete Frage.

Es gibt ausreichend Artikel 
http://www.mikrocontroller.net/articles/Hauptseite wo so alles drin 
steht was du brauchst.

von Peter D. (peda)


Lesenswert?

Gokhlayeh schrieb:
> sowas mit Watchdogtimer ist weit über meinen Möglichkeiten.

D.h. Du hast Probleme, den entsprechenden Abschnitt im Datenblatt zu 
lesen?

Gokhlayeh schrieb:
> Was ich mir vorstellen kann, ist ein Timerinterrupt,

Der Idle-Mode spart fast nix.


Peter

von Gokhlayeh (Gast)


Lesenswert?

Peter II schrieb:
> NEIN - fang selber an zu Programmieren, wenn du nicht weiter kommst dann
> stellt konkrete Frage.

Ich habe jetzt dieses programmiert, leider erwacht der µC nach dem 
Schlafenschicken nicht mehr.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <avr/sleep.h>
4
5
6
//Tabellen
7
8
9
10
11
//***********************************************
12
int main(void)
13
{
14
  TCCR1 = 0b00001111;    // Prescaler = CK / 16384
15
  TIMSK |= (1 << TOIE1);  // Timer1 Overflow Interrupt Enable
16
  sei();          // Enable Interrrupt
17
  while(1){}        // tue nix und warte auf Timer-int
18
              // 8MHz / 16384 / 256 = 1,9...Hz
19
}
20
//***********************************************
21
ISR(TIMER1_OVF_vect)
22
{
23
  static unsigned char n;
24
  DDRB = DDRB_tab[n];
25
  PORTB = PORTB_tab[n];  // LED-Blinky-Zauber
26
  if(n++ >= 19) n=0;
27
28
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);
29
  sleep_mode ();
30
}
31
//***********************************************
Was kann man tun?

von Peter II (Gast)


Lesenswert?

Gokhlayeh schrieb:
> Was kann man tun?

man sollte das sleep nicht in der ISR aufrufen, das sollte in der main 
passieren.

Ich habe jetzt die doku nicht im Kopf aber der Befehl zum schlafen war 
meines wissen

sleep();

den sehe ich bei dir überhaupt nicht.

von MWS (Gast)


Lesenswert?

Gokhlayeh schrieb:
> Was kann man tun?

Sleep nicht in 'ner ISR ausführen, da sind Interrupts global disabelt. 
Müssen aber enabelt sein, damit der nächste Interrupt wieder auslösen 
kann.

von Stone (Gast)


Lesenswert?

Aus dem Power Down, wir er auch so nie wieder aufwachen, weil der Timmer 
nicht mehr läuft.
vielleicht mal das Tutorial über Sleep Modi durch arbeiten.
http://www.mikrocontroller.net/articles/Sleep_Mode

Gruß Matthias

von MWS (Gast)


Lesenswert?

Stone schrieb:
> Aus dem Power Down, wir er auch so nie wieder aufwachen, weil der Timmer
> nicht mehr läuft.

Stimmt. Für den Fall des Tiny25 ließe sich nur wie oben bereits 
vorgeschlagen der WDT-Interrupt missbrauchen.
Unabhängig davon sägst Du mit einem Sleep in der ISR den eigenen Ast ab.

von Gokhlayeh (Gast)


Lesenswert?

So, habe jetzt dieses:
1
//***********************************************
2
int main(void)
3
{
4
  TCCR1 = 0b00001111;    // Prescaler = CK / 16384
5
  TIMSK |= (1 << TOIE1);  // Timer1 Overflow Interrupt Enable
6
  sei();          // Enable Interrrupt
7
  while(1)
8
  {
9
    set_sleep_mode (SLEEP_MODE_PWR_SAVE);
10
    sleep_mode();
11
  }
12
}
13
/*
14
SLEEP_MODE_IDLE         0
15
SLEEP_MODE_PWR_DOWN     1 wacht nicht auf
16
SLEEP_MODE_PWR_SAVE     2
17
SLEEP_MODE_ADC          3 wacht nicht auf
18
SLEEP_MODE_STANDBY      4 nicht bei ATtiny25
19
SLEEP_MODE_EXT_STANDBY  5 nicht bei ATtiny25
20
*/
21
//***********************************************
22
ISR(TIMER1_OVF_vect)
23
{
24
  static unsigned char n;
25
  DDRB = DDRB_tab[n];
26
  PORTB = PORTB_tab[n];  // LED-Blinky-Zauber
27
  if(n++ >= 19) n=0;
28
}
29
//***********************************************
Jetzt mal messen ob bei SLEEP_MODE_IDLE oder bei SLEEP_MODE_PWR_SAVE 
weniger Stromverbrauch.

von Peter II (Gast)


Lesenswert?

Gokhlayeh schrieb:
> Jetzt mal messen ob bei SLEEP_MODE_IDLE oder bei SLEEP_MODE_PWR_SAVE
> weniger Stromverbrauch.
geht auch ohne messen  - steht sogar im Datenblatt.

> set_sleep_mode (SLEEP_MODE_PWR_SAVE);
das musst du nicht jedesmal machen, einmal beim init reicht.

von Gokhlayeh (Gast)


Lesenswert?

Leider klappts mit dem Schlafen nicht so:
Während des Schlafens nuckelt der ATtiny25 ca. 3mA aus der (5V) 
Batterie.
Ich hatte eigentlich mit ein paar µA gerechnet
1
int main(void)
2
{
3
  set_sleep_mode (SLEEP_MODE_IDLE);
4
  TCCR1 = 0b00001111;    // Prescaler = CK / 16384
5
  TIMSK |= (1 << TOIE1);  // Timer1 Overflow Interrupt Enable
6
  sei();          // Enable Interrrupt
7
  while(1)
8
  {
9
                //hier steht mein LED-Blinky-Zauber 
10
                //13,5mA + 7mA Eigenverbrauch gemessen
11
12
    DDRB = 0;
13
    PORTB = 0;
14
    unsigned char i=30;
15
    while(i--) sleep_mode(); //leider hier 6mA gemessen
16
  }
17
}
18
//***********************************************
19
ISR(TIMER1_OVF_vect){TCNT1=14;}
20
//***********************************************
Vielleicht verwende ich dieses SLEEP_MODE_IDLE falsch?
Welchen Sleep-Mode müsste ich denn nehmen, um den Stromverbrauch unter 
10µA zu drücken?

von Peter D. (peda)


Lesenswert?

Gokhlayeh schrieb:
> Vielleicht verwende ich dieses SLEEP_MODE_IDLE falsch?

Siehe:

Peter Dannegger schrieb:
> Der Idle-Mode spart fast nix.


Gokhlayeh schrieb:
> Welchen Sleep-Mode müsste ich denn nehmen, um den Stromverbrauch unter
> 10µA zu drücken?

Siehe:

Peter Dannegger schrieb:
> Du kannst den Watchdoginterrupt nehmen und auf 8s setzen. Und dann ne
> Variable zählen, bis 1h rum ist.


Peter

von Falk B. (falk)


Lesenswert?

@  Gokhlayeh (Gast)

>Vielleicht verwende ich dieses SLEEP_MODE_IDLE falsch?

Ja.

>Welchen Sleep-Mode müsste ich denn nehmen, um den Stromverbrauch unter
>10µA zu drücken?

PWR_SAVE, siehe Sleep Mode.

MFG
Falk

von Gokhlayeh (Gast)


Lesenswert?

leider geht der SLEEP_MODE_PWR_SAVE bei mir irgendwie nicht,
der µC schläft nicht ein.

Bei SLEEP_MODE_IDLE schläft der µC ein, säuft allerdings noch 3mA.

Was tun?

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.