MicroPython: Schlafmodus (lightsleep und deepsleep)

Neben dem Normalbetrieb hat der RP2040 des Raspberry Pi Pico zwei Schlafmodi, mit denen der RP2040 extrem wenig Strom verbraucht. Das kann helfen, die Batterielaufzeit bei batteriebetriebenen Geräten zu verlängern.

  • SLEEP State
  • DORMANT State

Wenn man einen Raspberry Pi Pico mit MicroPython programmiert hat man allerdings nicht die Möglichkeit direkt in diese Betriebsarten umzuschalten. Allerdings hat MicroPython zwei Befehle, die den Mikrocontroller in einen Schlafzustand versetzen.
Wenn der Schlafmodus aktiviert ist, wird der Prozessor in einen Zustand versetzt, der weniger Energie verbraucht als im normalen Betrieb. Der Prozessor bleibt in diesem Zustand, bis ein Ereignis auftritt, das den Prozessor wieder in den normalen Betriebszustand versetzt.

Befehl: machine.lightsleep

Die Implementierung, um den Raspberry Pi Pico zeitweise in den Schlafmodus zu versetzen, ist vergleichsweise einfach. Hierfür verwendet man den Befehl „lightsleep“ mit einem Parameter, der die Dauer des Schlafmodus in Millisekunden (ms) angibt.

# 5000 ms = 5 Sekunden
machine.lightsleep(5000)

Wird das Kommando „machine.lightsleep“ mit einer Zeit in Millisekunden (maximal 72 Minuten) als Parameter aufgerufen, dann passiert folgendes:

  • Die interne RTC läuft weiter.
  • Externe Schnittstellen-Verbindungen werden unterbrochen.
  • Der RP2040 kann mit einem Timer-Alarm aufgeweckt werden.

Wird das Kommando „machine.lightsleep“ OHNE Parameter aufgerufen, dann muss folgendes berücksichtigt werden:

  • Der RP2040 schaltet in den Dormant Mode, aus dem er Software-seitig nicht aufgeweckt werden kann.
  • Zum Aufwecken muss vorher ein Register gesetzt werden, um ihn mit einem GPIO aufwecken zu können.

Wie groß ist der Stromverbrauch bei „machine.lightsleep“?

Der Stromverbrauch in diesem Zustand liegt unterhalb von 0,001 A. Mein USB-Messgerät konnte nur „0.000 A“ anzeigen.
Andere Quellen sprechen von 0,9 bis 1,5 mA. Für einen Batterie-Betrieb ist das ein optimaler Wert.

Kann man „time.sleep_ms“ durch „machine.lightsleep“ ersetzen?

Die Frage ist, welchen Zweck hat das „time.sleep_ms“ und welche Komponenten hängen am Mikrocontroller dran, mit der eine Kommunikation erfolgen soll.

Wenn „time.sleep_ms“ nur den nächsten Schritt im Programmcode verzögern soll, wird ein „machine.lightsleep“ nicht sehr viel bringen. Insbesondere dann nicht, wenn der Mikrocontroller mit Sensoren und Aktoren über Schnittstellen kommuniziert. Problematisch ist das auch, wenn Ein- und Ausgabe-Steuerungen von GPIOs erfolgen und zeitabhängig sind. Beispielsweise dann, wenn ein GPIO geschaltet werden sollte, der Programmcode aber im Schlafzustand ist.

Wann ist „machine.lightsleep“ also sinnvoll? Grundsätzlich immer dann, wenn der Programmcode seine Schuldigkeit getan hat und innerhalb einer größeren Zeitspanne nichts mehr zu tun ist. Diese Zeitspanne kann natürlich schon ein paar Sekunden sein. Interessant wird es dann, wenn der Mikrocontroller nur sehr wenig tun muss und sich deshalb hauptsächlich im Schlafmodus befinden sollte, weil dann erst ein Batterie-Betrieb möglich ist.

Wenn also der Schlafmodus der Grundzustand des Mikrocontrollers ist, dann hat man „machine.lightsleep“ am sinnvollsten eingesetzt.

Befehl: machine.deepsleep

Die Implementierung, um den Raspberry Pi Pico zeitweise in den Tiefschlaf zu versetzen, ist vergleichsweise einfach. Hierfür verwendet man den Befehl „deepsleep“ mit einem Parameter, der die Dauer des Tiefschlafs in Millisekunden (ms) angibt.

# 5000 ms = 5 Sekunden
machine.deepsleep(5000)

Wird das Kommando „machine.deepsleep“ aufgerufen, dann werden die meisten Systemfunktionen ausgeschaltet, einschließlich der CPU und anderer Peripheriegeräte. Nur einige wichtige Funktionen, wie beispielsweise die Interrupt-Behandlung, bleiben aktiv.

Wird das Kommando „machine.deepsleep“ mit einer Zeit in Millisekunden als Parameter aufgerufen, dann ist das die maximale Zeit in Millisekunden, die der Ruhezustand dauern wird.

Unterschied zwischen lightsleep und deepsleep

Das genaue Verhalten und die Energiesparfunktionen von lightsleep und deepsleep hängen vom Mikrocontroller ab. Im Allgemeinen gelten folgende Annahmen:

  • Im „lightsleep“-Modus bleibt das RAM und alle Zustände erhalten. Beim Aufwachen kann der Programmcode ohne Einschränkungen genau nach dem Punkt fortgesetzt werden, an dem der Ruhezustand ausgelöst wurde.
  • Im „deepsleep“-Modus bleibt das RAM und alle Zustände möglicherweise nicht erhalten. Das heißt, mann muss beim Aufwachen den Programmcode so konzipieren, dass der Programmcode von vorne beginnt. Ähnlich, wie bei einem Hard-Reset.

Probleme durch „machine.deepsleep“ und mögliche Lösungen

Ein „machine.deepsleep“ führt dazu, dass die logische Verbindung über den USB zwischen Pico und Host-Computer beendet wird. Das bedeutet, man kann den Pico nicht mehr programmieren, sobald „machine.deepsleep“ ausgeführt wurde. Das ist insbesondere dann ein Problem, wenn der Programmcode automatisch bei der Inbetriebnahme mit „main.py“ gestartet wird und der Pico relativ schnell mit „machine.deepsleep“ in den Tiefschlaf versetzt wird. Dann hat man unter Umständen keine Zeit mehr, um das Programm mit einer Entwicklungsumgebung zu stoppen. Die einzige Methode, den Pico wieder programmieren zu können, ist den Pico auf Werkseinstellungen zurückzustellen und eine neue Firmware draufzuspielen.

Aber, es gibt natürlich Lösungen, um dem Raspberry Pi Pico die Möglichkeit zu geben, ein „machine.deepsleep“ zu umgehen.

Lösung 1: Programm beim Neustart pausieren lassen

Zu Beginn des Codes kann man mit „time.sleep(15)“ den Programmcode für 15 Sekunden pausieren lassen, was in der Regel reichen sollte, um nach dem Anstecken mit der Entwicklungsumgebung die Ausführung des Programmcodes zu stoppen.
Nachteilig ist, dass dadurch die Dauer, bis er Pico etwas macht, unnötig erhöht wird. Wenn man auf einen Stromsparbetrieb aus ist, dann will man das vermeiden.

Eine Erweiterung dazu wäre, dass diese Pause nur dann erfolgt, wenn ein bestimmter GPIO-Eingang einen bestimmten Zustand hat. Auf einem Steckbrett lässt sich so etwas mit einem Verbindungskabel realisieren. Auf einer Platine oder einem Festaufbau ginge das mit einem Jumper, einer Steckbrücke oder sogar einem Taster.

wait_time = 15
wait_pin = machine.Pin(15, machine.Pin.IN, machine.Pin.PULL_UP)
if not wait_pin.value(): time.sleep(wait_time)

Ist die Brücke gesetzt, dann wird die Pause gemacht, ansonsten läuft der Programmcode einfach weiter. Das liese sich noch mit einer Status-LED kombinieren.

Lösung 2: „time.sleep“ statt „machine.deepsleep“

Wenn die Pause beim Start unerwünscht ist, aber die Lösung mit der Steuerung über einen GPIO realisierbar wäre, dann könnte man an der betreffenden Stelle eine Abfrage einbauen, die statt „machine.deepsleep“ nur ein „time.sleep“ macht.

if not wait_pin.value():
    machine.deepsleep(sleep_time * 1000)
else:
    time.sleep(sleep_time)

Auf diese Weise hätte man die Tiefschlafphase komplett unterbunden. Und könnte den Raspberry Pi Pico ganz normal programmieren.

Achtung: Kein Aufwecken aus dem Schlafmodus möglich

Stand: MicroPython Version 1.19

Das Verwenden von „machine.lightsleep“ und „machine.deepsleep“ ohne Parameter (Millisekunden) ist keine gute Idee. Ohne Parameter bleibt der Mikrocontroller im jeweiligen Schlafmodus. Es gibt dann keine funktionierende Möglichkeit einen Raspberry Pi Pico, der sich im Schlafmodus befindet, durch ein internes oder externes Ereignis aufzuwecken.

Warum funktionieren diese Anweisungen ohne Parameter? Es kann ja sein, dass der Mikrocontroller nach getaner Arbeit ausgeschaltet werden soll, was faktisch nicht geht. Eine Alternative wäre dann der Schlafmodus. Außerdem ist es denkbar, dass Aufweck-Funktionen in MicroPython für den RP2040 nachgerüstet werden, wie es in anderen Mikrocontrollern auch möglich ist.

Weitere verwandte Themen:

Frag Elektronik-Kompendium.de

Hardware-nahes Programmieren mit dem Raspberry Pi Pico und MicroPython

Elektronik-Set Pico Edition

Das Elektronik-Set Pico Edition ist ein Bauteile-Sortiment mit Anleitung zum Experimentieren und Programmieren mit MicroPython.

  • LED: Einschalten, ausschalten, blinken und Helligkeit steuern
  • Taster: Entprellen und Zustände anzeigen
  • LED mit Taster einschalten und ausschalten
  • Ampel- und Lauflicht-Steuerung
  • Elektronischer Würfel
  • Eigene Steuerungen programmieren

Elektronik-Set jetzt bestellen Online-Workshop buchen

Online-Workshop: Programmieren mit dem Raspberry Pi Pico

Programmieren mit dem Raspberry Pi Pico

Gemeinsam mit anderen und unter Anleitung experimentieren? Wir bieten unterschiedliche Online-Workshops zum Raspberry Pi Pico und MicroPython an. Einführung in die Programmierung, Sensoren programmieren und kalibrieren, sowie Internet of Things und Smart Home über WLAN und MQTT.

Online-Workshop buchen

Besuchen Sie unser fast monatlich stattfindendes Online-Meeting PicoTalk und lernen Sie uns kennen. Die Teilnahme ist kostenfrei.

Termine und Newsletter-Anmeldung

 

Elektronik-Sets für das Hardware-nahe Programmieren