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.
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.
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.
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.
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.
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"
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 :)
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.
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?
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
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...
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 :)
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.