Hat man einen Mikrocontroller wie den ESP8266 NodeMCU im Außenbetrieb, läuft dieser oftmals über portable Stromversorgung wie bspw. Akkus, Batterien oder Powerbanks. Daher ist es von enormer Bedeutung, dass der Stromverbrauch beim ESP8266 Batteriebetrieb möglichst gering gehalten wird.
Dafür hat der ESP8266 einen sog. „Deep Sleep“ Modus, in welcher der NodeMCU inaktiv ist und somit kaum Strom verbraucht – perfekt also für den Batteriebetrieb. Wie man diesen nutzt und welche Vorkehrungen dafür zu treffen sind, behandeln wir in diesem Tutorial.
Zubehör
Bei der mobilen Stromversorgung ist es natürlich besser ein Modul zu nehmen, welches optimiert ist. Falls du also nur einen bzw. zwei GPIO’s benötigst, ist ein ESP-01 besser als ein ESP-12 geeignet. Je nach Spannungsquelle (Batterie vs. Powerbank) sollte auch die Eingangsspannung beachtet werden, da bspw. das NodeMCU Development Board 5V benötigt.
- ESP8266 (bspw. ESP-01 oder ESP-12)
- Jumper Kabel
- ggf. Sensoren, Taster, Zubehör
Ich habe zum Test eine einfache LED genommen.
Daneben ist natürlich eine mobile Stromquelle erforderlich. Hierzu gibt es zwei Möglichkeiten:
- Powerbank (alternativ mit 10.000 mAH)
- 3.7V Li-ion Akku (Typ 18650)
Eine Powerbank hat den Vorteil, dass ggf. auch andere USB Geräte geladen werden können. Außerdem ist das NodeMCU Developer Board auch ohne weiteres damit zu betreiben.
Ein Lithium-Ionen Akku hingegen liefert nur 3.7V statt 5V, was aber für einen normalen ESP8266 (bspw. ESP-01) ausreicht. Allerdings ist zum Aufladen ein Ladegerät nötig, da diese Art von Akkus recht empfindlich ist. Wer ein Labornetzteil sein eigen nennt, kann die Li-ion Batterie auch gemäß dieser Anleitung aufladen.
Aufbau für den ESP8266 Batteriebetrieb
Der wichtigste Schritt, neben der Verkabelung der Sensoren, ist der Anschluss an die Stromquelle. Wer eine Powerbank nutzt, wird wohl kaum Schwierigkeiten haben, weshalb es anschließend nur kurz um die Verbindung einer Li-Ion Batterie geht (äquivalent für Li-po / Lithium-Polymer-Akkumulatoren).
Falls du ein 5V Modul verwendest, muss natürlich auch eine dementsprechende Spannung vorhanden sein.
Darüber hinaus muss der entsprechende Aufbau natürlich dem Ziel angepasst werden. So haben wir bspw. bereits einen Wetterstation Außenposten mit dem DHT22 Temperatur und Luftfeuchtigkeitssensor gebaut. Man könnte dieses Szenario nehmen und bspw. nur alle X Minuten eine Messung vornehmen und in der restlichen Zeit den ESP8266 schlafen lassen, sodass kaum Strom verbraucht wird.
Neben dem Anschluss der Sensoren etc. ist eine Verbindung von GPIO16 (D2) zu RST nötig, falls du den ESP8266 jeweils für eine gewisse Zeitspanne schlafen lassen möchtest. Die Alternative wäre die Pins nicht zu verbinden und ihn per Interrupt aufzuwecken, doch dazu später mehr. Hier der Schaltplan mit der beispielhaften Minischaltung einer LED:
Schaltbild
Software – Deep Sleep
Der „Deep Sleep“ Modus setzt den ESP8266 eine Weile in einen extrem stromsparenden Modus, in der nichts weiter ausgeführt wird. Nach der eingestellten Zeit wird ein Signal gesendet, womit der ESP neu startet – deshalb muss GPIO16 auch mit dem Reset verbunden werden, da sonst der Neustart nicht funktioniert:
This function can only be used in the condition that esp8266 PIN32(RST) and PIN8(XPD_DCDC aka GPIO16) are connected together. Using sleep(0) will set no wake up timer, connect a GPIO to pin RST, the chip will wake up by a falling-edge on pin RST.
Der Deep-Sleep Modus hat jedoch eine kleine Einschränkung: Und zwar ist die maximale Dauer auf ca. 71 Minuten begrenzt:
The maximum sleep time is 4294967295us, ~71 minutes.
Das sollte aber für die allermeisten Anwendungen reichen. Wer z.B. Temperatur o.ä. loggt, wird wahrscheinlich ein Zeitfenster unter einer Stunde nehmen.
Beginnen wir nun mit dem Aufspielen der Software über den ESPlorer. Wir werden zwei Dateien erstellen und übertragen, wovon die eine unsere „Logik“ enthält und die andere die „init.lua“ sein wird, welche beim Start aufgerufen wird.
Die erste Datei habe ich „dsleep.lua“ genannt und hat bei mir folgenden Inhalt:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
SLEEP_TIME = 60 -- max. 71 minutes (= 4294 sec) pin=4 gpio.mode(pin, gpio.OUTPUT) for i=1,3 do gpio.write(pin,1) tmr.delay(1000000) gpio.write(pin,0) tmr.delay(1000000) end node.dsleep(SLEEP_TIME * 1000000) |
Falls du einen Aufruf einer Webseite / API etc. machen willst, beachte dabei, dass der node.sleep()
Befehl in das Callback dieser Funktion muss. Ansonsten würde der ESP8266 in den Schlafmodus gesetzt, bevor der Aufruf der Website stattgefunden hat.
Nach dem Speichern und Übertragen dieser Datei, kümmern wir uns die „init.lua“:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
-- init.lua local SSID = "WLAN NAME" local SSID_PASSWORD = "password" wifi.setmode(wifi.STATION) wifi.setphymode(wifi.PHYMODE_N) --wifi.sta.config(SSID, SSID_PASSWORD) wifi.sta.config {ssid=SSID, pwd=SSID_PASSWORD} wifi.sta.autoconnect(1) tmr.alarm(1, 1000, 1, function() if wifi.sta.getip()== nil then print ("Waiting for Wifi connection") else tmr.stop(1) tmr.stop(2) print ("ESP8266 mode is: " .. wifi.getmode ( )) print ("The module MAC address is: " .. wifi.ap.getmac ( )) print ("Config done, IP is " .. wifi.sta.getip ( )) dofile("dsleep.lua") end end) -- if there is no connection after some seconds, stop trying to connect and go to deep sleep for a minute tmr.alarm(2, 10 * 1000, 1, function() tmr.stop(1) tmr.stop(2) if wifi.sta.getip() == nil then print("down", wifi.sta.getip()) node.dsleep(60 * 1000000) end end) |
Hier musst du natürlich den Namen und das Passwort deines WLANs eintragen. Ich habe in meiner Anwendung vorausgesetzt, dass eine Internet- bzw. Netzwerkverbindung besteht, bevor das andere Skript mittels dofile()
aufgerufen wird. Damit jedoch nicht dauerhaft versucht wird sich mit dem Wifi-Netzwerk zu verbinden (z.B. weil es nicht vorhanden ist oder die Daten falsch), habe ich eine Abbruchbedingung nach 10 Sekunden eingebaut. Sollte dies eintreten, wird der ESP8266 nach 60 Sekunden neu gestartet und ist in dieser Zeit im Stromsparmodus.
Mit diesem Beispiel wollte ich nur einmal zeigen, wie so eine Anwendung aussehen kann und darauf hinweisen, worauf geachtet werden muss. Du musst es natürlich nicht exakt so übernehmen, sondern solltest es entsprechend deinen Anforderungen anpassen.
Sobald die Datei übertragen wurde, wirst du sehen, wie die LED jede Minute zweimal kurz aufblinkt. Ich habe dieses Szenario nun schon viele Tage so mit meiner Powerbank, die ich auch im Roboter Projekt genutzt habe, getestet, ohne dass auch nur ein Balken abgenommen hat (bei minütlichem Aufwachen und Verbinden mit dem WLAN, was über 1400 Verbinden pro Tag entspricht). Bei längerem Schlafen kann man die Laufzeit entsprechend weiter erhöhen. Längere Sleep Zeiten ließen sich durch einen Counter ermöglichen: Wer bspw. alle 3 Stunden etwas ausführen möchte, der stellt einen 60 Minuten Timer und ließt bzw. schreibt den Wert in eine Datei. Wurde der Wert erreicht (3x60min), so kann die Aktion ausgeführt werden und der Counter wird zurückgesetzt. Ansonsten wird erneut eine Stunde geschlafen.
Möglichkeit 2: Interrupt
Falls du eine andere Anwendung hast, die bspw. nur dann Daten senden soll, sobald ein bestimmtes Ereignis auftritt (z.B. Aktivieren eines Bewegungsmelders, Durchlaufen einer Lichtschranke, etc.), so macht ein Aufwachen nach vorbestimmter Zeit natürlich keinen Sinn.
In diesem Fall nutzen wir:
node.dsleep(0)
Damit wird der Schlafmodus ausgelöst, jedoch wird er nicht mehr selbst erwachen (daher auch kein 71 Minuten Limit).
Dafür darf allerdings GPIO16 und RST nicht verbunden sein. Sobald das Ereignis ausgelöst wurde, senden wir ein kurzes LOW Signal („Falling Edge“) an den RST Pin. Dadurch startet der ESP8266 neu und wir können unsere Aktion ausführen (Serveraufruf, Daten an Raspberry Pi senden, etc.).
Sobald alles fertig ist, sollte der Mikrocontroller wieder in den „Deep Sleep“ Modus versetzt werden (us=0), um so auf den nächsten Interrupt zu warten und in der Zwischenzeit Strom zu sparen.
Je nach Auslastung und Anwendung ist es mit einer Li-ion Batterie, einem Li-Po Akku oder einer Powerbank möglich den ESP8266 NodeMCU über einen sehr langen Zeitraum mit Strom zu versorgen. Wer es schafft den Ladestatus auszulesen, könnte bei Bedarf sogar eine Email versenden, sobald die Kapazität zu gering wird. Wenn dich der ungefähre Zeitraum interessiert, kannst du mit einem Multimeter den Strom messen, der im Schlafmodus und während der aktiven Zeit gebraucht wird. Dadurch, das die Kapazität des Akkus / Powerbank bekannt ist, kannst du die ungefähre Dauer berechnen.
28 Kommentare
Hey, ein sehr interessanter Beitrag. Danke dafür. Was ich noch vermisse, ist ein eingehen auf das Thema Tiefentladung bei LiPo’s. Sprich: wie wird verhindert, das der LiPo unter 3,3V fällt und dann „kaputt“ ist?
Hallo Jan,
ich würde in diesem Fall ein TP4056 Modul nutzen.
https://dlnmh9ip6v2uc.cloudfront.net/datasheets/Prototyping/TP4056.pdf
Eine wirklich dumme Frage von mir, aber wo schließe ich denn eine Powerbank an den ESP8266 an? Da gibt es doch keinen Eingang für Mikro USB oder übersehe ich was?
Je nachdem welchen ESP du nutzt. Das Development Board hat einen micro USB Eingang.
Ich verwende ein ESP-01, aber wenn ich RESET mit GPIO0 verbinde (wie auf dem Bild gezeigt, blaues Kabel), bleibt das Board beim Starten in einer endlosen Reset-Schleife hängen. GPIO0 ist nach Anlegen von Spannung immer zunächst HIGH, und löst damit sofort ein Reset aus.
Sollte die Verbindung bei diesem Board so gemacht werden wie hier gezeigt?
http://www.instructables.com/id/Enable-DeepSleep-on-an-ESP8266-01/
Habe es ausprobiert, die Lösung von Instructables funktioniert.
Hallo,
im Netz liest man immer wieder das man zwischen Reset und D0 einen Widerstand verbauen soll. Was hat es damit auf sich?
In den letzten 4 Jahren ist der ESP8266 die beliebteste Wifi-Lösung für Hersteller. Die guten Spezifikationen und der günstige Preis machen die Konkurrenz wie RTL8710 schwer zu wachsen.
Aber manchmal ist Plan B tatsächlich notwendig. Vor kurzem die W600-Lösung W600 Arm WCon, die wir von Winner Micro herausgebracht haben. Wir glauben, dass sie mit ESP8266 ein gleichmäßiger Wettbewerber sein könnte.
Hallo, habe mir einen Nodemcu mit einem DHT22 aufgebaut der mir die Temperatur viertelstündlich an ioBroker sendet und danach in DeepSleep geht. Nun suche ich noch eine mobile Stromversorgung. Ein 9V-Block hält leider nur 2-3 Tage, also unbrauchbar. Was wäre da die beste Lösung? Möchte wenn möglich schon mindestens einen Monat hinkommen, wenn möglich auch länger.
Hallo,
ich lese das rein zufällig während ich auf der Suche nach einer TCP-Verbindung von ESP8266 zu Raspberry bin. Ich habe ebenfalls das Problem mit dem zu hohen Stromverbrauch. Dabei connected der ESP8266 nur 1s etwa alle 3 Minuten und sendet die Temperatur an einen Raspberry.
Das hat mir geholfen Strom zu sparen:
– ESP8266-01S (rein nur den Baustein, kein NodeMCU).
– Upload-Diode entfernt.
– Stromversorgung direkt mit 2 AAA-Batterien
Da ich immer wieder rumprobiere ist die Batteriehaltezeit noch nicht ganz sicher, aber 1 Monat ist bestimmt drin.
Ein Problem ist der hohe Stromverbrauch, wenn das Programm läuft – so ca. 70..90mA.
Im deepSleep() ist der Stromverbrauch etwa 20 Mikro-Ampere. Das ist wenig genug.
Nur sobald es Arduino-Arbeit gibt (z.B. weil der Raspberry nicht antwortet) kann man aufpassen, wie die Spannung nach unten geht. D.h. also, die aktive Arduino-Zeit muss noch geringer werden. Deshalb meine Suche nach einer effektiveren Verbindung zum Raspberry. Aktuell polle ich via „curl“ den Arduino und das benötigt mehrere Sekunden – nicht toll!
Grüße
Thomas
Hi Thomas,
ich würde es mal mit MQTT versuchen.
Grüße
Sven
Solarmodul in Kombination mit TP4056. Das dürfte ewig halten und eine 3,7 V LiO Batterie als Puffer. Das TP4056 lädt über Solarzelle den Akku auf, schaltet bei „Voll“ ab und sorgt bei leerem Akku für Tiefentladeschutz. Besser gehts nicht 😉
Danke für den super Beitrag, ABER. Die Idee mit der PowerBank funktioniert nicht – gerade die von Dir empfohlene hat ein unerwünschtes Feature: „Auto-Stopp, wenn das Telefon voll aufgeladen ist.“.
D.h. wenn der ESP in den Tiefschlafmodus geht zieht er so wenig Strom, dass die PowerBank abschaltet und dann wacht er leider nicht mehr auf 🙁
Da ich die PowerBank jetzt rumliegen habe überlege ich eine Schaltung mit einem Zwischenpuffer. Der müsste gerade so viel bringen, dass der ESP wieder aufwacht – dann startet auch die PowerBank wieder.
Hi, genau das Problem habe ich auch konntest du mittlerweile ein Lösung finden?
Das Problem ist bekannt und in der EU ist die Abschaltautomatik für Powerbanks Pflicht.
Man kann z.B. die Grundlast erhöhen in dem man etwas Strom über ein Transistor in einem Widerstand verbrät.
Mal die ersten zwei Google Treffer zu „powerbank schaltet ab“ lesen. 🙂
Nur eine nicht erprobte Idee von mir: Bevor die kürzest mögliche Zeit zur automatischen Abschaltung der PowerBank erreicht ist, lässt man den ESP für einen Moment aufwachen, damit ein ausreichend hoher Strom gezogen wird, damit die Nachlaufzeit der Powerbank erneut startet. Danach versetzt sich der ESP erneut in den Tiefschlaf bis zum nöchsten Aufwachen. Sei es ein Aufwachen, um einen weiteren Stromimpuls zu generieren oder das geplante Aufwachen, um Programm abzuarbeiten.
Schöne kurze Anleitung. Einen Hinweis zu den 71 Minuten. Das ist formal korrekt, kann aber mit etwas „tricksen“ stromsparend verlängert werden.
Aufgeweckt wird der ESP grundsätzlich immer nach spätestens 71 Minuten, aber was es dann zu tun gibt, das kann man ja steuern. So kann man sich z.B. in 2 von 3 Fällen einfach wieder schlafen legen. Das kurze Aufwachen zieht etwas Strom, aber da das Einschlafen schon vor WLAN-Aktivierung passiert, ist das nicht so tragisch. Um mitzuzählen über die Resets empfehle ich (Werbung, bin der Autor…) die RTCVars Bibliothek: https://github.com/highno/rtcvars
Ein Beispiel dabei macht nichts anderes als die Resets zu zählen. So ist auch ein Logging 2x täglich stromsparend möglich.
Hallo Lars,
ich habe deine Bibliothek heruntergeladen und auf den ESP8266 überspielt. funktioniert auch tadellos. Allerdings würde ich gerne bei einem „reset_counter“ Stand von z.b 5 auf zu einer Datei init.lua springen. Wie müsste ich sowas programmieren? Kann ich auf dem ESP eine Arduino Sketch und eine Lua Datei kombinieren?
Statt über die RTC die Daten zu speichern, könnte man aber doch auch mit dem Filesystem SPIFFS die Daten ablegen, oder gibt es gravierende Vorteile bei der RTC?
Bei SPIFFS wären die Daten auch noch nach einem Cold-Reboot bzw. Power off/on noch vorhanden.
Wie würdest Du das lösen?
Ich möchte den ESP über Nacht in den deep sleep versetzen, um Energie zu sparen.
Kann ich das lokal am ESP iwie lösen oder sollte ich den Schlafbefehl per MQTT vom Raspi (MQTT Server) an den ESP senden?
Frage ist aber da, wie ich den ESP wieder aufwecke. Ich kann ja keine Befehle senden, wenn der ESP am schlafen ist. Oder?
Oder ich sende alle 72 Minuten den Schlafbefehl wieder.
So hätte ich die Kontrolle über den ESP vom Raspi aus ^^
Hallo.
Warum ist denn oben im Bild beim ESP8266-01 der RST Pin mit GPIO0 verbunden ?
(Beim anderen kenne ich die Belegung nicht auswendig)
GPIO0 wird mit GND verbunden wenn man flashen also programmieren will.
Ansonsten bleibt der offen.
Ist das Bild falsch oder geht es hier um was anderes ?
Gruß
Mein Tipp: Autobatterie vom Wertstoffhof und ein gutes Step-Down-Modul. Hat man das passende Step-Down-Modul kann man bis zu 4-5 12 Volt Batterien in Reihe schalten, dann reicht der Saft ewig, bis es auch für den Stepper nicht mehr langt. Man glaubt nicht wie viele noch brauchbare Batterien weggeworfen werden.
Hallo AM.
Du willst die Batterien in Reihe schalten????
Macht 48 bis 60 Volt. Was soll das??
Auf das Thema 3,3V CPU und 3,7V oder höher Stromversorgung gehst du überhaupt nicht ein. Hier wäre zB ein MCP1700-3302E sehr hilfreich.
Zunächst mal Danke für deinen Beitrag, ich habe hier schon einige Ideen „klauen“ können.
Jetzt bin ich durch diesen Beitrag auf die Idee gekommen mit einem ESP8622 meinen Briefkasten etwas KI zu verpassen (Benachrichtigung bei öffnen).
Verstehe ich dies hier richtig:
„Sobald das Ereignis ausgelöst wurde, senden wir ein kurzes LOW Signal („Falling Edge“) an den RST Pin“
Ich kann damit den ESP8622 aus „node.dsleep(0)“ wecken kann indem ich Reset vorrübergehen auf GND setze?
Ich denke daran mittels Reed Kontakt GND durchzuschalten.
Sorry für die vielleicht blöde Frage, ich bin relativ neu in der Materie.
Kay
Das Bild passt nicht zum benutzen Akku oder?
Ich nutze meinen NodeMCU Amica mit einem Feuchtigkeitssensor und einem DHT jetzt seit zwei Wochen ohne Deep Sleep zur Überwachung im Gewächshaus. Betrieben mit einer PiwerBank mit 22Ah und Solarpanel. Bislang wirds nicht weniger.
http://ihr-it-profi.de/index.php