Forum: Mikrocontroller und Digitale Elektronik Reminder per Microcontroller realisieren


von Sascha M. (sfx2k)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich bin neu in Sachen µC, ja sogar neu in Sachen Elektronik allgemein.

Als erstes Projekt wollte ich mir einen Reminder bauen bzw. habe das 
auch bereits getan.
Das Ganze funktioniert, wie es soll, aber ich weiß, dass es sehr viel 
Optimierungspotenzial gibt. Und da wollte ich Euch um Unterstützung 
bitten.

Was möchte ich erreichen?
Ich möchte alle 15 Minuten an etwas erinnert werden.

Wie soll das geschehen?
Alle 15 soll eine LED für kurze Zeit blinken.

Ich habe zuerst mit dem Timer-IC 555 herumgespielt, bin aber nie soweit 
gekommen, dass nach 15 Minuten das gewünschte Ergebnis eintrat.
Entweder habe ich etwas falsch gemacht oder die Teile sind nicht auf 
eine so große Zeitspanne ausgelegt. Bei mir waren es jedenfalls immer 
>17 Minuten, obwohl ich die Dimensionierung der 
Kondensatoren/Widerstände so vorgenommen habe, wie ich es anhand einer 
Formel (die ich auf mehreren Seiten fand, die mir gerade aber nicht mehr 
geläufig ist) berechnet habe.
Des Weiteren erschien mir das mit den vielen Bauteilen auch irgendwie, 
naja, zu kompliziert und unzuverlässig. Wie auch immer...

Ich bin dann dazu übergegangen, das Ganze mit einem µC zu versuchen.
Ich habe mich für den Attiny85 entschieden, weil der schön klein ist und 
dennoch 2 Timer bietet, die ich laut meiner Vorüberlegungen benötigte.

Timer 1 läuft ~15 Minuten und aktiviert dann Timer 2, welcher das 
Blinken der LED realisiert und sich danach wieder selber deaktiviert.
Das funktioniert auch alles (auch wenn ich bei ~ 15 Minuten und 20 
Sekunden bin, aber das ist wahrscheinlich Feinjustierung)...

Betrieben wird die Schaltung mit einer 3,6 Volt AA Lithiumbatterie.
Die LED ist weiß und kann mit bis zu 3,4V betrieben werden.

Mittlerweile habe ich gelesen, dass ein AVR µC Pi*Daumen so viel Strom 
verbraucht, mit wieviel Spannung er betrieben wird, also etwa 3.3mA bei 
3.3V usw.
Demnach müsste meiner ja ~3.6mA verbrauchen, was mir erstmal recht hoch 
erscheint.

Ich hatte diese Batterie gewählt, da der µC mit 1,8V betrieben werden 
kann und die Spannung der Batterie ja immer weiter runter geht. Da 
dachte ich mir, wäre ein Puffer ganz gut...
Aber diese Entscheidung war wahrscheinlich schon nicht so optimal.

Jedenfalls ging ich davon aus, dass die Schaltung damit einige Zeit 
überleben kann.
Dann habe ich aber gesehen, dass man den Stromverbrauch durch 
Optimierungen drastisch senken und die Lebensdauer so selbst mit einer 
Knopfzelle auf mehrere Jahre erhöhen kann.
Leider bin ich noch nicht so weit vorgedrungen, um zu wissen, ob bspw. 
der IDLE-Mode bei mir überhaupt etwas bringen würde wegen des 
Programmcodes, der da in den Interrupt-Routinen beim Überlauf ausgeführt 
wird usw.
Am sinnigsten erschien mir bei Nachforschungen der Power-Save-Modus, den 
der Tiny85 allerdings nicht bietet...

Vielleicht könnt Ihr mir ein paar Tipps geben, die einerseits 
Optimierungen an meinem derzeitigen Vorgehen, also mit AVR µC aufzeigen 
(Power-Modes ausnutzen, Codeoptimierungen, generelles Vorgehen mit zwei 
Timern überhaupt sinnvoll usw., vielleicht ein RTC-Modul als externe 
Weckquelle für den AVR im Power-Down-Modus?) aber auch, wie man es 
vielleicht komplett anders machen kann.

Wie gesagt; ich stecke noch in den Kinderschuhen und weiß nicht, was es 
alles für Möglichkeiten gibt; Best Practices so zusagen.

Freue mich über Eure Kommentare.

Im Anhang findet Ihr noch meinen Schaltplan und den Quellcode.

von Peter D. (peda)


Lesenswert?

Man kann den ATtiny85 mit einem externen Uhrenquarz (32kHz) takten, dann 
kommt man auf <10µA.
Oder man setzt ihn in Power-Down und weckt ihn mit dem Watchdoginterrupt 
auf, der ist allerdings nicht sonderlich genau.

Der 555 ist für lange Delays ungeeignet, außerdem haben Elkos sehr hohe 
Toleranzen.

von Wolfgang (Gast)


Lesenswert?

Sascha M. schrieb:
> Die LED ist weiß und kann mit bis zu 3,4V betrieben werden.

LEDs werden grundsätzlich mit Strom betrieben. Die Spannung suchen sie 
sich anhand des Kennlinienfeldes U_f(Temperatur, Strom) selber aus.

von Boris O. (bohnsorg) Benutzerseite


Lesenswert?

Peter D. schrieb:
> Man kann den ATtiny85 mit einem externen Uhrenquarz (32kHz) takten, dann
> kommt man auf <10µA.

Man kann auch den internen Watchdog-Oszillator bei 128kHz nutzen. Ob bei 
wiederholter Rücksetzung nach 15min eine Genauigkeit von 1% Wesentlich 
ist, mag der TO für sich entscheiden. Aber mit dem Watchdog alle 8s 
wecken, einen uint8_t inkrementieren und nach 112 oder 113 im uint8_t 
blinken reicht dicke hin.

Bei höherer gewünschter Genauigkeit kann man den Temperatureinfluss noch 
über den integrierten Temperatursensor hinzunehmen. In der Hosentasche 
hätts ja >25° und auf dem Blechbriefkasten, draußen, im Winter <4°. 
Ansonsten ist der 128kHz-Oszillator ausreichen.

von THOR (Gast)


Lesenswert?

Sascha M. schrieb:

> Mittlerweile habe ich gelesen, dass ein AVR µC Pi*Daumen so viel Strom
> verbraucht, mit wieviel Spannung er betrieben wird, also etwa 3.3mA bei
> 3.3V usw.
> Demnach müsste meiner ja ~3.6mA verbrauchen, was mir erstmal recht hoch
> erscheint.

Wo kommt dieser Quatsch denn her?

https://www.google.de/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0ahUKEwiSg4uurO7QAhUCExoKHesEBvIQFghAMAA&url=http%3A%2F%2Fwww.atmel.com%2Fimages%2Fatmel-2586-avr-8-bit-microcontroller-attiny25-attiny45-attiny85_datasheet.pdf&usg=AFQjCNHsSR-VeIb2z8owMadLa4W-GKQpng&sig2=e3789VIV0X1hvvR_qoo1Gg

Datenblatt Figure 22-1

Du kommst da selbst mit laufender CPU locker unter 1mA.

Bei 15min kann man nen 32kHz Uhrenquarz nehmen, aber bei der kurzen 
Zeitspanne ist auch der interne 1MHz RC Oszillator genau genug.

1 MHz mit Timer1 und 16384 Prescaler auf 61Hz runterteilen, das ist dann 
dein Grundtakt. Den in Software weiter auf 1/15Min runterteilen.

Am Ende jeder Timer-ISR kannst du den µC in den Idle Mode schicken, den 
laut 7.1.1 wacht die CPU auch bei nem Timer Overflow aus dem Idle auf.

Da deine CPU kaum was zu tun hat, sollte Sie damit etwa 99% der Zeit im 
Idle sein. Das ist laut Fig 22-6 unter 150uA.

Guck auch mal bei 7.4 was man alles abschalten sollte.

von Sascha M. (sfx2k)


Lesenswert?

THOR schrieb:
> Sascha M. schrieb:
>
>> Mittlerweile habe ich gelesen, dass ein AVR µC Pi*Daumen so viel Strom
>> verbraucht, mit wieviel Spannung er betrieben wird, also etwa 3.3mA bei
>> 3.3V usw.
>> Demnach müsste meiner ja ~3.6mA verbrauchen, was mir erstmal recht hoch
>> erscheint.
>
> Wo kommt dieser Quatsch denn her?

z.B. von hier: Beitrag "Re: ATTiny85 an 6V Batterie möglichst lange betreiben"

von Sascha M. (sfx2k)


Lesenswert?

Hallo zusammen,

Euren Kommentaren, für die ich mich herzlich bedanke, entnehme ich, dass 
mein Vorgehen gar nicht soo falsch ist.

Ich sauge die Infos alle auf und freue mich über weitere Beiträge :)

von THOR (Gast)


Lesenswert?

Sascha M. schrieb:
> THOR schrieb:
>> Sascha M. schrieb:
>>
>>> Mittlerweile habe ich gelesen, dass ein AVR µC Pi*Daumen so viel Strom
>>> verbraucht, mit wieviel Spannung er betrieben wird, also etwa 3.3mA bei
>>> 3.3V usw.
>>> Demnach müsste meiner ja ~3.6mA verbrauchen, was mir erstmal recht hoch
>>> erscheint.
>>
>> Wo kommt dieser Quatsch denn her?
>
> z.B. von hier: Beitrag "Re: ATTiny85 an 6V Batterie möglichst lange
> betreiben"

Das gilt jeweils für 8MHz, das hättest du vielleicht erwähnen sollen. 
Für deine 15 Minuten Wartezeit sind 8MHz eher kontraproduktiv.

von Sascha M. (sfx2k)


Lesenswert?

THOR schrieb:
> Das gilt jeweils für 8MHz, das hättest du vielleicht erwähnen sollen.
> Für deine 15 Minuten Wartezeit sind 8MHz eher kontraproduktiv.
Sorry, ich dachte, das wäre allgemeingültig :(
Ich verwende den µC ja aktuell mit 8MHz - vielleicht sollte ich das 
Fusebit CKDIV8 doch lassen :)

THOR schrieb:
> 1 MHz mit Timer1 und 16384 Prescaler auf 61Hz runterteilen, das ist dann
> dein Grundtakt. Den in Software weiter auf 1/15Min runterteilen.
Sorry, ich fürchte, das habe ich nicht genau verstanden.
Wie mache ich das? Hättest Du ein Codebeispiel?

> Am Ende jeder Timer-ISR kannst du den µC in den Idle Mode schicken, den
> laut 7.1.1 wacht die CPU auch bei nem Timer Overflow aus dem Idle auf.
Hmm, okay. Aber wenn der µC bei jedem Timeroverflow wieder aufgeweckt 
wird - bringt das idlen dann überhaupt etwas? Ich meine, das Zählen geht 
ja schon schnell, somit auch viele Überläufe - mehr als vier pro 
Sekunde. Oder denke ich da falsch?

von Walter S. (avatar)


Lesenswert?

anderes Thema:
der 10Ohm Widerstand ist etwas klein. Bei 20mA fallen zwar die 0,2V ab 
die sich aufgrund der typ. Werte ergeben, die du angegeben hast
Aber da ist keine Toleranz berücksichtigt und moderne LED leuchten auch 
bei 5mA schon hell genug

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Sascha M. schrieb:
> Hmm, okay. Aber wenn der µC bei jedem Timeroverflow wieder aufgeweckt
> wird - bringt das idlen dann überhaupt etwas? Ich meine, das Zählen geht
> ja schon schnell, somit auch viele Überläufe - mehr als vier pro
> Sekunde. Oder denke ich da falsch?
Du denkst zu menschlich. Wenn der alle 250ms aufgeweckt wird und dann 
nach 25us schon wieder Schlafen geht, dann ist er nur für 100us pro 
Sekunde oder eben für 0,01% der Zeit aktiv. Der uC wird also eigentlich 
die allermeiste Zeit schlafen...

von Sascha M. (sfx2k)


Lesenswert?

Walter S. schrieb:
> anderes Thema:
> der 10Ohm Widerstand ist etwas klein. Bei 20mA fallen zwar die 0,2V ab
> die sich aufgrund der typ. Werte ergeben, die du angegeben hast
> Aber da ist keine Toleranz berücksichtigt und moderne LED leuchten auch
> bei 5mA schon hell genug

Okay, danke - das werde ich korrigieren!

Lothar M. schrieb:
> Sascha M. schrieb:
>> Hmm, okay. Aber wenn der µC bei jedem Timeroverflow wieder aufgeweckt
>> wird - bringt das idlen dann überhaupt etwas? Ich meine, das Zählen geht
>> ja schon schnell, somit auch viele Überläufe - mehr als vier pro
>> Sekunde. Oder denke ich da falsch?
> Du denkst zu menschlich. Wenn der alle 250ms aufgeweckt wird und dann
> nach 25us schon wieder Schlafen geht, dann ist er nur für 100us pro
> Sekunde oder eben für 0,01% der Zeit aktiv. Der uC wird also eigentlich
> die allermeiste Zeit schlafen...

Ja, so ungefähr hatte ich das auch befürchtet - menschliches Denken :)
Wenn man es ausrechnet und das prozentuale Verhältnis anschaut, dann 
machts Sinn!

Danke Euch beiden :)

von THOR (Gast)


Lesenswert?

Sascha M. schrieb:
> THOR schrieb:
>> 1 MHz mit Timer1 und 16384 Prescaler auf 61Hz runterteilen, das ist dann
>> dein Grundtakt. Den in Software weiter auf 1/15Min runterteilen.
> Sorry, ich fürchte, das habe ich nicht genau verstanden.
> Wie mache ich das? Hättest Du ein Codebeispiel?

Software-Counter:
1
uint16_t counter = 0;
2
ISR(timer1_vect)
3
{
4
  counter++;
5
if(counter == 54900)
6
{counter = 0;
7
LEDBlinkbeginn();
8
}
9
if(IdleAllowed())
10
{//Hier Idle Mode setzen}
11
}
Aus dem Kopf, ungetestet, 54900 ist nicht die genaue Zahl, Während dem 
LED-Blinken darf kein Idle stattfinden daher noch Hilfsvariable dafür 
hinzufügen. Das LED-Blinken kann mit delay_ms in main() implementiert 
werden oder mit dem Timer0.

von THOR (Gast)


Lesenswert?

Oder genaugenommen: Während dem LED-Blinken darf schon Idle stattfinden, 
aber das Programm wird einfacher wenn mans weglässt.

Die LED braucht eh diverse Größenordnungen mehr Strom als die CPU, ergo 
bringt Idle während des Blinkens kaum was.

von Sascha M. (sfx2k)


Lesenswert?

THOR schrieb:
> Sascha M. schrieb:
>> THOR schrieb:
>>> 1 MHz mit Timer1 und 16384 Prescaler auf 61Hz runterteilen, das ist dann
>>> dein Grundtakt. Den in Software weiter auf 1/15Min runterteilen.
>> Sorry, ich fürchte, das habe ich nicht genau verstanden.
>> Wie mache ich das? Hättest Du ein Codebeispiel?
>
> Software-Counter:
>
1
> uint16_t counter = 0;
2
> ISR(timer1_vect)
3
> {
4
>   counter++;
5
> if(counter == 54900)
6
> {counter = 0;
7
> LEDBlinkbeginn();
8
> }
9
> if(IdleAllowed())
10
> {//Hier Idle Mode setzen}
11
> }
12
>
> Aus dem Kopf, ungetestet, 54900 ist nicht die genaue Zahl, Während dem
> LED-Blinken darf kein Idle stattfinden daher noch Hilfsvariable dafür
> hinzufügen. Das LED-Blinken kann mit delay_ms in main() implementiert
> werden oder mit dem Timer0.

Ahh, okay. Dann habe ich Dich falsch verstanden mit dem 
Software-Counter.
Das ist ja das, was ich im Prinzip jetzt auch schon so mache (s. 
Quellcode main.c).
Vielen Dank, werde das heute Abend alles mal austesten :)

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.