Multitask-Programmierung mit dem Raspberry Pi Pico
Zeitsteuerung, Scheduler, PIO und Zustandsmaschinen


Hans-Joachim Seeger
![]()


Hans-Joachim Seeger
Hans-Joachim Seeger
● © 2026: Elektor Verlag GmbH, Aachen.
1.Auflage 2026
● Alle Rechte vorbehalten.
Die in diesem Buch veröffentlichten Beiträge, insbesondere alle Aufsätze und Artikel sowie alle Entwürfe, Pläne, Zeichnungen und Illustrationen sind urheberrechtlich geschützt. Ihre auch auszugsweise Vervielfältigung und Verbreitung ist grundsätzlich nur mit vorheriger schriftlicher Zustimmung des Herausgebers gestattet.
Die Informationen im vorliegenden Buch werden ohne Rücksicht auf einen eventuellen Patentschutz veröffentlicht.
Die in diesem Buch erwähnten Soft- und Hardwarebezeichnungen können auch dann eingetragene Warenzeichen sein, wenn darauf nicht besonders hingewiesen wird. Sie gehören dem jeweiligen Warenzeicheninhaber und unterliegen gesetzlichen Bestimmungen.
Bei der Zusammenstellung von Texten und Abbildungen wurde mit größter Sorgfalt vorgegangen. Trotzdem können Fehler nicht vollständig ausgeschlossen werden. Verlag, Herausgeber und Autor können für fehlerhafte Angaben und deren Folgen weder eine juristische Verantwortung noch irgendeine Haftung übernehmen.
Für die Mitteilung eventueller Fehler sind Verlag und Autor dankbar.
● Erklärung
Autor und Verlag haben sich nach bestem Wissen und Gewissen bemüht, die Richtigkeit der in diesem Buch enthaltenen Informationen sicherzustellen. Sie übernehmen jedoch keine Haftung gegenüber Dritten für Verluste oder Schäden, die durch Fehler oder Auslassungen in diesem Buch entstehen, unabhängig davon, ob diese Fehler oder Auslassungen auf Fahrlässigkeit, Unglücksfälle oder andere Ursachen zurückzuführen sind
●
978-3-89576-743-2 Print
978-3-89576-744-9 eBook
978-3-89576-745-6 ePub
● Satz und Aufmachung: D-Vision, Julian van den Berg | Oss (NL)
Druck: Ipskamp Printing, Enschede (NL)
Elektor Verlag GmbH, Aachen www.elektor.de
Elektor ist die weltweit wichtigste Quelle für technische Informationen und Elektronik-Produkte für Maker, Ingenieure und Elektronik-Entwickler und für Firmen, die diese Fachleute beschäftigen. Das internationale Team von Elektor entwickelt Tag für Tag hochwertige Inhalte für Entwickler und DIY-Elektroniker, die über verschiedene Medien (Magazine, Videos, digitale Medien sowie Social Media) in zahlreichen Sprachen verbreitet werden. www.elektor.de
7.4
7.5
• Die Schaltungen und Boards dürfen ausschließlich mit geprüften, doppelt isolierten Sicherheitsnetzgeräten betrieben werden. Isolationsfehler bei einfachen oder ungeeigneten Netzteilen können zu gefährlichen Berührungsspannungen an Bauteilen oder Leitungen führen.
• Alle Komponenten dürfen nur innerhalb ihrer vorgesehenen Spannungs- und Strombereiche betrieben werden. Falsche Spannungspegel – insbesondere über 3,3 V am Raspberry Pi Pico – können sofortige und dauerhafte Schäden verursachen.
• Der Raspberry Pi Pico sowie angeschlossene Module erzeugen empfindliche CMOS-Signale. Elektrostatische Entladungen (ESD) können Bauteile zerstören. Verwendung einer antistatischen Unterlage und vorsichtiges Arbeiten werden empfohlen.
• Leistungsstarke LEDs, insbesondere Hochleistungs- oder RGB-LEDs, können Blendungen und dauerhafte Augenschäden verursachen. Niemals direkt in helle Lichtquellen schauen.
• Beim Umgang mit LED-Streifen, NeoPixel/WS2812 und Displays kann eine hohe Stromaufnahme entstehen. Die Stromversorgung muss ausreichend dimensioniert sein, um Überlastungen und Überhitzung zu vermeiden.
• Beim Aufbau auf dem Breadboard ist auf sichere und feste Kontaktierung zu achten. Lose oder wackelige Verbindungen können Kurzschlüsse, Fehlfunktionen oder Beschädigungen des Mikrocontrollers verursachen.
• Taster und mechanische Schalter erzeugen Prellen. Unsachgemäße Entprellung kann zu Fehlauslösungen führen, besonders bei programmgesteuerten Menüs oder PIO-Abfragen.
• Bei der Arbeit mit PIO-Programmen können sehr hohe Frequenzen erzeugt werden. Fehlkonfigurationen können zu instabilen Zuständen oder unerwünschtem Verhalten der Peripherie führen.
• Der Autor übernimmt keinerlei Haftung für Schäden, die durch unsachgemäße Nutzung, Fehlverdrahtung, falsche Spannungen oder fehlerhafte Programme entstehen.
• Alle Programme und PIO-Beispiele sind zu Lehr- und Experimentierzwecken gedacht und dürfen nur unter Aufsicht oder mit ausreichendem technischem Verständnis verwendet werden.
• Vor Änderungen an der Verdrahtung oder Bauteilen muss das gesamte System vom Strom getrennt werden, um Kurzschlüsse oder Verletzungen zu vermeiden.
Die vollständigen Programme aller im Buch verwendeten Projekte können kostenlos von der Elektor-Store Webseite
www.elektor.de heruntergeladen werden. Sofern ein Programm nicht identisch mit dem im Buch beschriebenen ist, sollte die Version aus dem Download verwendet werden, da es sich dabei um die aktuelle Version handelt.
Multitasking ist ein Begriff, der in der Computerwelt fast selbstverständlich verwendet wird. Moderne Betriebssysteme führen zahlreiche Programme gleichzeitig aus. Musik läuft im Hintergrund, Dateien werden heruntergeladen, ein Browser zeigt Webseiten an – und alles scheint parallel zu geschehen.
Wer jedoch beginnt, mit Mikrocontrollern zu arbeiten, stellt schnell fest:
Hier gelten andere Regeln.
Ein Mikrocontroller besitzt in der Regel nur eine einzige Recheneinheit. Speicher und Rechenleistung sind begrenzt, und ein komplexes Betriebssystem steht meist nicht zur Verfügung. Trotzdem soll ein solches System häufig mehrere Aufgaben gleichzeitig erfüllen.
Typische Beispiele sind:
• Sensoren regelmäßig messen
• Taster ohne Verzögerung erkennen
• Anzeigen oder Displays aktualisieren
• Signale erzeugen
• Kommunikation mit anderen Geräten aufrechterhalten
Viele Projekte beginnen mit einer einfachen Endlosschleife und einigen sleep()-Aufrufen. Für erste Experimente funktioniert das durchaus gut. Doch sobald mehrere Funktionen zusammenkommen, treten häufig Probleme auf:
• Taster reagieren verzögert
• Anzeigen flackern
• Messwerte erscheinen unregelmäßig
• das Zeitverhalten wird schwer vorhersehbar
Spätestens an diesem Punkt zeigt sich, dass Multitasking kein Komfortmerkmal moderner Computer ist, sondern eine grundlegende Denkweise in der Entwicklung von EmbeddedSystemen.
Dieses Buch zeigt, wie sich mehrere Aufgaben auch auf kleinen Mikrocontrollern zuverlässig und strukturiert organisieren lassen.
Als Hardwareplattform wird der Raspberry Pi Pico verwendet. Sein RP2040-Mikrocontroller bietet ausreichend Leistung für Experimente mit verschiedenen Multitasking-Strategien und bleibt gleichzeitig übersichtlich genug, um die zugrunde liegenden Mechanismen nachvollziehen zu können.
Dabei steht nicht ein bestimmtes Betriebssystem im Mittelpunkt, sondern das Verständnis grundlegender Prinzipien:
• Zeitgesteuerte Programme
• kooperatives Multitasking
• einfache Scheduler
• strukturierte Aufgabenverwaltung
Ziel ist es, Programme so zu entwickeln, dass mehrere Funktionen zuverlässig und nachvollziehbar zusammenarbeiten.
Die vorgestellten Konzepte lassen sich nicht nur auf den Raspberry Pi Pico übertragen. Sie gelten grundsätzlich für viele Mikrocontroller – von klassischen 8-Bit-Systemen bis zu modernen 32-Bit-Architekturen.
Worum es in diesem Buch geht
Dieses Buch beschäftigt sich mit der Frage, wie mehrere Aufgaben auf einem Mikrocontroller zuverlässig zusammenarbeiten können. Zu Beginn werden die grundlegenden Konzepte betrachtet.
Was bedeutet Multitasking eigentlich?
Was ist der Unterschied zwischen echter Parallelität und scheinbar gleichzeitig ablaufenden Aufgaben?
Und warum ist Zeit in einem Embedded-System eine ebenso wichtige Ressource wie Speicher oder Energie?
Anschließend betrachten wir klassische Mikrocontrollersysteme mit begrenzten Ressourcen. Gerade bei einfachen 8-Bit-Architekturen wird besonders deutlich, wie wichtig ein strukturiertes Zeitmanagement ist. Hier zeigt sich sehr klar, dass nicht die reine Rechenleistung entscheidend ist, sondern eine saubere Planung des Programms.
Im weiteren Verlauf wenden wir uns dem Raspberry Pi Pico zu. Sein RP2040-Mikrocontroller eröffnet zusätzliche Möglichkeiten, etwa durch zwei Prozessorkerne, Hardware-Timer und programmierbare I/O-Einheiten.
Damit lassen sich neue Ansätze für Multitasking realisieren. Gleichzeitig entstehen jedoch auch neue Herausforderungen, beispielsweise durch Laufzeitumgebungen wie MicroPython, Garbage-Collection oder Synchronisationsprobleme zwischen verschiedenen Aufgaben.
Ziel dieses Buches ist es nicht, möglichst viele Techniken nebeneinanderzustellen. Im Mittelpunkt steht vielmehr das Verständnis dafür, welche Lösung in einer bestimmten Situation sinnvoll ist.
Dazu gehören Fragen wie:
• Wann ist ein einfaches zeitgesteuertes Programm ausreichend?
• Wann bietet kooperatives Multitasking Vorteile?
• Wann kann ein zweiter Prozessorkern sinnvoll eingesetzt werden?
• Und wann ist es besser, bestimmte Aufgaben direkt von der Hardware ausführen zu lassen?
Das Buch richtet sich sowohl an Einsteiger als auch an Leser mit Vorkenntnissen.
Einsteiger lernen, typische Probleme blockierender Programme zu erkennen und Anwendungen strukturiert aufzubauen. Fortgeschrittene Leser erhalten Werkzeuge, um Laufzeiten zu analysieren, zeitliches Verhalten zu bewerten und Systemarchitekturen bewusster zu gestalten.
Multitasking ist dabei kein zusätzlicher Baustein, der später in ein Projekt eingefügt wird. Es ist eine grundlegende Denkweise beim Entwurf von Embedded-Systemen.
Wer Multitasking versteht, erkennt leichter,
• warum Systeme instabil werden können,
• warum Zeitplanung entscheidend ist,
• warum Hardwarelösungen oft eleganter sind als rein softwarebasierte Ansätze,
• und warum eine klare Struktur häufig wichtiger ist als maximale Rechenleistung.
Dieses Buch lädt dazu ein, Mikrocontroller nicht nur zu programmieren, sondern Systeme bewusst zu entwerfen und ihr Verhalten zu verstehen.
Aufbau dieses Buches
Dieses Buch ist so aufgebaut, dass die Konzepte schrittweise entwickelt werden. Die einzelnen Kapitel bauen aufeinander auf, können jedoch teilweise auch unabhängig voneinander gelesen werden.
Zu Beginn wird zunächst die verwendete Hardwareplattform vorgestellt. Alle Experimente und Programme in diesem Buch basieren auf einer einheitlichen Testumgebung. Als Mikrocontroller wird der Raspberry Pi Pico verwendet.
Ergänzend dazu kommen Ein- und Ausgabemodule zum Einsatz, die LEDs und Taster bereitstellen und damit typische Embedded-Aufgaben nachvollziehbar darstellen.
Nach der Hardwareeinführung folgen erste Beispiele, die zeigen, wie mehrere Aufgaben innerhalb eines Programms organisiert werden können. Dabei wird zunächst auf einfache zeitgesteuerte Programme eingegangen, die ohne Betriebssystem und ohne zusätzliche Bibliotheken auskommen.
Im weiteren Verlauf werden verschiedene Strategien betrachtet, mit denen sich Multitasking auf Mikrocontrollern realisieren lässt. Dazu gehören unter anderem:
• zeitgesteuerte Programmschleifen
• kooperatives Multitasking
• einfache Scheduler
• Ereignissteuerung
• Nutzung mehrerer Prozessorkerne
Besonderes Augenmerk liegt dabei auf dem zeitlichen Verhalten von Programmen. In Embedded-Systemen ist es häufig entscheidend, dass bestimmte Aufgaben in definierten Zeitabständen ausgeführt werden. Daher werden Methoden vorgestellt, mit denen sich Laufzeiten analysieren und Programme stabil strukturieren lassen.
Neben klassischen softwarebasierten Lösungen wird auch gezeigt, wann es sinnvoll sein kann, Aufgaben an spezielle Hardwarefunktionen zu übertragen. Moderne Mikrocontroller bieten dafür häufig zusätzliche Möglichkeiten, die eine effiziente und stabile Systemarchitektur unterstützen.
Alle Programme des Buches sind bewusst übersichtlich gehalten und konzentrieren sich auf die jeweils behandelten Konzepte. Ziel ist es nicht, möglichst komplexe Anwendungen zu entwickeln, sondern die grundlegenden Prinzipien klar nachvollziehbar darzustellen.
Voraussetzungen
Für das Verständnis dieses Buches sind grundlegende Programmierkenntnisse hilfreich. Erfahrungen mit Mikrocontrollern oder Embedded-Systemen sind jedoch nicht zwingend erforderlich.
Die Programme werden überwiegend in Python geschrieben und auf dem Raspberry Pi Pico mit MicroPython ausgeführt. Dadurch lassen sich viele Konzepte schnell ausprobieren und leicht nachvollziehen.
Kenntnisse in der Programmiersprache Python sind von Vorteil, jedoch werden die verwendeten Sprach Konstrukte jeweils kurz erläutert.
Ziel dieses Buches
Das Ziel dieses Buches ist es, ein Verständnis dafür zu entwickeln, wie sich mehrere Aufgaben auf einem Mikrocontroller zuverlässig organisieren lassen.
Dabei geht es weniger um einzelne Programmiersprachen oder spezielle Bibliotheken, sondern um grundlegende Prinzipien der Systemstruktur.
Wer diese Prinzipien versteht, kann sie auf viele unterschiedliche Mikrocontroller und Entwicklungsumgebungen übertragen.
Kapitel 1 • Was ist Multitasking?
Stellen Sie sich ein kleines Mikrocontrollersystem vor, das drei einfache Aufgaben erfüllen soll:
1. Eine LED soll regelmäßig blinken.
2. Ein Taster soll jederzeit erkannt werden.
3. Ein Sensor soll alle 100 Millisekunden gemessen werden.
Jede dieser Aufgaben für sich genommen ist sehr einfach. Eine LED zum Blinken zu bringen benötigt nur wenige Programmzeilen. Auch ein Taster lässt sich leicht abfragen, und das Auslesen eines Sensors ist meist ebenfalls unkompliziert.
Die Schwierigkeit entsteht erst dann, wenn alle drei Aufgaben gleichzeitig funktionieren sollen.
• Die LED soll unabhängig vom Taster blinken.
• Der Taster soll sofort erkannt werden.
• Der Sensor soll regelmäßig gemessen werden.
Die zentrale Frage lautet daher:
Wie kann ein Mikrocontroller alle diese Aufgaben gleichzeitig erledigen?
Ein Mikrocontroller besitzt normalerweise nur eine einzige CPU. Diese CPU kann jedoch immer nur eine einzige Anweisung zur gleichen Zeit ausführen. Trotzdem erwarten wir, dass alle drei Funktionen parallel arbeiten. Dieses scheinbare Paradox führt direkt zum zentralen Thema dieses Buches:
Multitasking in Embedded-Systemen
Die Lösung besteht nicht darin, mehrere Programme gleichzeitig auszuführen. Stattdessen wird das Programm so aufgebaut, dass der Mikrocontroller sehr schnell zwischen verschiedenen Aufgaben wechselt.
Wenn jede Aufgabe regelmäßig in kurzen Abständen bearbeitet wird, entsteht für den Beobachter der Eindruck, dass alle Funktionen parallel arbeiten. Genau dieses Prinzip bildet die Grundlage vieler Multitasking-Strategien in Embedded-Systemen.
1 .1 Der erste Eindruck: "Alles gleichzeitig"
Wenn wir den Begriff Multitasking hören, denken viele zunächst an ein System, das mehrere Dinge gleichzeitig erledigt.
Ein Computer spielt Musik, zeigt ein Video, lädt Daten aus dem Internet herunter und reagiert gleichzeitig auf Tastatureingaben. Für den Benutzer wirkt es so, als würden all diese Aufgaben parallel ausgeführt.
Dieser Eindruck ist im Alltag völlig normal. Moderne Computer, Smartphones oder Tablets sind darauf ausgelegt, viele Programme gleichzeitig zu betreiben. Ein Musikplayer läuft im Hintergrund, während gleichzeitig ein Webbrowser geöffnet ist und vielleicht noch eine Datei heruntergeladen wird.
Aus Sicht des Benutzers scheint das System viele Aufgaben gleichzeitig zu erledigen.
Tatsächlich verbirgt sich dahinter jedoch ein komplexer Mechanismus. Häufig entsteht dieser Eindruck nicht durch echte Parallelität, sondern durch eine sehr schnelle Abfolge einzelner Rechenschritte
Der Prozessor wechselt ständig zwischen verschiedenen Programmen und führt von jedem Programm immer nur einen kleinen Teil aus. Diese Technik wird Zeitaufteilung genannt. Die verfügbare Rechenzeit wird auf mehrere Programme verteilt. Wenn dieser Wechsel schnell genug erfolgt, entsteht für den Benutzer der Eindruck, dass alle Programme gleichzeitig arbeiten.
1 .2 Warum Computer scheinbar viele Dinge gleichzeitig tun
In modernen Computersystemen übernimmt das Betriebssystem die Organisation aller laufenden Programme.
Es verwaltet unter anderem:
• den Prozessor
• den Arbeitsspeicher
• Ein- und Ausgabegeräte
• laufende Programme
Ein wichtiger Bestandteil dieser Verwaltung besteht darin, die verfügbare Rechenzeit zwischen verschiedenen Programmen aufzuteilen. Dieses Verfahren wird Scheduling genannt.
Dabei erhält jedes Programm nur für kurze Zeit Zugriff auf den Prozessor. Danach wird das Programm unterbrochen und ein anderes Programm erhält Rechenzeit. Dieser Wechsel geschieht extrem schnell – oft tausende Male pro Sekunde. Für den Benutzer entsteht dadurch der Eindruck, dass mehrere Programme gleichzeitig laufen.
Zusätzlich besitzen viele moderne Prozessoren mehrere Kerne. In diesem Fall können tatsächlich mehrere Programme gleichzeitig ausgeführt werden, da verschiedene Prozessorkerne unabhängig voneinander arbeiten. Trotzdem gilt auch hier ein grundlegendes Prinzip:
Jeder einzelne Prozessorkern kann zu jedem Zeitpunkt nur eine einzige Anweisung ausführen.
1 .3
Mikrocontroller und Desktop-Systeme
Während Desktop-Computer und Smartphones über leistungsfähige Betriebssysteme verfügen, ist die Situation bei Mikrocontrollern meist deutlich einfacher.
Ein Mikrocontroller ist ein kleiner Computer auf einem einzigen Chip. Er enthält typischerweise:
• eine CPU
• Programmspeicher
• Datenspeicher
• Ein- und Ausgabeschnittstellen
• verschiedene Peripheriemodule
Solche Systeme werden als Embedded-Systeme bezeichnet.
Embedded-Systeme sind meist für eine ganz bestimmte Aufgabe entwickelt. Ein Mikrocontroller kann zum Beispiel:
• eine Waschmaschine steuern
• eine Temperaturregelung überwachen
• ein Messgerät betreiben
• eine Motorsteuerung regeln
• ein Kommunikationsgerät betreiben
Im Gegensatz zu großen Computersystemen besitzen Mikrocontroller häufig:
• nur einen einzigen Prozessorkern
• sehr begrenzten Speicher
• keine komplexe Betriebssystemumgebung
Viele Mikrocontrollerprogramme laufen daher ohne Betriebssystem direkt auf der Hardware.
Trotz dieser Einschränkungen müssen auch Mikrocontroller häufig mehrere Aufgaben gleichzeitig erfüllen.
Ein typisches Embedded-System könnte beispielsweise:
• Sensoren regelmäßig messen
• Taster oder Schalter abfragen
• LEDs oder Displays aktualisieren
• Signale erzeugen
• Daten mit anderen Geräten austauschen
All diese Aufgaben sollen scheinbar parallel ablaufen.
1 .4
Eine CPU kann immer nur eine Anweisung ausführen
Um zu verstehen, wie Multitasking auf Mikrocontrollern funktioniert, muss man ein grundlegendes Prinzip akzeptieren: Eine CPU kann zu jedem Zeitpunkt nur eine einzige Maschinenanweisung ausführen.
Ein Programm wird daher immer Schritt für Schritt abgearbeitet.
Die CPU liest eine Anweisung aus dem Speicher, führt sie aus und lädt danach die nächste Anweisung. Dieser Ablauf wiederholt sich ständig. Wenn ein Programm mehrere Aufgaben enthält, werden auch diese Aufgaben nacheinander ausgeführt.
Der Mikrocontroller bearbeitet zunächst einen kleinen Teil einer Aufgabe, danach einen Teil einer anderen Aufgabe und anschließend wieder eine weitere Aufgabe. Durch die hohe Geschwindigkeit moderner Mikrocontroller können diese Wechsel jedoch sehr schnell erfolgen.
Viele Mikrocontroller arbeiten mit Taktraten im Bereich von mehreren Millionen oder sogar hundert Millionen Taktzyklen pro Sekunde. Dadurch können innerhalb sehr kurzer Zeiträume viele einzelne Programmschritte ausgeführt werden. Diese hohe Geschwindigkeit ermöglicht es, mehrere Aufgaben scheinbar parallel zu bearbeiten.
1 .5 Scheinbare Parallelität
Wenn verschiedene Aufgaben regelmäßig in kurzen Zeitabständen bearbeitet werden, entsteht für den Beobachter der Eindruck, sie würden gleichzeitig arbeiten.
Tatsächlich passiert jedoch etwas anderes: Das Programm wechselt ständig zwischen verschiedenen Aufgaben
Ein vereinfachter Ablauf könnte beispielsweise so aussehen:
LED aktualisieren
Taster prüfen
Sensor messen
Anzeige aktualisieren
LED aktualisieren
Taster prüfen
Sensor messen
Anzeige aktualisieren
Dieser Zyklus wird ständig wiederholt.
Wenn der Mikrocontroller diese Schleife sehr schnell durchläuft – möglicherweise mehrere tausend Male pro Sekunde – wirkt es so, als würden alle Aufgaben gleichzeitig arbeiten.
Dieses Prinzip wird scheinbare Parallelität genannt.
Kapitel 1 • Was ist Multitasking?
Viele Embedded-Systeme arbeiten genau auf diese Weise. Sie führen keine Aufgaben wirklich gleichzeitig aus, sondern verteilen die verfügbare Rechenzeit auf mehrere Teilaufgaben. Der entscheidende Punkt ist dabei, dass jede Aufgabe regelmäßig wieder ausgeführt wird.
1 .6 Multitasking als Denkweise
Multitasking in Embedded-Systemen ist weniger eine spezielle Programmiertechnik als vielmehr eine grundlegende Denkweise beim Entwurf von Software.
Der Entwickler muss Programme so strukturieren, dass mehrere Aufgaben regelmäßig Rechenzeit erhalten. Gleichzeitig muss verhindert werden, dass einzelne Funktionen den gesamten Programmablauf blockieren. Dabei spielen mehrere Fragen eine wichtige Rolle:
• Wie häufig muss eine Aufgabe ausgeführt werden?
• Wie schnell muss das System auf Ereignisse reagieren?
• Welche Aufgaben sind besonders wichtig?
• Welche Aufgaben dürfen etwas länger warten?
Ein schlecht strukturiertes Programm kann dazu führen, dass Eingaben verzögert erkannt werden oder Zeitabläufe ungenau werden. Die Organisation der Zeit im Programm wird daher zu einem zentralen Bestandteil des Softwareentwurfs.
Im Verlauf dieses Buches werden verschiedene Techniken vorgestellt, mit denen sich diese Zeitorganisation systematisch umsetzen lässt.
1 .7 Überblick über Multitasking-Strategien
Im Laufe der Zeit haben sich verschiedene Strategien entwickelt, um mehrere Aufgaben auf Mikrocontrollern zu organisieren. Die wichtigsten Ansätze sind:
Superloop-Programme
Eine einfache Endlosschleife ruft alle Aufgaben nacheinander auf. Dieser Ansatz ist sehr verbreitet und bildet die Grundlage vieler kleiner Embedded-Systeme.
Zeitgesteuerte Programme
Hier werden Aufgaben in bestimmten Zeitintervallen ausgeführt. Anstatt das Programm anzuhalten, wird kontinuierlich überprüft, ob eine bestimmte Zeitspanne vergangen ist.
Diese Technik wird später im Buch ausführlich behandelt.
Interrupt-basierte Systeme
Bestimmte Ereignisse können den normalen Programmablauf kurz unterbrechen. Der Mikrocontroller reagiert sofort auf wichtige Signale und kehrt danach zum ursprünglichen Programm zurück.
Scheduler und Echtzeitbetriebssysteme
Größere oder komplexere Systeme verwenden spezielle Software, die mehrere Aufgaben automatisch verwaltet und priorisiert. Solche Systeme werden häufig als Echtzeitbetriebssysteme (RTOS) bezeichnet.
1 .8 Hardware

Raspberry Pi Pico mit 4 LEDs und 4 Tastern
Mit dieser Schaltung kann man viele verschiedene Programme bereits ausführen
1 .9 Ausblick
In den folgenden Kapiteln werden wir diese Konzepte anhand praktischer Beispiele untersuchen.
Zunächst betrachten wir ein sehr einfaches Programm, das mehrere LEDs scheinbar gleichzeitig steuert – obwohl das Programm nur aus einer einzigen Programmschleife besteht. Dieses Beispiel führt uns direkt zum nächsten wichtigen Konzept:
dem Superloop
Der Superloop ist die grundlegende Struktur vieler Mikrocontrollerprogramme. Er bildet das Fundament für einfache Multitasking-Systeme und stellt den Ausgangspunkt für die weiteren Kapitel dieses Buches dar.
Der Superloop ist das grundlegende Programmiermodell vieler Mikrocontroller-Systeme. Bevor komplexere Multitasking-Techniken eingeführt werden, ist es wichtig zu verstehen, wie Programme ohne Betriebssystem strukturiert werden.
In diesem Kapitel wird gezeigt,
• wie ein Superloop aufgebaut ist,
• warum dieses Modell so weit verbreitet ist,
• welche Vorteile es besitzt,
• und an welchen Stellen seine Grenzen liegen.
2 .1 Das klassische Embedded-Modell
In Mikrocontroller-Systemen existiert in der Regel kein komplexes Betriebssystem wie bei Desktop-Computern. Stattdessen werden alle Aufgaben eines Systems in einem einfachen Endlosschleifenmodell abgearbeitet – dem Superloop.
Typische Eigenschaften dieses Modells sind:
• Eine einzige CPU führt immer nur eine Anweisung gleichzeitig aus.
• Alle Aufgaben werden nacheinander, aber sehr schnell bearbeitet.
• Blockierende Wartezeiten verhindern die gleichzeitige Bearbeitung anderer Aufgaben.
• Das System muss zeitlich so strukturiert sein, dass alle Aufgaben zuverlässig ausgeführt werden.
Der Superloop ist besonders in kleinen Mikrocontrollerprojekten verbreitet, weil er:
• einfach zu verstehen ist
• ohne Betriebssystem funktioniert
• sehr wenig Speicher benötigt
• deterministisches Verhalten erlaubt
Viele professionelle Embedded-Systeme beginnen ebenfalls mit diesem Modell, bevor komplexere Strukturen eingesetzt werden.
2 .2 Aufbau eines Superloops
Ein typisches Mikrocontrollerprogramm besteht aus zwei Hauptteilen:
1. Initialisierung der Hardware
2. Endlosschleife des Programms
Die Initialisierung wird nur einmal beim Start des Systems ausgeführt. Danach arbeitet das Programm dauerhaft in einer Endlosschleife.
Der grundsätzliche Aufbau sieht folgendermaßen aus: Initialisierung der Hardware while True:
Aufgabe 1
Aufgabe 2
Aufgabe 3
Der Superloop besitzt vier zentrale Bestandteile:
1 Initialisierung
Alle Hardware-Komponenten werden vorbereitet:
• GPIO-Pins
• Sensoren
• Kommunikationsschnittstellen
• Timer
Diese Phase wird nur einmal ausgeführt.
2 Endlosschleife
Das eigentliche Programm läuft in einer Endlosschleife: while True
Diese Schleife wird ununterbrochen wiederholt. Jede Aufgabe im System wird innerhalb dieser Schleife nacheinander bearbeitet.
3 Zeitsteuerung
Viele Aufgaben sollen nicht ständig ausgeführt werden, sondern nur in bestimmten Zeitabständen.
Deshalb prüfen Aufgaben meist:
• Zeitintervalle
• Eingaben
• Ereignisse
Nur wenn eine Bedingung erfüllt ist, wird eine Aktion ausgeführt.
4 Iteration
Sobald das Ende der Schleife erreicht ist, beginnt sie sofort wieder von vorne.
Dadurch entsteht eine sehr schnelle Wiederholung der Programmlogik.
2 .3 Gedankenexperiment – Multitasking mit LEDs
Bevor wir praktische Programme betrachten, hilft ein kleines Gedankenexperiment.
Angenommen, ein Mikrocontroller soll 16 LEDs steuern. Jede LED soll mit einer anderen Blinkfrequenz arbeiten.
Gleichzeitig besitzt der Mikrocontroller:
• nur einen Prozessorkern
• kann immer nur eine Anweisung gleichzeitig ausführen
Die Frage lautet:
Wie kann ein Mikrocontroller 16 LEDs gleichzeitig steuern?
Die Antwort lautet:
Er steuert sie nicht gleichzeitig, sondern sehr schnell nacheinander.
Jede LED verwaltet dabei ihr eigenes Zeitintervall. Der Superloop prüft kontinuierlich, ob eine LED gerade umgeschaltet werden muss.
2 .4 Hardware mit 16 LEDs

Raspberry Pi Pico mit 16 LEDs
Mit dieser Schaltung können 16 LEDs angesteuert werden.
# ================================================
# Multitasking Prg 1
# ================================================
# Schaltet 16 LEDs unabhängig
# ================================================ from machine import Pin import time
# -------------------------------------------------
# Klasse für eine blinkende LED
# -------------------------------------------------
# Diese Klasse kapselt alle Eigenschaften einer LED:
# - Name der LED (nur für Dokumentation)
# - GPIO Pin
# - Blinkintervall
# - Zeitpunkt des letzten Umschaltens
# - aktueller Zustand der LED
# Jede LED arbeitet völlig unabhängig von den anderen. class BlinkLED: def __init__(self, name, gpio, interval_ms):
# Name der LED (nur zur besseren Übersicht) self.name = name
# GPIO Pin konfigurieren
self.pin = Pin(gpio, Pin.OUT)
# Blinkintervall speichern self.interval = interval_ms
# Zeitpunkt des letzten Umschaltens merken self.last_toggle = time.ticks_ms()
# LED Zustand
# 1 = LED AUS
# 0 = LED EIN
# Die LEDs sind LOW-AKTIV angeschlossen
# (LED über Widerstand an Vcc)
self.state = 1
# LED initial ausschalten self.pin.value(self.state)
# -------------------------------------------------
# update() prüft ob die LED umgeschaltet werden muss
# -------------------------------------------------
def update(self, current_time):
# Zeitdifferenz berechnen if time.ticks_diff(current_time, self.last_toggle) >= self.interval:
# Zustand umschalten
# XOR Trick:
# 1 -> 0
# 0 -> 1
self.state ^= 1
# neuen Zustand auf den GPIO schreiben self.pin.value(self.state)
# Zeitpunkt merken self.last_toggle = current_time
# -------------------------------------------------
# LED Objekte erzeugen
# -------------------------------------------------
# Jede LED bekommt:
# Name
# GPIO
# Blinkzeit
LED_1 = BlinkLED("LED_1", 15, 100)
LED_2 = BlinkLED("LED_2", 14, 200)
LED_3 = BlinkLED("LED_3", 13, 300)
LED_4 = BlinkLED("LED_4", 12, 400)
LED_5 = BlinkLED("LED_5", 11, 500)
LED_6 = BlinkLED("LED_6", 10, 600)
LED_7 = BlinkLED("LED_7", 9, 700)
LED_8 = BlinkLED("LED_8", 8, 800)
LED_9 = BlinkLED("LED_9", 7, 900)
LED_10 = BlinkLED("LED_10", 6, 1000)
LED_11 = BlinkLED("LED_11", 5, 1100)
LED_12 = BlinkLED("LED_12", 4, 1200)
LED_13 = BlinkLED("LED_13", 3, 1300)
LED_14 = BlinkLED("LED_14", 2, 1400)
LED_15 = BlinkLED("LED_15", 1, 1500)
LED_16 = BlinkLED("LED_16", 0, 1600)
Multitask-Programmierung mit dem Raspberry Pi Pico
# -------------------------------------------------
# Hauptprogramm (Superloop)
# -------------------------------------------------
# Der Mikrocontroller arbeitet hier in einer sogenannten "Superloop".
# Das bedeutet: Endlosschleife → alle Aufgaben werden nacheinander aufgerufen
# Jede LED prüft selbstständig, ob ihre Zeit abgelaufen ist.
while True:
# aktuelle Systemzeit lesen now = time.ticks_ms()
# -------------------------------------------------
# jede LED einzeln aktualisieren
# -------------------------------------------------
LED_1.update(now)
LED_2.update(now)
LED_3.update(now)
LED_4.update(now)
LED_5.update(now)
LED_6.update(now)
LED_7.update(now)
LED_8.update(now)
LED_9.update(now)
LED_10.update(now)
LED_11.update(now)
LED_12.update(now)
LED_13.update(now)
LED_14.update(now)
LED_15.update(now)
LED_16.update(now)
Was passiert in diesem Programm?
Der Mikrocontroller durchläuft die Endlosschleife des Programms mehrere tausend Male pro Sekunde. Bei jedem Durchlauf wird für jede LED überprüft, ob ihre Blinkzeit abgelaufen ist.
Jede LED entscheidet dabei selbst, ob sie ihren Zustand ändern muss. Dadurch können alle LEDs unabhängig voneinander mit unterschiedlichen Frequenzen blinken.
Grundprinzip des Programms
Für jede LED wird ein eigenes Objekt der Klasse BlinkLED erzeugt. Dieses Objekt enthält alle Informationen, die für die Steuerung der LED benötigt werden:
• den verwendeten GPIO-Pin
• das Blinkintervall
• den aktuellen Zustand der LED
• den Zeitpunkt des letzten Umschaltens
Jede LED verwaltet ihre eigene Zeitinformation und kann daher unabhängig von den anderen LEDs arbeiten.
Zeitsteuerung
Die Blinksteuerung basiert auf der Funktion time.ticks_ms()
Diese Funktion liefert die aktuelle Systemzeit in Millisekunden. Bei jedem Durchlauf der Hauptschleife wird überprüft, wie viel Zeit seit dem letzten Umschalten vergangen ist. Sobald das Blinkintervall erreicht ist, wird die LED umgeschaltet.
Dabei werden drei Schritte ausgeführt:
1. Der Zustand der LED wird geändert.
2. Der neue Zustand wird auf den GPIO-Pin geschrieben.
3. Der aktuelle Zeitpunkt wird gespeichert.
Damit beginnt sofort ein neuer Zeitzyklus für diese LED.
Hauptschleife (Superloop)
Das gesamte Programm arbeitet mit einer einfachen Endlosschleife: while True
Innerhalb dieser Schleife werden nacheinander alle LEDs aktualisiert:
LED_1.update(now)
LED_2.update(now) ...
LED_16.update(now)
Da diese Schleife sehr schnell durchlaufen wird, kann jede LED ihr eigenes Blinkintervall genau einhalten.
A
Abtastrate
Adressierung (I²C) ............................ 108
B
C
Multitask-Programmierung mit dem Raspberry Pi Pico
Multitasking ist der Schlüssel zu leistungsfähigen Embedded-Systemen, und zugleich eine der größten Herausforderungen in der MikrocontrollerProgrammierung. Dieses Buch zeigt Ihnen Schritt für Schritt, wie Sie von einem einfachen Ein-Task-Programm zu einem strukturierten, reaktionsfähigen und skalierbaren System gelangen. Dabei steht nicht nur das Wie, sondern vor allem das Warum im Mittelpunkt.
Sie lernen:
> warum scheinbare Parallelität entsteht
> weshalb blockierende Programme instabil werden
> wie Aufgaben effizient und kontrolliert parallel ablaufen
Ausgehend vom klassischen Superloop vermittelt das Buch moderne Multitasking-Strategien – von nicht-blockierender Programmierung und Tick-Systemen bis zu Task-Schedulern, Zustandsmaschinen und ereignisgesteuerten Konzepten.
Der Fokus liegt auf der Praxis: Sensoren, Displays, Kommunikation und reale Anwendungen werden Schritt für Schritt integriert und mit verständlich kommentierten Beispielprogrammen erklärt.
Fortgeschrittene Themen umfassen:
> Multicore-Programmierung mit dem Raspberry Pi Pico
> asynchrones Programmieren mit uasyncio
> RTOS-Grundlagen mit FreeRTOS
> die Kombination aus Multicore und RTOS
Dabei werden auch die Grenzen dieser Techniken, insbesondere unter MicroPython, klar aufgezeigt.
Das Buch richtet sich an ambitionierte Einsteiger und fortgeschrittene Entwickler, die Embedded-Systeme fundiert verstehen und robuste, wartbare Multitasking-Anwendungen entwickeln möchten.

Hans-Joachim Seeger ist ausgebildeter Radio- und Fernsehtechnikermeister sowie Elektromeister. Er verfügt über mehr als 30 Jahre Erfahrung im Service und in der Wartung elektronischer Geräte sowie in der Gebäudeleittechnik. Seit vielen Jahren beschäftigt er sich intensiv mit der Programmierung von Mikrocontrollern, insbesondere mit AVR und dem Raspberry Pi Pico, in C und Python. Darüber hinaus besitzt er umfangreiche praktische Erfahrung mit I²C-Bussystemen, Multitasking-Anwendungen und der Integration verschiedener Hardwarekomponenten.
Elektor Verlag GmbH www.elektor.de