Forum: Mikrocontroller und Digitale Elektronik ADC Stromverbrauch Tiny13


von gone g. (xcc)


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

von Martin (Gast)


Lesenswert?

Sind 22 mA für den ADC bein Tiny13 richtig?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.)

von gone g. (xcc)


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?

von Andreas K. (a-k)


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?

von gone g. (xcc)


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.

von Andreas K. (a-k)


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.

von gone g. (xcc)


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.:
1
if(ADCH>SENSETIVITY)
. Im Simulator braucht er dafür nur wenige Cycles.  Woran kann das 
liegen?



1
void save_power(void)
2
{
3
  cli();
4
  if(ADCH>SENSETIVITY)
5
  {
6
     if(seq_timer_active==0 || seq_timer_active==1)
7
   {
8
9
       MCUSR = ~(1<<WDRF);
10
       WDTCR = (1<<WDCE) | (1<<WDE);
11
       WDTCR = ((1<<WDTIE) | (1<<WDP0));
12
       MCUSR = ~(1<<WDRF);
13
       WDTCR = ~(1<<WDE);
14
       ADCSRA&=~(1<<ADEN);
15
       set_sleep_mode(SLEEP_MODE_PWR_DOWN);
16
       sleep_enable();
17
       sei();
18
       sleep_cpu();
19
   }
20
   }  
21
}

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

von avion23 (Gast)


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?

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.