www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Stromverbrauch ATtiny13A im Sleep-Modus


Autor: Martin (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich betreibe einen ATtiny13 als Temperatursensor. Dieser soll in diesem 
Beispiel einfach nur die drei angeschlossenen LEDs anschalten, wenn die 
Temperatur unter einen festgelegten Wert sinkt.

Um die Temperatur zu messen kommt ein NTC zusammen mit einem normalen 
Widerstand als Spannungsteiler zum Einsatz. Dieser Spannungsteiler wird 
nur während der Temperaturmessung mit Strom versorgt.

Folgendes soll passieren: Der ATtiny13 soll alle 8 Sekunden per Watchdog 
aufgeweckt werden und die Temperatur messen. Ist diese zu hoch, soll er 
sofort wieder in den Sleep-Modus gehen. Ist die Temperatur ausreichend 
niedrig, so soll er die LEDs anschalten und ab und zu überprüfen, ob die 
Temperatur immernoch ausreichend niedrig ist. Falls ja, soll er das 
Reset des Watchdog verhindern.

Der Code funktioniert soweit sehr gut. Es kommt mir allerdings darauf 
an, dass die Schaltung mit einer Knopfzelle so lange wie möglich 
durchhält. Die LED wird nur sehr selten angehen und daher kommt es vor 
allem auf den Stromverbrauch im Standby an. Das Standby setzt sich aus 
zwei Phasen zusammen. Der Eigenentlichen Sleep-Phase (8 Sekunden) und 
dem kurzen Aufwachen zum Messen der Temperatur (wenige µs).

Ich habe diesen Stromverbrauch nun gemessen und sehe, dass der ATtiny13A 
im Sleep-Modus 50µA benötigt, was mir deutlich zu viel vorkommt (laut 
Datenblatt im nA-Bereich!).

Wo liegt der Fehler?
#define LED_RED      PB3
#define LED_GRN      PB4
#define LED_BLU      PB1
#define PIN_TEMP_VCC PB0
#define PIN_TEMP_MEA PB2

#define RED_OFF      PORTB |= (1 << PB3);
#define GRN_OFF      PORTB |= (1 << PB4);
#define BLU_OFF      PORTB |= (1 << PB1);
#define RED_ON       PORTB &=~(1 << PB3);
#define GRN_ON       PORTB &=~(1 << PB4);
#define BLU_ON       PORTB &=~(1 << PB1);

#define TEMP_VCC_ON  PORTB |= (1 << PB0);
#define TEMP_VCC_OFF PORTB &=~(1 << PB0);

#define TEMP_THRESHOLD 600

#include <avr/io.h>
#include <util/delay.h>

#include <avr/sleep.h>
#include <avr/wdt.h>

// Watchdog initialisieren
void initSleep()
{
  wdt_enable(WDTO_8S);      // Watchdog einstellen
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);  // Stromsparmodus einstellen
}

// Reset verhindern
void stayAwake()
{
  wdt_reset();
}

// In den Stromsparmodus wechseln
void fallAsleep()
{
  sleep_mode();
}

// Temperatur messen (ADC)
int temp()
{
  TEMP_VCC_ON;  // NTC-Spannungsteiler mit Strom versorgen

  int result;
  ADMUX = 1;

  ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0);
  ADCSRA |= (1<<ADSC);
  while ( ADCSRA & (1<<ADSC) ) {}
  result = ADCW;
  result = 0;
  ADCSRA |= (1<<ADSC);
  while ( ADCSRA & (1<<ADSC) ) {}
  result = ADCW;  
  ADCSRA &= ~(1<<ADEN); 

  TEMP_VCC_OFF;  // Spannungsteiler stromlos machen

  return result;
}

int main()
{
  // Ausgänge
  DDRB =   (1 << LED_RED)
         | (1 << LED_GRN)
         | (1 << LED_BLU)
         | (1 << PIN_TEMP_VCC);
         

  // LEDs abschalten
  BLU_OFF;
  GRN_OFF;
  RED_OFF;

  // Temperaturmesser
  DDRB &= ~(1 << PIN_TEMP_MEA);

  // Watchdog und Sleep-Modus initialisieren
  initSleep();

  // LEDs anschalten?
  char on = 1;
  
  // Temperaturmess-Verzögerung
  int temp_count = 0;
  
  // PWM-Variable
  char pwm = 0;
  
  // Wenn es zu warm ist -> Sleep
  if (temp() <= TEMP_THRESHOLD)
  {
    fallAsleep();
  }

  // Hauptschleife
  while(1)
  {
    // Alle 512000 Zyklen die Temperatur messen und prüfen ob der Schwellenwert unter- oder überschritten wurde
    if (pwm == 255)
    {
      temp_count++;
      if (temp_count == 2000)
      {
        on = (temp() > TEMP_THRESHOLD);
        temp_count = 0;
      }
    }
    ++pwm;

    if (on)
    {
      stayAwake();  // Reset-Counter zurücksetzen
      RED_ON;
      GRN_ON;
      BLU_ON;
      /* An dieser Stelle sind eigentlich Animationen mit den LEDs gewesen die aus Gründen der besseren Übersicht gestrichen wurden und ein reines Anschalten anstelle eingefügt. */
    }
    else
    {
      RED_OFF;
      GRN_OFF;
      BLU_OFF;  // LEDs ausschalten
      fallAsleep();  // Einschlafen
    }
  }
}

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Brown out an? Der Watchdog braucht übrigens auch Strom.

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Brown-Out-Detection ist aus. Klar braucht der Watchdog Strom, aber doch 
nicht so viel?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Travel Rec. wrote:
> Brown out an? Der Watchdog braucht übrigens auch Strom.

Sind allerdings eher 5 statt 50 µA.

Ansonsten kann das von Flussmittelresten auf der Platine beginnend
über offene Eingänge alles mögliche sein.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch wrote:

> Ansonsten kann das von Flussmittelresten auf der Platine beginnend
> über offene Eingänge alles mögliche sein.

OK, die offenen Eingänge nehme ich nach Blick auf die Schaltung
zurück. ;-)

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das hier:
    // Alle 512000 Zyklen die Temperatur messen und prüfen ob der Schwellenwert unter- oder überschritten wurde
    if (pwm == 255)
    {
      temp_count++;
      if (temp_count == 2000)
      {
        on = (temp() > TEMP_THRESHOLD);
        temp_count = 0;
      }
    }
    ++pwm;

würde ich auch nicht gerade als stromsparende Programmierung
bezeichnen.  Dafür kann man auch einen Timer nehmen und die CPU
solange in den idle sleep schicken.

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>würde ich auch nicht gerade als stromsparende Programmierung
>bezeichnen.  Dafür kann man auch einen Timer nehmen und die CPU
>solange in den idle sleep schicken.

Ich habe den Code etwas gekürzt. Eigentlich wird hier mit Soft-PWM 
gearbeitet, sodass die Hauptschleife wirklich immer laufen muss, wenn 
die Temperatur-Bedingung erfüllt ist.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nebenbei: "char" ist kein guter Datentyp für einen kleinen (und
noch dazu offenbar in der Erwartungshaltung vorzeichenlosen)
Integer.  Nimm uint8_t aus <stdint.h>.

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

hat keiner mehr eine Idee?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich habe diesen Stromverbrauch nun gemessen und sehe, dass der ATtiny13A
> im Sleep-Modus 50µA benötigt
Wie hast du den gemessen (nur uC oder gesamte Schaltung?) und woran 
siehst du das?

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mein Tiny13 (ohne A) verbraucht mit Brown-Out und mit Watchdog und mit 
Schaltung und einem Meßspannungsteiler 1MOhm um 40µA. Irgendwas ist bei 
Deiner Anordnung nicht richtig. Die LEDs sollen keine Vorwiderstände 
haben oder?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Martin wrote:

> hat keiner mehr eine Idee?

Hab ich doch oben schon geschrieben: Dreck auf der Platine,
insbesondere unter den Bauteilen.  Da ist schon so manches
Mikroampere drin versenkt worden.

Softwaretechnisch kannst du dich auch Stück für Stück
durcharbeiten: erstmal alle Pins auf Ausgang, die LED-Ausgänge
auf High, die Spannungsteiler-Ausgänge auf Low setzen, den
Chip (ohne Watchdog vorerst) in den Sleep schicken.  Der Strom,
den du dabei misst, wird später nicht mehr zu unterbieten sein.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuch mal:

DIDR0 = 0x3F;

Und den ADC abschalten vor dem Power-Down.


Peter

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So wie ich das sehe, wird der ADC wieder abgeschaltet, nachdem er 
gemessen hat.

Autor: Chris K. (chrisk86)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hat zwar nichts mit dem Thema zu tun, aber die LEDs haben keinen 
Vorwiderstand =)

Lg,
Chris

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sagte ich schon.

Autor: Chris K. (chrisk86)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ups, überlesen... Sorry ^^

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die LEDs sollen keinen Vorwiderstand haben, das ist schon in Ordnung so. 
Den Stromverbrauch habe ich mit einem Messverstärker gemessen und dabei 
die gesamte Schaltung berücksichtigt. Im Moment ist die Schaltung noch 
fliegend mit Fädeldraht aufgebaut. Ich möchte gerne 5-10µA erreichen. 
Ist das realistisch?

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Du alles richtig gemacht hast, ist es beinahe realistisch. Bei 
ausgeschaltetem Brownout und laufendem Watchdog solltest Du bei etwa 
15...20µA bei 3V landen. Ohne Watchdog und ohne Brownout sind es unter 
1µA.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Analog Comparator ist blödsinnigerweise von Haus aus eingeschaltet.

Autor: hotstuff (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Spannungsteiler (Temp-sensor und Widerstand) hochohmiger auslegen !

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Analog-Komparator ist im Power-Down automatisch aus.

Der Spannungsteiler wird von der Software vor dem Sleep abgeschaltet.

Autor: hans (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mir fehlen im Listing 2 Register, die Strom sparen:

13.2.2 ACSR– Analog Comparator Control and Status Register
hier
      Bit 7 – ACD: Analog Comparator Disable

und

7.5.3 PRR – Power Reduction Register


Evtl. wird es dann schon etwas besser.

gruß hans

Autor: Olli R. (omr) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Martin wrote:

> Ich habe diesen Stromverbrauch nun gemessen und sehe, dass der ATtiny13A
> im Sleep-Modus 50µA benötigt, was mir deutlich zu viel vorkommt (laut
> Datenblatt im nA-Bereich!).

Wie und womit gemessen?

Olli

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Wie und womit gemessen?
siehe obiges Posting
>Den Stromverbrauch habe ich mit einem Messverstärker gemessen

Den Watchdog kann ich natürlich nicht ausschalten... wie soll der µC 
denn sonst aufwachen, wenn es kalt wird?

Autor: Olli R. (omr) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Martin wrote:

>>Wie und womit gemessen?
> siehe obiges Posting
>>Den Stromverbrauch habe ich mit einem Messverstärker gemessen

Ist zwar keine wirkliche Antwort auf meine Frage, aber wenn Du meinst, 
Du misst richtig, wird's schon stimmen.

Olli

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Messverstärker ist auf den Bereich 100µA eingestellt und ist eine 
Stunde lang gelaufen bevor die Messung gestartet wurde. Es wurden 
geschirmte Kabel für die Messung verwendet. Das Ausgangssignal liegt 
dann zwischen 0V (0µA) und 10V (10µA). Den Wert habe ich mit einem 
Oszilloskop abgelesen, da ich den zeitlichen Verlauf sehen wollte 
(Sleep-Phase/Wach-Phase).

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.