Grundlagenverständniss: Timer2-Asynchron + Powersave

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Grundlagenverständniss: Timer2-Asynchron + Powersave

      Hallo!

      Mache mir gerade Gedanken zum Thema Stombedarf minnimieren:
      Gegeben ist ein ATmega324PA ohne Hauptquarz (läuft mit intern RC 8MHz) allerdings mit 32,768kHz Uhrenqarz an Timer2.

      Grob angeplant ist:

      BASCOM Source Code

      1. Config Clock = Soft , Gosub = Sectic
      2. Enable Interrupts
      3. Do
      4. Select Case Aufgabe
      5. Case = 1 : Gosub Aufgabe1
      6. Case = 2 : Gosub Aufgabe2
      7. Case = 3 : Gosub Aufgabe3
      8. end select
      9. Gosub schlafen
      10. loop
      11. Sectic:
      12. If _sec = 5 then Aufgabe = 1 , end If
      13. If _sec = 10 then Aufgabe = 2 , end If
      14. If _sec = 45 then Aufgabe = 3 , end If
      15. Return
      16. Aufgabe1:
      17. 'Meßbefehle absenden
      18. Aufgabe = 0
      19. Return
      20. Aufgabe2:
      21. 'Meßwerte einlesen und formatieren
      22. Aufgabe = 0
      23. Return
      24. Aufgabe3:
      25. 'Datensatz versenden
      26. Aufgabe = 0
      27. Return
      28. Schlafen:
      29. 'Externe Geräte in Sleepmode setzen.
      30. 'µC in Sleepmode setzen
      31. Config Powermode = Powersave
      32. Return
      Display All

      Gedacht ist es, das der µC die meißte Zeit im Powersave-Mode (alles aus, ausser Timer2 als RTC) liegt.
      Jede Sekunde soll in der Sectic geschat werden ob die Zeit für eine bestimmte Aufgabe gekommen ist, und entsprechend ein Aufgabenbyte setzen.
      Nach verlassen der Sectic soll die Do-Loop-Schleife ein mal durchlaufen werden, um zu prüfen ob eine Aufgabe ansteht.
      Danach soll wieder in den Powersave-Mode gewechselt werden.

      Das Datenblatt spricht davon das dass Programm nach dem Aufwachen unmittelbar hinter dem letzten Sleep-Befehl fortgesetzt wird.
      Das wäre dann oben das Return in Zeile 41, welches zurück in die Do-Loop-Schleife führt.

      Aufgrund Zeile 1 wird aber die Sectic angesprungen.
      Wohin führt dann das Return in Zeile 22?
      Zum Return in Zeile 44, oder in die Hauptschleife, oder irgendwo anders hin?

      Und by the Way noch was:
      Wenn ich das Datenblatt richtig verstehe könnte ich mir mit TIMER2_COMPA / COMPB zusätzliche Interrupts zwischen den vollen Sekunden basteln, qausi auf 3,9ms Auflösung. Funktioniert das bei Verwendung des Timer2 als asnchrone RTC oder taugt das nur für PWM-Anwendungen?

      Grüße

      Jürgen
    • Nach dem Aufwachen springt er in die main, der sectic wird schon anliegen, daher ein Sprung in die sectic und von da wieder in die main.

      Die compare gehen meiner Meinung nach immer. Man ist hier halt bisschen eingeschränkt, weil man die Zählweite des timers nicht ändern kann/darf.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Der Return in Zeile 22 ist das Ende der ISR-Routine, die durch Config Clock=Soft... konfiguriert wird wird.
      Das vermute ich zumindest mal ganz stark. Es ist also ne Interrupt-Routine.

      Das Return in Zeile 44 gehört zu dem Aufruf in der Hauptschleife. (Gosub Schlafen).

      Damit dürfte klar sein, wohin die Returns führen.

      Was mir unklar ist, ob due Soft-Cklock überhaupt weiter läuft, wenn du im Power-Save Mode bist. Und wie der Controller geweckt wird.
      Üblicherweise wird der Sleep-Mode durch einen Interrupt ausgelöst, der auch eine ISR_Routine haben sollte.

      Zur letzten Frage. (By the way)

      Wenn der Timer extern getaktet wird, hängt es vom Power-Down-Mode ab, ob er auf die Compare-Interrupts überhaupt reagiert und wach wird.
      Kaum macht man es richtig - und schon geht's!
    • Hallo Mitch,
      man braucht keinen Compare_Interrupt, um die PWM nutzen zu können. Dazu braucht der Controller nicht mal aufzuwachen, wenn er mit Powersave schlafen geschickt wurde. Der Timer2 läuft ja dann durch und beim Erreichen des Compare-Wertes wird der Ausgang gesetzt. Dazu muss der Timer2 nur in den Fast-PWM Mode gesetzt werden, nachdem Config Clock=Soft durchlaufen wurde.
      Aber: eine PWM mit 1Hz?
    • Hallo!

      Vielen Dank an alle! Lag ich also nicht wirklich falsch mit meinem Schlachtplan..:-)


      Mitch64 wrote:

      Was mir unklar ist, ob due Soft-Cklock überhaupt weiter läuft, wenn du im Power-Save Mode bist. Und wie der Controller geweckt wird.Üblicherweise wird der Sleep-Mode durch einen Interrupt ausgelöst, der auch eine ISR_Routine haben sollte.

      Das dürfte kein Problem sein:
      Die ATmegas habe mehrere unterschiedliche Sleepmodes die einzeln konfiguriert werden können.
      Der Modus Powersave ist dabei der Sleepmode der alles abschaltet bis auf den asynchronen Timer2 als RTC (mit 32,768kHz Uhrenquarz).
      Bei jedem Überlauf des 8Bit-Timers wird der Interrupt TIMER2_OVF ausgelöst welcher den µC aufweckt.

      Guenther wrote:

      Aber: eine PWM mit 1Hz?
      Ne, gennau das nicht. Viel mehr ging es um die Idee mit oben gezeigtem Quellcode feinere Zeitauflösungen fest zu stellen.
      Aktuell nur eine Idee die es warscheinlich nicht braucht.
      Aber mal angenommen:
      Eine Aufgabe die in Sekunde 49 stattfinden soll, müsste im ms-Bereich verzögert werden, sagen wir um 80ms.
      Das könnte man (ungenau) machen indem man in der jeweilegen Aufgaben-Sub ein "Waitms 80" einfügt.
      Ungenau zumindest in meinem Fall wo der Haupttakt über den internen RC-Oszillator mit irgendwas zwischen 7,2~8,3MHz läuft.

      Meine Überlegung war das eventuell genauer (RTC-genauigkeit) hin zu bekommen, indem ich z.B. TIMER2_COMPA auf 21 setze und in der Aufgabe dann nach Sekunde 49 auf den Interrupt COMPA-Match warte.

      Ich weis aber noch nicht ob ich das wirklich brauche. Die Idee entsprang aus der Idee die Stromeinsparung zu maximieren:
      Es geht um Sensoren die einmal je Minute Meßwerte versenden sollen.
      µC zusammen mit Sensoren ziehen activ 6~7mA @ 3,3V. Da die Stromquelle ein 600mAh LiPo ist, soll die activ-Zeit auf das notwendigste (1-50ms je Minute) beschränkt werden, damit der Lipo deutlich länger als 3-4 Tage hält. Angestrebt sind 4-6 Monate, gerne mehr.

      Grüße

      Jürgen
    • Klar kannst du das so machen. In Sekunde 49 setzt du dann den OCR2 auf den gewünschten Wert (denke daran, dass der bei 0 startet), enablest dann den Compare2 und löschst das schon gesetzte Flag. In der Compare2 ISR disablest du den Interrupt dann wieder.
      Aufgrund der Auflösung von 3.9ms wirst du natürlich manchmal auch nicht besser mit der Genauigkeit sein als mit dem Waitms. Aber das scheint hier ja auch nicht soooooo wichtig zu sein.

      Wenn du weniger als 1% Duty Cycle hast (60ms/Minute) dann sollte es möglich sein, mehrere Monate hinzubekommen. Hängt natürlich auch davon ab, wieviele µA deine Schaltung im PowerSave zieht.
    • Hallo!

      Guenther wrote:

      Klar kannst du das so machen. In Sekunde 49 setzt du dann den OCR2 auf den gewünschten Wert (denke daran, dass der bei 0 startet), enablest dann den Compare2 und löschst das schon gesetzte Flag. In der Compare2 ISR disablest du den Interrupt dann wieder.
      Aufgrund der Auflösung von 3.9ms wirst du natürlich manchmal auch nicht besser mit der Genauigkeit sein als mit dem Waitms. Aber das scheint hier ja auch nicht soooooo wichtig zu sein.

      Wenn du weniger als 1% Duty Cycle hast (60ms/Minute) dann sollte es möglich sein, mehrere Monate hinzubekommen. Hängt natürlich auch davon ab, wieviele µA deine Schaltung im PowerSave zieht.

      Was die Zeitgenauigkeit angeht:
      Mir geht es darum in dem Projekt aufgrund möglichst langer Akkulaufzeit das Timing möglichst exakt zu planen.
      Mit Abstand der hungrigste Verbraucher in der ganzen Schaltung ist ein RFM69W Funkmodul, welches im aktiven Zustand (senden oder empfangen) Peaks zwischen 16-20mA zieht. Diese Aktivphasen umfassen insgesamt etwa 100ms je Minute.
      Ein Sendedurchgang umfasst 27ms + Umschatzeit ca. 30ms.
      Der Empfang dagegen ist problematischer:
      Am Anfang der Sekunde 0 einer jeden Minute soll ein 27ms lang erwartetes Paket empfangen werden.
      Die Gegenstelle (Sternpunkt sendet es irgendwann zwischen 1-10ms nach Wechsel von Sekunde 59 auf 00.
      Damit der akkugespeißte Empfänger möglichst exakt dieses Fenster trifft, wäre eine exakte Schrittweite von 3,9ms schon besser als 1000ms.
      Schaffe ich das Empfangsfenster exakt zu timen würde ich für den RFM69W einen Energiebedarf von 33,3µA über 1 Minute erreichen.

      Der Strombedarf insgesamt ist aktuell noch theoretisch (Datenblatt-Werte).
      Über mein angestrebtes Timing komme ich so auf einen Energiebedarf, gemittelt über eine Minute, auf knapp 135µA, was bei einer nagelneuen und intakten LiPo (600mAh) theoretisch knapp 6,6Monate reichen sollte.

      Nicht berücksichtigt, weil m.E. nicht wirklich ausschlaggebend, die drei PullUp's in der Schaltung:
      Einen 100k PullUp habe ich am /SS des SPI-Busses zum RFM. Wird dieser auf Low gezogen, wären das theoretisch 33µA.
      Da aber der SPI mit 2MHz läuft und maximal 30Bytes je Minute darüber laufen, reden wir da maximal über 120µs je Minute.
      Dann zwei PullUp's am I²C wo inklusive Adressen gerade mal 12Bytes je Minute drüber laufen, mit 400kHz, also rund 240µs Verkehr je Minute.

      Weitere Kalkulation ohne reale Messungen erübrigen sich erst mal, weil die Spannung natürlich nicht langzeitstabil ist:
      Zwischen LiPo-Zelle und Schaltung sitzt ein PWM-PFM-Schaltwandler (TPS62203) welcher mit 88-95% Wirkungsgrad @ 1MHz Taktrate den Eingangsbereich 3,3-4,2V effizient auf 3,3V am Ausgang regelt.
      Sinkt die LiPo unter 3,3V schaltet der Regler auf 100% Duty Cycle, ein externer Resetbaustein (STM1061) begrenzt die minimal zulässige Resetspannung auf 2,8V.

      Ach ja, der theoretische Wert von 135µA könnte noch kleiner sein, so etwa 90-100µA, wenn ich nicht schon über ein Problem gestolpert wäre:
      Um in diesem Projekt (Vcc 2,8-3,3V) hinreichend gut die LiPo (2,9-4,2V) mit dem ADC vermessen zu können, habe ich mir eine analoge Rechenschaltung auf die Platine gesetzt. Ein Einzel-OP als Subtrahierer welcher die Referenzspannung 2,500V (MCP1700-2502) zubtrahiert, währen Aref auf 1,800V gesetzt ist.
      Habe ich schon dutzende male so gemacht und funktioniert perfekt.
      Strombedarf ist niedrig, aber eben nicht 0.
      Daher habe ich diese Rechenschaltung mittels N-FET + P-FET schaltbar gemacht. Um eben diesen Schaltungsbereich nur dann zu aktivieren, wenn eine ADC-Messung ansteht. Dumm ist aber eine Latenz: Aktiviere ich die Rechenschaltung und lasse den ADC messen, sind die Meßergebnisse in den ersten 200ms müll.
      Erst wenn ich mindestens 250ms warte, haben sich die Spannungen so stabilisiert das der ADC auf +-2mV exakte Werte kommt.
      Später muss ich gucken welcher ADC-Meßzyklus sinn macht...alle 10h oder 24h eine Akkumessung sollte eigentlich reichen.

      Grüße

      Jürgen
    • Hallo!

      Michael wrote:

      Um Strom zu sparen, würde ich den AVR direkt an die Lipo Zelle hängen.
      Wenn der RFM nicht mit 4,2 V klar kommt, dann den Wandler schaltbar machen.
      Die Batteriemessung kann der AVR ohne stromhungrige und langsame analoge Schaltung.
      Einen Resetbaustain hat der AVR auch schon eingebaut.

      Neben dem RFM69W via SPI hängen da noch zwei I²C-Sensoren mit am ATmega324PA, die alle im Datenblatt spezifiziert sind mit Absolut Max. 3,6V.
      Daher habe ich mich für komplett Vcc = 3,3V als Maximalspannung bzw. dem Spannungsfenster 2,8-3,3V entschieden. Machte mehr sinn als unnötige Pegelwandler mit drauf zu setzen.
      Die ADC-Messung der Akkuspannung sollte möglichst exakt sein, eben da es um eher lange Entladezeiten geht.
      Und das ist die Krux:
      Spannungsmessung direkt ohne externe Referenz ginge ausschließlich über die interne 2,56V-Ref der ATmegas.
      Die zieht unnötig Strom ohne das sie eine nennenswerte Genauigkeit an den Tag legt.
      Vcc direkt als Aref geht nicht, weil Vcc ja identisch mit der Zellspannung wäre.

      Um dennoch was brauchbares an ADC-Meßwerten zu erreichen, braucht man eine externe Spannungsreferenz.
      Ein MCP1700-1802 in SOT-23 kostet weder Platz noch sonderlich Strom: Schlappe 1,6µA. Dafür hat man tatsächlich eine Aref von 1,800V +-2%, absolut rauschfrei und linear reguliert. Wenn der Abstand wie bei mir mit 1V zu Vcc-Min (2,8V) hinreichend ist, bleibt die Aref auch stabil innerhalb ihrer 2%.
      Das ist um Dekaden genauer als die interne 2,56V die eher 2,5xV hat, und spätestens unter Vcc=3V absurd wird als Referenz.

      Die analoge Rechenschaltung ist zwar "langsam", aber nur relativ. Nach dem Einschalten steht die ADC-Meßspannung nach 40µs exakt an.
      Im Prinzip diese Schaltung:



      Der OP ist bei mir ein MCP6241 mit 50µA Strombedarf.
      Alle Widerstände 100k mit 1% Toleranz.
      An E2 liegt die LiPo-Spannung (2,8-4,2V).
      An E1 hängt ein MCP1700-2502 welcher ebenso aus der LiIo gespeißt wird und exakte 2,500V bereitstellt.
      Ua bildet die Differenz Vbat - 2,500V = 300mV - 1700mV.
      E2, U+ des OP und der MCP2502 hängen gemeinsam über einen P-FET schaltbar an Vbat.
      Was die "Langsamkeit" angeht: Der MCP6241 hat nur eine SlewRate von 0,3V/µs.
      Daher kann ich am Oszi sehen das Ua etwa 20-40µs (je nach Akkuspannung) braucht um ein exakten Meßpegel zu erreichen.
      Sprich: Bei 4,114V LiPo nach einschalten des P-FET's steigt Ua rasant (eben innerhalb 40µs) von 0 auf 1614mV an und bleibt stabil.
      Dennoch spuckt der ADC da völlig chaotische Werte aus, wenn ich nicht mindestens 200ms bis zum getadc warte.

      Gut, um im Sleepmode Powersave unnötigen Strom zu sparen deaktiviere ich vor Powersave den ADC und starte ihn erst wieder wenn eine Messung ansteht.
      Zumindest laut Datenblatt sollte das ganze aber innerhalb von einstellige ms startklar sein, nicht erst nach 200ms.

      Ist aber kein wirkliches Problem. Es bringt mich im jetzigen Evaluationsstadium zwar ins grübeln, jedoch im Wirkbetrieb fallen diese 200ms nicht mehr ins Gewicht.
      Denn bei einem durchschnittlichen Durchschnittsstrom irgendwo zwischen 60-135µA an einem 600mAh-LiPo wird es eher Sinn machen nur alle 10-24h eine ADC-Messung zu machen. Und schon machen die insgesamt theoretischen 50µA (MCP6241) + 1,6µA (2,5V-LDO) nichts mehr aus.


      Guenther wrote:

      Michael wrote:

      Die Batteriemessung kann der AVR ohne stromhungrige und langsame analoge Schaltung.
      Ich habe bei mir einen Spannungsteiler mit insgesamt 2MOhm (also 2µA), da geht die AD Wandlung ganz normal. Obwohl irgendwo steht, dass der Eingang niederohmig (also einige 10k) sein sollte.

      Meine Erfahrungen mit dem ADC der ATmegas:
      Geht es um schnarchlangsame Meßsignale, beispielsweise die Batteriespannung einer hinreichend großen Zelle, spielt die Impedanz der Signalquelle kaum eine nennenswerte Rolle. Schnarchlangsam heißt hier für mich: Pegelverläufe im Minuten oder Stundenbereich.

      Sobald es hingegen um Meßsignale geht die geschaltet werden oder aufgrund ihrer Herkunft eben nur kurz anliegen (Sekunden oder Bruchteile davon), ist eine sinvolle ADC-Messung nur realistisch bei möglichst niederohmigen Signalquellen.
      Im Regelfall verwende ich seit Jahren daher Operationsverstärker vor den ADC-Eingängen, welche beliebig hochohmige Signale am Eingang mit mehreren mA Kraft hinreichend schnell an den ADC-Pin treiben.

      Und dann gibt es noch einen Aspekt der Operationsverstärker sehr interessant macht am ADC:
      Der 10Bit-ADC kennt werte zwischen 0 und 1024 mit einer Schrittweite von Aref / 1025.
      Bei Aref =5V also in einer Schrittweite von 4,878mV oder bei Aref 3,3V in einer Schrittweite von 3,22mV.

      Um diese Meßauflösung von grob 5mV oder 3mV zu behalten, muss sich die Meßspannung jedoch im Bereich GND und Aref befinden.
      Sobald man gezwungen ist die Meßspannung durch einen Spannungsteiler so zu teilen das die zu erwartende Meßspannung knapp unter Aref fällt, teilt sich die Meßauflösung im gleichen Verhältniss.
      Beispiel 12V-Bleiakku:
      Man kann mit einem 3:1 Spannungsteiler z.B. 20k + 10k die an einem 12V Bleiakku erwartbaren Spannungen auf Aref=5V runter holen.
      Die erzielbare Meßauflösung verdreifacht sich aber dann von 4,878mV auf etwa 14,63mV.
      Wem das an Meßauflösung reicht, der kann das so machen.
      Jedoch, was für Werte erwartet man an einem Bleiakku, die wirklich interessieren?
      Macht es z.B. Sinn an einem 12V Bleiakku den Bereich 1-9V zu messen um feststellen zu können das der Akku kaputt ist?
      Vielmehr interessieren Spannungen zwischen 10,8 und 14,8V was die interessanten Exremwerte wären: Bei 10,8V wäre der Akku leer und schon im Bereich der Tiefentladung, am Rande seines Lebens. 13,2-13,8V wäre seine angestrebte Pufferspannung, und 14,4-14,6V die maximal zulässige Ladespannung am Ende einer Schnelladung.
      Der Spannungsbereich der also in dem Fall von Interesse wäre, liegt also eher 10,8-14,8V und hat eine Dynamik von 4V.
      Und den kann man mit einer Auflösung von 4,878mV mittels 10Bit-ADC vermessen.
      Man muss nur die untere Spannungsgrenze auf theoretisch GND holen.
      Genau das macht der Subtrahierer oben:
      Er zieht von der Meßspannung eine exakte Referenzspannung ab (Umess - Uhilfsspg) und gibt die Differenz aus.
      Zurück zum Bleiakku:
      Man nehme einen möglichst exakten Spannungsregler der die gewünschte Differenz von 10V an den Subtrahierer legt, und der OP macht aus Umess = 10-15V dann Uadc 0-5V mit nativer ADC-Auflösung (4,878mV).

      Grüße

      Jürgen
    • Um Vcc zu erfassen ist keine externe Beschaltung nötig. Mit adc(31) mißt er 1,1V und das ergibt einen Wert aus dem man die Betriebsspannung errechnen kann. Diese 1,1 Volt sind zwar Chip unterschiedlich aber innerhalb jedes Chip sehr stabil. Muß man nun noch den Unterschied zwischen 2,95V und 3V erkennen, könnte er sich bei jeder Volladung (4,2V) selbst eichen.
    • Hallo Michael!

      Michael wrote:

      @DG7DJ
      Noch mal zum Verständnis:
      Der AD-Wandler ist mit der internen Refernz nicht genau genug, um eine leere Batterie zu erkennen?
      Welche Rolle spielt es, ob du das bei 3,0 oder bei 2,95 V erkennst?
      Der Akku ist dann schlicht leer.

      Wenn es nur um eine "1bit"-Entscheidung ginge in der Art "Akku leer" oder "Akku voll" bräuchte es überhaupt keinen ADC.
      Den braucht es nur wenn man etwas mehr Aussagekraft haben will. Und von den verfügbaren 10Bit fast 6Bit zu verschenken für einen Wertebereich der aussagt "so tiefentladen das LiPo kaputt!" macht auch nicht viel Sinn.
      Zumindest nicht wenn man höhere Anforderungen hat:

      Diese Sensoren sind für Orte gedacht wo ich nicht mal eben kurzfristig ran komme.
      Daher will ich anhand der Akkuspannung und deren Historie abschätzen können, ob ich da in den nächsten 4 Wochen laden muss, oder nicht.
      Und warum bitte soll man die verfügbaren 10Bit nicht mit externer 1,800V-Referenz entsprechend einer Schrittweite von 1,76mV nicht nutzen?
      Zumal braucht man da nix zu kalibrieren: Sorgt man bei MCP1700 für mindestens 400mV mehr Eingangsspannung als sie ausspucken sollen, kann man sich auf sehr exakte Ausgangsspannungen verlassen. Diese LDO's sind so genau das man manch preiswertere Multimeter daran kalibrieren kann.
      Das die interne 2,56V-Referenz in den ATmegas da nicht mal ansatzweise ran kommt, sieht man schon in den Datenblättern.
      Halbwegs brauchbar sind die nur bei stabiler Vcc und Temperatur und Kalibrierung (nachmessen der exakten 2,xxV am Aref-Pin).

      Grüße

      Jürgen
    • Hallo!

      Pluto25 wrote:

      Um Vcc zu erfassen ist keine externe Beschaltung nötig. Mit adc(31) mißt er 1,1V und das ergibt einen Wert aus dem man die Betriebsspannung errechnen kann. Diese 1,1 Volt sind zwar Chip unterschiedlich aber innerhalb jedes Chip sehr stabil. Muß man nun noch den Unterschied zwischen 2,95V und 3V erkennen, könnte er sich bei jeder Volladung (4,2V) selbst eichen.
      Hmm, hab da nochmal im Datenblatt geschaut.
      Das die 1,1V eine Bandgap-Referenz ist, die man bei "single ended" nicht verwenden soll, also wohl nur für differenzielle Messungen gedacht ist.
      Das man eine BandGap durchaus zur Vcc-Messung missbrauchen kann ist irgendwo logisch, denn eine echte Referenz ist mit bandGap nicht möglich. Wann immer irgendein Chip eine BandGap-Referenz hat ist sie immer sehr abhängig von der Betriebsspannung.
      Aber dazu gedacht ist sie wohl nicht, zumindest finde ich im Datenblatt keinen Hinweis darauf.

      Grüße

      Jürgen