Wie kann ich meinen atmega328 dazu bringen, ein Jahr lang mit Batterien zu laufen?

Szenario

Ich habe ein schönes elektronisches Türschloss für meinen Schlafsaal erstellt. Es ist derzeit ein Arduino Diecimila mit einem Servo, der die Tür [un]verriegelt. Es hat eine numerische Tastatur mit 3x4 Tasten und 5 LEDs (2 Reihenpaare und eine einzelne LED). Es läuft derzeit auch auf einem Handy-Ladegerät.

Ich habe es jetzt so umgestaltet, dass es auf einem eigenständigen Arduino (ATmega328) läuft, aber ich würde es wirklich gerne mit AA-Batterien oder sogar einer 9-V-Batterie laufen lassen.

Für den Softwareteil dachte ich, ich könnte sleepAnrufe für bestimmte Zeiten innerhalb der Schleifenmethode platzieren, um den Stromverbrauch des ATmega so gering wie möglich zu halten. Und lassen Sie die LED's mit möglichst langer Pause "blinken".

Frage 1

Wenn eine Taste während der wenigen Millisekunden gedrückt wird, in denen das Board schläft, wird sie "erinnert"/"gehalten", bis sie aus dem Ruhezustand kommt, und dann als Tastendruck aufgenommen?

Was wäre der beste Weg, um mit diesem Knopfdruck im Schlaf umzugehen? Kann ich es so codieren, dass es bei Tastenbetätigung aufwacht, oder muss ich es einfach für zB 10 ms schlafen lassen? in jeder Schleife?

Frage 2

Wie würde ich die Mathematik angehen, um zu berechnen, wie viele AA-Batterien benötigt werden, um dieses Gerät 10 Monate lang zu betreiben?

Außerdem weiß ich nicht, wie ich den durchschnittlichen Stromverbrauch pro Minute oder so messen soll, da er schnell wechselt usw.

Das Gerät

Mein Türschlossgerät

Antworten (7)

Der Atmega328 bietet sechs Energiesparmodi, geordnet von minimal bis ausgezeichnet (geschätzter Stromverbrauch aus diesem Forumsbeitrag ):

  • SLEEP_MODE_IDLE: 15 mA
  • SLEEP_MODE_ADC: 6,5 mA
  • SLEEP_MODE_PWR_SAVE: 1,62 mA
  • SLEEP_MODE_EXT_STANDBY: 1,62 mA
  • SLEEP_MODE_STANDBY: 0,84 mA
  • SLEEP_MODE_PWR_DOWN: 0,36 mA

Zitat der ursprünglichen Frage:

Ich dachte, ich könnte sleepAufrufe für bestimmte Zeiten in die Schleifenmethode einfügen "

Sie müssten sleep_cpu()nach dem Einrichten den gewünschten Schlafmodus aus der obigen Liste verwenden. Der Arduino Playground hat dazu einen nützlichen Beitrag .

Die Anwendung muss unterbrechungsgesteuert sein, die oben genannten Schlafmodi ausgiebig verwenden und den Prozessor bei Tastendruck, Timer-Überlauf und Watchdog-Timer-Ereignissen aufwecken, um Aufgaben tatsächlich auszuführen.

Zusätzliche Energieeinsparungen können durch die folgenden Schritte erreicht werden:

  • Verwenden Sie den internen Oszillator des Mikrocontrollers und eine niedrige Taktrate (8 MHz statt 16) - aber stellen Sie sicher, dass zeit- und zeitbezogener Code weiterhin wie erwartet funktioniert. Hierfür ist möglicherweise eine andere Version des Bootloaders erforderlich.
  • Vermeiden Sie es, LEDs lange eingeschaltet zu lassen, wenn die Anwendung sie verwendet. Die Verwendung eines schnellen Doppel- oder Dreifachblitzes von kurzer Dauer (0,05 Sekunden an, 0,5 Sekunden aus) mit Pausen von Sekunden dazwischen gewährleistet eine deutliche Anzeige bei minimalem Stromverbrauch
  • Verwenden Sie einen Schaltregler anstelle eines linearen, wenn ein Regler erforderlich ist.
  • Betreiben Sie den Mikrocontroller mit niedrigerer Spannung, falls unterstützt, 3,0 Volt (z. B. CR2032-Lithiumzelle, kein Regler erforderlich) oder 3,3 Volt anstelle von 5 Volt.
  • Befolgen Sie die Empfehlungen im Datenblatt für unbenutzte Eingangs- und Ausgangs-Pin-Einstellungen für minimale Energieverschwendung.

Durch die Einbeziehung dieser Vorschläge können Mikrocontroller-Anwendungen wochen- oder monatelang mit einer einzigen CR2032-Knopfzelle und jahrelang mit einer Lithiumzelle vom Typ LR123 ausgeführt werden. Natürlich kann Ihre Laufleistung variieren, je nachdem, welche Sensoren, Ausgänge und tatsächlichen Verarbeitung Ihre Anwendung erfordert.

Einige nützliche Referenzen:

Nach meiner Erfahrung können Sie es in SLEEP_MODE_PWR_DOWN auf 0,1 uA bis 6,0 uA reduzieren, wenn Sie schlau waren, alles auszuschalten (wie die Brown-Out-Erkennung). Ich habe Builds erstellt, die weniger als 60uA verbrauchen und mit einem Satz AA-Alkalibatterien 3-5 Jahre halten.
@TimEckel Ich bin verrückt danach, den Status mit LEDs anzuzeigen - das verbraucht das Strombudget, als würde es aus der Mode kommen.
Es muss nicht. Verwenden Sie Hochleistungs-LEDs mit hohem Widerstand. Wird einen Bruchteil eines mA statt über 20 mA verwenden. Lassen Sie außerdem die Status-LED alle paar Sekunden für 5–15 ms blinken, anstatt ständig zu leuchten. Ich hatte eine billige Dimmstatus-LED, die 30 mA verbrauchte. Ich änderte sie in eine Hochleistungs-LED mit einem 3,3-kOhm-Widerstand, den ich alle 8 Sekunden für 15 ms blinken ließ. Ging von 30 mA auf 2,9 uA Durchschnittsstrom, 1/1000 der Leistung!
@TimEckel Du verstehst das Ausmaß meiner Leidenschaft für blinkende Lichter offensichtlich nicht :-D Es ist nicht so, als ob ich die Intensität reduzieren möchte, ich mag diese kleinen Dinger, die wie die Flammen des Hades glitzern, verflixt mit dem Energiebudget! Um es ernster zu nehmen: Ich kenne diese kleinen Tricks und habe tatsächlich ein paar eigene entwickelt, die die Wirkung des visuellen Alarms erhöhen und gleichzeitig die Leistung durch die LEDs reduzieren. Dieser vorherige Kommentar war ( nur teilweise ) ein Scherz, passend zu den vielen lustigen LED-Fragen, die ich hier beantworte.
Ich habe den Stromverbrauch von ATMega328P bei verschiedenen Spannungen und Frequenzen gemessen und dieses Diagramm erstellt docs.google.com/spreadsheets/d/…

Ich habe gerade einen Arduino Pro Mini auf meinem Schreibtisch, der mit 2 AA-Batterien betrieben wird und bei Bedarf über ein Jahr laufen könnte.

Es gibt drei Aspekte des Designs, die dies erreicht haben.

1. Ein anderer Regler

Ich verwende einen Aufwärtsregler LTC3525. Es hat einen sehr niedrigen Ruhestrom (7 uA) und einen hohen Wirkungsgrad (> 90 % bei 0,2 mA). So etwas wie dieses Sparkfun-Board https://www.sparkfun.com/products/8999 sollte einen ähnlichen Job machen. Stellen Sie sicher, dass Sie es an den 5-V-Pin des Arduino anschließen, nicht an VIN, damit der Arduino-Regler nicht verwendet wird.

2. Schlafeeeeep

Der Anteil der Zeit, in der das Gerät aktiv ist, wird gering sein. Für den Rest der Zeit sollte das Gerät im SLEEP_MODE_POWER_DOWN schlafen. Sie können Ihre Schlafroutinen auf der Rocketscreem Low Power Library aufbauen . Laut diesem Link sollten Sie in der Lage sein, es auf 1,7 uA zu bringen, wenn ADC, BOD und WDT ausgeschaltet und im Abschaltmodus sind.

3. Unterbrechungen

Die andere Hälfte des Schlafes besteht aus Unterbrechungen, um ihn aufzuwecken. Im Power-Down-Schlafmodus werden nur Level-Interrupts auf INT1 und INT2, TWI übereinstimmen, und der WDT wird ihn aufwecken. Sie müssen also eine Taste entweder an INT1 oder INT2 anschließen, damit das Drücken der Taste ihn aufweckt.

Andere Sachen:

Schalten Sie alle LEDs aus, sofern nicht unbedingt erforderlich. Wenn sich das Schloss im Innenbereich befindet, müssen die LEDs nicht hell sein, wodurch mehr Strom gespart wird. Auch wenn die MCU regelmäßig eine Aufgabe ausführen muss, verwenden Sie den Watchdog-Timer, um sie regelmäßig aufzuwecken.

Bearbeiten:

Eine Methode, die funktionieren könnte, besteht darin, die obige Low-Power-Bibliothek zu verwenden und dank des Watchdog-Timers in jeder Schleife für beispielsweise 60 ms zu schlafen. Beim Aufwachen auf Tastendruck prüfen. Die aufzurufende Funktion wäre

LowPower.powerDown(SLEEP_60MS, ADC_CONTROL_OFF, BOD_OFF);

Alle diese Kommentare sind genau richtig. Ich möchte noch ein paar Anregungen hinzufügen:

1) Verwenden Sie für LEDs 20-mA-LEDs mit hoher Ausgangsleistung. Hier ist die Logik. Angenommen, Sie möchten eine schwache Status-LED, die alle 8 Sekunden blinkt. Sie möchten nicht, dass es hell ist, also verwenden Sie eine zufällige LED. Das Problem ist, dass eine dunkle LED immer noch 20 mA (oder mehr) verbraucht, um nur 100 mcd auszugeben. Holen Sie sich stattdessen eine Hochleistungs-LED, die immer noch für 20 mA ausgelegt ist, aber 4000 mcd ausgeben kann (achten Sie darauf, dass Sie sich den Ausgangswinkel ansehen, Sie möchten wahrscheinlich immer noch, dass er 30 Grad oder mehr beträgt). Mit dieser 4000-mcd-LED verbinden Sie sie mit so etwas wie einem 3,3-kOhm-Widerstand und Sie erhalten eine Lichtleistung von etwa 100 mcd, verbrauchen jedoch weniger als 1 mA. Anstatt 20 mA für die Status-LED zu verwenden, verwenden Sie also einen Bruchteil eines einzelnen mA. Ich stelle die Status-LED-Blitzzeit normalerweise auch auf nur 5-15 ms ein, was auch viel Strom sparen kann, wenn Sie zuvor die Blitzzeit auf 100 ms eingestellt hatten.

2) Mein Spannungsregler der Wahl ist der Microchip MCP1700. Es verbraucht nur 1,6 µA Ruhestrom und ist supergünstig (ca. 0,30 $ in kleinen Mengen). Die einzige Einschränkung besteht darin, dass die maximale Eingangsspannung nur 6 Volt beträgt, sodass Sie keine 9-Volt-Batterie verwenden können. Aber es ist perfekt für 4 AA-Batterien, einen einzelligen LiPo oder zwei Lithium-Knopfzellen.

3) Zur Stromversorgung eines ATmega-Schaltkreises mit 4 AA-Batterien verwende ich normalerweise eine 1N4001-Diode an VCC, um die maximalen 6 Volt der 4 Batterien auf 5,5 Volt zu senken. Außerdem schützt die Diode den ATmega vor Sperrspannung, so dass sie zwei nützlichen Zwecken dient. Auf diese Weise kann ich eine batteriebetriebene Schaltung erstellen, die im Schlaf nur 0,1 µA verbraucht, da kein Spannungsregler ständig Strom verbraucht.

Ich habe einen Test auf einer nackten atmega328P-PU auf einem Steckbrett mit der RocketScream LowPower-Bibliothek durchgeführt

Habe diese Skizze verwendet:

#include "LowPower.h"

void setup(){}

void loop()
{
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);         
    delay(5000);
}

Mit einem uCurrent Gold habe ich im Power-Down-Modus 7,25 uA gemessen.

Nett! Ich werde das so schnell wie möglich versuchen. Erlaubt dies, einen atmega238 jahrelang mit einer CR2032-Batterie zu betreiben?

Hier gibt es zwei Fragen, aber nur die zweite ist wirklich Teil des Fragentitels, daher ist es wahrscheinlich besser, wenn Sie eine weitere für die Frage zur Arduino-Programmierung öffnen. Die zweite Frage beantworte ich hier.

Eine einzelne 1,5-V-AA-Alkalibatterie der Spitzenklasse hat eine Kapazität von etwa 2600 mAh. Wenn Sie sich für Lithiumbatterien entscheiden, können Sie mit etwas Glück etwa 3400 mAh erhalten. Lassen Sie uns mit dieser Zahl als Grundlage für den absoluten Best-Case gehen.

Die Art und Weise, wie Sie die theoretische maximale Laufzeit für eine Last berechnen, ist einfach Kapazität geteilt durch Last. Wenn Ihre Last 1 mA beträgt, können Sie sie 3400 / 1 = 3400 Stunden = 141 Tage = ~ 5 Monate laufen lassen. Dies ist jedoch nur ein theoretisches Maximum , da Sie in dieser Zeit einen signifikanten Spannungsabfall von etwa 65 % erhalten. Wenn Sie den Ausgang regulieren, erhalten Sie einen außer Kontrolle geratenen Effekt, bei dem je niedriger die Batteriespannung ist, desto mehr Strom wird benötigt, um die geregelte Spannung aufrechtzuerhalten, wodurch die Batterie schneller entladen wird. Ich wäre überrascht, wenn Sie mehr als 80 % der beworbenen Kapazität mit einer Spannung herausholen könnten, die hoch genug ist, um Ihr Gerät zu betreiben.

Nehmen wir also an, dass Sie 80 % dieser Zeit nach Spannungsabfällen und Reglerineffizienzen erhalten. Wir gehen davon aus, dass Sie mit 3,3 V aus drei Batterien in Reihe laufen. Dadurch erhalten Sie immer noch die gleiche Kapazität, aber die Spannung reicht für einen Regler aus. Wenn Ihr Gerät mit 15 mA läuft (das ist eine eher konservative Schätzung), sehen die Zahlen so aus:

  • Kapazität nach 80 % Effizienz = 3400 * 0,8 = 2720 mAh
  • Zeit = 2720 / 15 = 181 Stunden = 7,54 Tage

Sie benötigen also etwa 144 Lithium-Batterien (48 3er-Sets), um es ein Jahr lang zu betreiben. Nicht so gut!

Ich würde vorschlagen, stattdessen eine geregelte Gleichstromversorgung aus dem Netz zu verwenden. Ein Batterie-Backup kann eingebaut werden, das einfach mit einem SPDT-Relais eingerichtet werden kann - schließen Sie einfach die Spule an das Gleichstromnetz an und verbinden Sie den "Aus"-Kontakt mit der Batterie. Wenn der Gleichstrom ausfällt, fällt der Kontakt ab und die Batterie wird stattdessen verwendet.

Meine kabellosen Träume sind zerstört ;) Danke für die ausführliche Antwort. Dies schien mir auch die beste Option zu sein.
Diese Frage stellte ich mir zufällig auch bei der Entwicklung eines elektronischen Türschlosses. Selbst mit einem klobigen 10.000-mAh-Akku hat es sich nicht gelohnt. Am Ende wurde nur ein 250-mA-Gleichstromadapter und ein alter Handyakku als Backup verwendet.
15 mA Durchschnitt klingt für mich nicht sehr konservativ! Der 328 kann im Schlafmodus mit einstelligen Mikroampere betrieben werden, und Sie könnten sicherlich damit davonkommen, ihn die meiste Zeit zumindest im Halbtiefschlaf zu haben. Auch bei niedrigen Frequenzen (z. B. 0,5 MHz) kommt man im aktiven Modus mit <1 mA aus. Natürlich müssen andere Komponenten (Spannungsregler usw.) ausgewählt werden, um der Niedrigleistungsnatur zu entsprechen.
@exscape LED4 allein zieht 15 mA. Durch Aktivieren von S1, S2 oder S3 werden aufgrund der Pullups jeweils weitere ~0,5 mA gezogen.
@Polynomial Ich habe mir den Schaltplan nicht genau angesehen, aber das Projekt könnte sicherlich ohne "Power-LED" erstellt werden. Oder Sie könnten es blinken lassen, so dass es z. B. bei halber Helligkeit (über PWM) nur für etwa 25 ms alle 2 Sekunden eingeschaltet ist, sodass der Stromverbrauch auf durchschnittlich ~ 0,09 mA statt 15 sinken würde.
@exscape Das stimmt. Vielleicht ist es doch möglich, ihn fast ein Jahr lang mit ein paar Lithium-AA-Batterien zu betreiben, wenn Sie etwas zusätzliche Arbeit investieren, um den Verbrauch zu senken. Ich würde mir vorstellen, dass die durchschnittliche Alkalibatterie nicht besser als 4-6 Monate sein würde.
Arduino ist machthungrig. Der Bau eines eigenen Boards würde dies lösen. Atmega328 zieht 0,2 mA bei 32 kHz und 0,75 uA im Energiesparmodus.

Etwas, das noch niemand erwähnt hat: Sie müssen eine Möglichkeit haben, die +5-V-Versorgung abzuschalten, die das Servo mit Strom versorgt, wenn Sie es nicht verwenden. Auch wenn es sich nicht bewegt, zieht ein Servo immer noch Strom.

Ein FET, dessen Gate von einem E / A-Pin des Arduino gesteuert wird, ist eine gute Möglichkeit, dies zu tun.

Ich verwende normalerweise einen 2N3904 für jeden Sensor oder was auch immer, um ihn ein- / auszuschalten. Oder, wenn der Sensor wenig Leistung hat und die gleiche Spannung wie das, was ich mit dem ATmega betreibe, verwende ich einfach einen Pin direkt, um den Stromstatus zu steuern.
Verwenden Sie einen 2n7000, um deutlich weniger Strom zu verbrauchen als einen 2n3904, und Sie benötigen keinen Basiswiderstand.

Sie könnten in Betracht ziehen, für Ihr nächstes Design einen Mikrocontroller zu verwenden, der speziell für geringen Stromverbrauch optimiert ist. Für einen geringen Stromverbrauch ist es notwendig, während des Schlafens sehr wenig Strom zu sich zu nehmen. Was oft übersehen wird, ist, dass es auch wichtig ist, wie schnell es aus diesem Schlaf erwachen kann.

Was zählt, ist, wie viel Ladung aus dem tiefsten Schlaf benötigt wird, um einen Interrupt so schnell wie möglich zu verarbeiten (weil der Stromstoß dann sehr kurz sein wird) und wieder einzuschlafen.

Ein Beispiel für einen solchen Mikrocontroller ist MSP430 von Texas Instruments. Auf ihrer Website finden Sie Anwendungshinweise zur Energieeinsparung und Energiegewinnungsanwendungen.