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?
TEMP_VCC_ON;// NTC-Spannungsteiler mit Strom versorgen
48
49
intresult;
50
ADMUX=1;
51
52
ADCSRA=(1<<ADEN)|(1<<ADPS1)|(1<<ADPS0);
53
ADCSRA|=(1<<ADSC);
54
while(ADCSRA&(1<<ADSC)){}
55
result=ADCW;
56
result=0;
57
ADCSRA|=(1<<ADSC);
58
while(ADCSRA&(1<<ADSC)){}
59
result=ADCW;
60
ADCSRA&=~(1<<ADEN);
61
62
TEMP_VCC_OFF;// Spannungsteiler stromlos machen
63
64
returnresult;
65
}
66
67
intmain()
68
{
69
// Ausgänge
70
DDRB=(1<<LED_RED)
71
|(1<<LED_GRN)
72
|(1<<LED_BLU)
73
|(1<<PIN_TEMP_VCC);
74
75
76
// LEDs abschalten
77
BLU_OFF;
78
GRN_OFF;
79
RED_OFF;
80
81
// Temperaturmesser
82
DDRB&=~(1<<PIN_TEMP_MEA);
83
84
// Watchdog und Sleep-Modus initialisieren
85
initSleep();
86
87
// LEDs anschalten?
88
charon=1;
89
90
// Temperaturmess-Verzögerung
91
inttemp_count=0;
92
93
// PWM-Variable
94
charpwm=0;
95
96
// Wenn es zu warm ist -> Sleep
97
if(temp()<=TEMP_THRESHOLD)
98
{
99
fallAsleep();
100
}
101
102
// Hauptschleife
103
while(1)
104
{
105
// Alle 512000 Zyklen die Temperatur messen und prüfen ob der Schwellenwert unter- oder überschritten wurde
106
if(pwm==255)
107
{
108
temp_count++;
109
if(temp_count==2000)
110
{
111
on=(temp()>TEMP_THRESHOLD);
112
temp_count=0;
113
}
114
}
115
++pwm;
116
117
if(on)
118
{
119
stayAwake();// Reset-Counter zurücksetzen
120
RED_ON;
121
GRN_ON;
122
BLU_ON;
123
/* 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. */
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.
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. ;-)
// Alle 512000 Zyklen die Temperatur messen und prüfen ob der Schwellenwert unter- oder überschritten wurde
2
if(pwm==255)
3
{
4
temp_count++;
5
if(temp_count==2000)
6
{
7
on=(temp()>TEMP_THRESHOLD);
8
temp_count=0;
9
}
10
}
11
++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.
>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.
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>.
> Ich habe diesen Stromverbrauch nun gemessen und sehe, dass der ATtiny13A> im Sleep-Modus 50µA benötigtWie hast du den gemessen (nur uC oder gesamte Schaltung?) und woran
siehst du das?
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?
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.
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?
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.
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
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
>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?
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
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).
Eine eigene Frage?
Dieser Thread ist über 17 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.