mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ADC Stromverbrauch Tiny13


Autor: gone gone (xcc)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,

sobald ich in meinem Testprogramm den ADC einschalte, steigt die 
Stromaufnahme im Powerdown-Modus von einigen Mikroampere auf etwa 22 mA. 
Nun frage ich mich, ob es irgendeine Möglichkeit gibt den Stromverbrauch 
trotz aktiviertem ADC noch weiter zu reduzieren? Oder kann ich den ADC 
vielleicht einfach abschalten, obwohl der Mikrocontroller über einen 
externen Interrupt geweckt werden soll? Im Datenblatt steht dazu "To 
save power, the ADC should be disabled before entering any sleep mode", 
also gehe ich davon aus, dass es grundsätzlich möglich ist (obwohl ich 
mich frage, wie er dann aufwachen soll)?.

Den ADC vor dem einschlafen abzuschalten und in die ISR für den ext. 
Interrupt einfach ein ADCSRA|=(1<<ADEN); zu setzen klappt leider nicht.

danke

Dominik

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sind 22 mA für den ADC bein Tiny13 richtig?

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

Bewertung
0 lesenswert
nicht lesenswert
Dominik Hensler wrote:

> sobald ich in meinem Testprogramm den ADC einschalte, steigt die
> Stromaufnahme im Powerdown-Modus von einigen Mikroampere auf etwa 22 mA.

Das ist entschieden zu viel.  Du hast nicht zufällig eine Last an
AREF angeklemmt, die dann Strom zieht?

Laut den Diagrammen im Datenblatt braucht der ADC so zwischen 200 und
300 µA.

> Oder kann ich den ADC
> vielleicht einfach abschalten, obwohl der Mikrocontroller über einen
> externen Interrupt geweckt werden soll?

Ja, natürlich!  Was hat denn der externe Interrupt mit dem ADC zu
tun?

> (obwohl ich
> mich frage, wie er dann aufwachen soll)?.

Na, durch den Externinterrupt doch, oder was hast du konfiguriert?

> Den ADC vor dem einschlafen abzuschalten und in die ISR für den ext.
> Interrupt einfach ein ADCSRA|=(1<<ADEN); zu setzen klappt leider nicht.

Was genau klappt daran nicht?  (Außer dass du natürlich noch irgendwann
eine Konvertierung starten musst.  Im Prinzip gibt es auch keinen
Grund, ADCSRA an dieser Stelle mit irgendwas zu ver-oder-n, das kannst
du dort explizit neu zuweisen, da du ja den ADC ,from scratch'
startest in diesem Moment.)

Autor: gone gone (xcc)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch wrote:
> Dominik Hensler wrote:
>
>> sobald ich in meinem Testprogramm den ADC einschalte, steigt die
>> Stromaufnahme im Powerdown-Modus von einigen Mikroampere auf etwa 22 mA.
>
> Das ist entschieden zu viel.  Du hast nicht zufällig eine Last an
> AREF angeklemmt, die dann Strom zieht?
>
> Laut den Diagrammen im Datenblatt braucht der ADC so zwischen 200 und
> 300 µA.


Sorry, sollte 0,22mA heißen. Ist aber natürlich immer noch zu viel.


>
>> Oder kann ich den ADC
>> vielleicht einfach abschalten, obwohl der Mikrocontroller über einen
>> externen Interrupt geweckt werden soll?
>
> Ja, natürlich!  Was hat denn der externe Interrupt mit dem ADC zu
> tun?
>


Ich hatte gedacht, dass ein Pin Change Interrupt nur durch ein digitales 
Signal ausgelöst werden könnte.

>> (obwohl ich
>> mich frage, wie er dann aufwachen soll)?.
>
> Na, durch den Externinterrupt doch, oder was hast du konfiguriert?
>
>> Den ADC vor dem einschlafen abzuschalten und in die ISR für den ext.
>> Interrupt einfach ein ADCSRA|=(1<<ADEN); zu setzen klappt leider nicht.
>
> Was genau klappt daran nicht?  (Außer dass du natürlich noch irgendwann
> eine Konvertierung starten musst.  Im Prinzip gibt es auch keinen
> Grund, ADCSRA an dieser Stelle mit irgendwas zu ver-oder-n, das kannst
> du dort explizit neu zuweisen, da du ja den ADC ,from scratch'
> startest in diesem Moment.)

Er wacht leider nicht mehr auf. Hmm.. ich hatte den ADC am Anfang des 
Programms in den free running mode geschaltet. Aber wenn der ADC 
tatsächlich "from scratch" gestartet wird, werden beim wieder hochfahren 
wahrscheinlich alle für den Betrieb des ADC relevanten register 
zurückgesetzt?

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dominik Hensler wrote:

> Sorry, sollte 0,22mA heißen. Ist aber natürlich immer noch zu viel.

Mag dir es auch zuviel sein, es passt zum Datasheet.

> Ich hatte gedacht, dass ein Pin Change Interrupt nur durch ein digitales
> Signal ausgelöst werden könnte.

Und was hat das mit dem ADC zu tun?

Autor: gone gone (xcc)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Kaiser wrote:
> Dominik Hensler wrote:
>
>> Sorry, sollte 0,22mA heißen. Ist aber natürlich immer noch zu viel.
>
> Mag dir es auch zuviel sein, es passt zum Datasheet.
>
>> Ich hatte gedacht, dass ein Pin Change Interrupt nur durch ein digitales
>> Signal ausgelöst werden könnte.
>
> Und was hat das mit dem ADC zu tun?


Das Gerät erhält nur analogen Input. An dem verwendeten Inputpin des 
Mikrocontrollers hängen zwei Drähte. Wird der Stromkreis durch Berührung 
geschlossen, soll das Gerät aufwachen.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie schnell muss der reagieren? Möglicherweise reicht es, den Controller 
per Watchdog alle zig Millisekunden aufwachen zu lassen. Dann ADC 
einschalten, messen, wieder abschalten und schlafen legen.

Es dauert zwar einige Zeit bis der ADC stabil ist (vor allem die interne 
Referenz), aber wenn der Controller dabei nur 1% der Zeit läuft und 
dabei 1mA frisst, den Rest der Zeit aber nur 5µA, dann sind das im 
Mittel auch nur 15µA.

Autor: gone gone (xcc)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, hab es jetzt so gemacht wie in obigem Beitrag empfohlen (danke für 
den Tip, btw). In der Hauptschleife wird save_power() aufgerufen, wenn 
das Gerät idle läuft. Dort wird noch einmal geprüft ob der Stromkreis 
geschlossen ist, wenn nicht (das Gerät also tatsächlich idle ist) wird 
der Watchdog gestartet und das Gerät schlafen gelegt.
Klappt auch alles hervorragend, nur dauert die Abarbeitung des folgenden 
If-Statements ganze 12(!)Sek.:
if(ADCH>SENSETIVITY)
. Im Simulator braucht er dafür nur wenige Cycles.  Woran kann das 
liegen?



void save_power(void)
{
  cli();
  if(ADCH>SENSETIVITY)
  {
     if(seq_timer_active==0 || seq_timer_active==1)
   {

       MCUSR = ~(1<<WDRF);
       WDTCR = (1<<WDCE) | (1<<WDE);
       WDTCR = ((1<<WDTIE) | (1<<WDP0));
       MCUSR = ~(1<<WDRF);
       WDTCR = ~(1<<WDE);
       ADCSRA&=~(1<<ADEN);
       set_sleep_mode(SLEEP_MODE_PWR_DOWN);
       sleep_enable();
       sei();
       sleep_cpu();
   }
   }  
}

P.S.: SENSETIVITY ist =128, ADC läuft im free running mode.

Autor: avion23 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Dominik,
falls du nochmal reinschaust: Dein WDTCR register überschreibst du immer 
wieder. So kann das nicht funktioneren. Richtiger wäre WDTCR |= 
(1<<blub); o.ä.
Vielleicht sind im Rest des Codes ähnliche Dinger?

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.