Spielzeug-Roboter mit dem Raspberry Pi steuern
Roboter-Bausätze von Lego und Fischertechnik erlauben den Einstieg in die Robotik. An Stelle der teuren herstellereigenen Controller bietet sich ein Raspberry Pi mit Bluetooth an.
- Dr. Till Harbaum
Der Raspberry Pi eignet sich für Robotik-Experimente. Allerdings ist es nicht jedermanns Sache, einen Roboter zu bauen. Ganz einfach klappt das mit Konstruktionsbaukästen etwa von Lego oder Fischertechnik. Beide Hersteller haben mit dem „Lego EV3“ respektive dem „Robotics TXT“ auch eigene Linux-Controller im Angebot. Die kosten allerdings um die 300 Euro und erreichen trotzdem nicht ansatzweise die Leistung eines aktuellen Raspberry Pi 3. Beide Hersteller bieten zum etwa halben Preis aber auch Sets mit einfacheren Controllern an, die sich dank Bluetooth am Raspberry Pi betreiben lassen und ihn auf diesem Weg mit den Sensoren und Aktoren des jeweiligen Baukastenroboters verbinden.
Legos WeDo-2.0-Controller und der neue Boost-Controller nutzen dabei ebenso Verbindungen per Bluetooth Low Energy (BLE) wie der BT-Smart-Controller und das Bluetooth-Control-Set von Fischertechnik. Beide Hersteller folgen damit dem Trend weg vom PC und hin zu Mobilgeräten. Die Intelligenz bei diesen Systemen steckt dabei im Tablet oder Smartphone, wo per Drag-and-Drop programmiert wird und die eigentliche Programmausführung stattfindet. Doch auch der Raspi kann Roboter per BLE steuern. Die dafür nötigen Linux-Programme muss man dann allerdings selbst schreiben, beispielsweise in Python.
Spielzeug-Controller mit Bluetooth Low Energy
Bluetooth Low Energy hat sich vor allem bei Smartphones etabliert und zugehörige Verbindungs-Tools sind in den App-Stores zu finden. Ich habe das kostenlose „nRF Connect“ von Nordic Semiconductors verwendet, um die beiden Spielzeug-Controller einer ersten Analyse zu unterziehen. Dank des von BLE genutzten Generic Attribute Profils (GATT) lassen sich die für die Steuerung notwendigen Funktionen und Fähigkeiten der Controller leicht abfragen.
Neu ist bei BLE gegenüber klassischem Bluetooth, dass ein Gerät ohne bestehende Verbindung durch sogenannte Undirected-Advertisements außer seinem Namen auch detaillierte Informationen über seine angebotenen Dienste verbreiten kann. Dafür werden Bluetooth-üblich 128-Bit lange Kennungen (sogenannte UUIDs) verwendet, die Dienste und einzelne Funktionen eines BLE-Gerätes eindeutig identifizieren. Der WeDo-2.0-Hub meldet während des Scans einen Dienst mit der UUID 00001523-1212-efde-1523-785feabcd123 und ist darüber als WeDo-Hub zu erkennen, selbst wenn der Benutzer den Gerätenamen per Lego-App verstellt.
Der Fischertechnik BT-Smart-Controller ist etwas weniger mitteilsam und verbreitet ungefragt lediglich seinen Namen. Da der Name bei Fischertechnik nicht veränderbar ist, lässt er sich zur Geräteerkennung nutzen. Bezieht man zusätzlich den herstellerspezifischen Teil der Bluetooth-Adresse ein, so ist auch er sicher zu erkennen.
Bluetooth Low Energy am Raspberry-Pi
Da beide Controller ausschließlich den Low-Energy-Standard von Bluetooth 4.0 nutzen, muss der verwendete Raspberry Pi diesen Standard ebenfalls unterstützen. Beim eingebauten Bluetooth-Controller des Raspberry Pi 3 ist das der Fall. Bei nachgerüsteten USB-Dongles an älteren Raspis muss man neben Bluetooth-4.0-Fähigkeiten explizit auf Unterstützung des Low-Energy-Standards achten. Unter ct.de/y6ks stellen wir eine kleine Sammlung von Programmen und Skripten bereit. Das Linux-Script ble-test.sh stellt fest, ob der Bluetooth-Adapter die nötigen BLE-Fähigkeiten mitbringt.
Obwohl der BLE-Standard bereits ein paar Jahre auf dem Buckel hat, unterstützt ihn Linux-BlueZ bislang erst nur rudimentär. Das wichtigste Werkzeug ist, außer den auch für klassisches Bluetooth zuständigen Programmen „hciconfig“ und „hcitool“, das BLE-spezifische „gatttool“. Diese Programme sind bei aktuellen Distributionen wie Raspbian bereits vorinstalliert.
Unter dem Link haben wir auch einen Patch für hcitool hinterlegt, der dessen „lescan“-Kommando zum Suchen nach BLE-Geräten erweitert, sodass es wie nrF-Connect neben Bluetooth-Adresse und Gerätenamen weitere Informationen anzeigt. Unsere Beispiele laufen auch ohne diesen Patch, aber er hilft unter anderem beim Identifizieren des Lego-WeDo-Hub via UUID. Ein fertig für den Raspi übersetztes Tool ist ebenfalls im Download-Archiv zum Artikel enthalten.
Kommunikationsprofil
Die eigentliche Kommunikation über BLE GATT erfolgt durch das Lesen und Schreiben der namensgebenden Attribute. Unter Linux gibt es dafür gatttool. Durch Eingabe von gatttool -I startet man einen interaktiven Modus, in dem man manuell Geräte verbinden und mit ihnen kommunizieren kann. Die meisten Befehle kann man gatttool aber auch direkt als Parameter mitgeben. Im Download befinden sich drei einfache Beispiel-Skripte: batterie.sh, ft_bt_smart_led_blink.sh und lego_wedo_led_blink.sh. Sie verwenden hcitool und gatttool, um die Controller zu erkennen und ihren Batteriestand abzufragen respektive die in beiden Controllern vorhandenen LEDs blinken zu lassen.
Der BLE-Zugriff auf die Controller folgt dabei immer dem gleichen Muster. Zunächst muss die Bluetooth-Adresse des Gerätes gefunden werden. Das geschieht mithilfe des hcitool auf Basis der erstendrei Bytes der Bluetooth-Adresse (OID), des Bluetooth-Namens oder der eindeutigen Kennungen (UUIDs). Ist die Adresse bereits bekannt, kann die Suche per hcitool entfallen. Alle unsere Beispiele erlauben es daher, die Bluetooth-Adresse des anzusprechenden Controllers auch direkt als Parameter anzugeben. Über die Bluetooth-Adresse des Controllers baut gatttool die eigentliche Verbindung auf.
Nach dem Verbindungsaufbau werden die UUIDs der Dienste des Controllers abgefragt und im letzten Schritt die UUIDs der im Weiteren benötigten Funktionen eines Dienstes, welche die BLE-Spezifikation als GATT-Characteristics bezeichnet. Im Falle der Spielzeugcontroller sind vor allem die Funktionen zum Zugriff auf die Ein- und Ausgänge zum Anschluss von Motoren und Sensoren interessant. Sobald die Geräteadresse und Adressen der Funktionen bekannt sind, lassen sich die Ein- und Ausgänge ansteuern.
Die genaue Bedeutung der GATT-Funktionen und deren UUIDs stehen in ihren Beschreibungen auf bluetooth.com (Beispielprogramme für Lego und Fischertechnik zum Download). Hersteller- und gerätespezifische Funktionen werden aber in der Regel nicht durch standardisierte Dienste und Funktionen abgedeckt, sodass man auf Unterlagen der Hersteller angewiesen ist oder eigene Forschungen betreiben muss.
Lego-Controller für BLE
Für die Lego-Controller gibt es ein Entwickler-Kit (SDK) im Web. Da die nötigen Informationen dort recht tief im Source-Code versteckt sind, haben wir die wichtigsten Werte in der Tabelle unten zusammengefasst. Für die interessanten Teile der Kommunikation verwendet der WeDo-2.0-Controller nur wenige Attribute. Kommandos, die über die Funktion mit der UUID 00001565-1212-efde-1523-785feabcd123 ausgetauscht werden, beeinflussen zum Beispiel die Ausgänge des WeDo-Hub. Das schließt die LED am Controller ein und die Byte-Sequenz 06040109 schaltet beispielsweise die Farbe der LED auf rot.
Wichtigste herstellerspezifische Funktionen für Lego WeDo-2.0-Hub | |
Funktion |
Schreiben von Ausgangs-Kommandos |
Service-UUID | 00004f0e-1212-efde-1523-785feabcd123 |
Funktions-UUID | 00001565-1212-efde-1523-785feabcd123 |
Beispiel-Byte-Sequenzen | |
Motor setzen | CH 01 01 SD (CH=1/2, SD = Richtung –100…+100) |
Ton ausgeben | 05 02 04 FL FH DL DH (FH/FL=Frequenz, DH/DL = Dauer) |
LED-Farbindex setzen | 06 04 01 CI (CI=Farbe 01-09, 10 = aus) |
Funktion |
Schreiben von Sensor-Konfigurationen |
Service-UUID | 00004f0e-1212-efde-1523-785feabcd123 |
Funktions-UUID | 00001563-1212-efde-1523-785feabcd123 |
Beispiel-Byte-Sequenzen | |
Neigungssensor-Modus setzen | 01 02 CH 22 TM 01 00 00 00 02 01 (CH = 1/2, TM 00 = Winkel, 01 = Neigung) |
Bewegungssensor-Modus setzen | 01 02 CH 23 MM 01 00 00 00 02 01 (CH = 1/2, MM 00 = Distanz, 01 = Zähler) |
Funktion | Lesen von Sensor-Werten |
Service-UUID | 00004f0e-1212-efde-1523-785feabcd123 |
Charakteristik-UUID |
00001560-1212-efde-1523-785feabcd123 |
Beispiel-Byte-Sequenzen | |
Neigungssensor an Eingang 2 | 03 02 00 00 a0 40 (Byte 2-5: 32-Bit-Float-Wert) |
Funktion | Lesen von Anschlussereignissen |
Service-UUID | 00001523-1212-efde-1523-785feabcd123 |
Charakteristik-UUID | 00001527-1212-efde-1523-785feabcd123 |
Beispiel-Byte-Sequenzen | |
Neigungssensor (Typ 22) an Anschluss 1 angesteckt | 01 01 00 22 00 00 00 10 00 00 00 10 |
Motor (Typ 01) an Anschluss 2 angesteckt |
02 01 01 01 01 00 00 00 01 00 00 00 |
Gerät von Anschluss 2 entfernt | 02 00 |
Beim Lesen von Werten via BLE gibt es prinzipiell zwei Wege: Zum einen kann man vergleichbar zum Schreiben explizit einzelne Werte abfragen. Zum anderen kann man das Zielgerät auffordern, Werteänderungen von sich aus mitzuteilen. Das spart nicht nur Kommunikation, sondern auch Energie, da man nicht permanent nach geänderten Werten fragen muss (sogenanntes Polling). Diese Benachrichtigungen werden ihrerseits durch das Schreiben entsprechender Funktionen aktiviert.
Durch diesen Mechanismus kann der Lego-Controller nicht nur Änderungen von Sensorwerten melden, sondern auch das An- und Abstecken von Sensoren und Aktoren mitteilen. Unser Beispiel lego_dino.py macht von dieser Möglichkeit Gebrauch und es ist sogar möglich, das Modell während des Betriebs umzubauen.
Sensoren und Motoren von Fischertechnik für BLE
Da bei Fischertechnik die Sensoren und Motoren deutlich einfacher gehalten sind und keine automatische Erkennung der angeschlossenen Geräte möglich ist, gestaltet sich auch die Bluetooth-Kommunikation sehr viel einfacher als bei Lego. Es gibt nur wenige einfache Attribute für jeden Anschluss – das Beispielprogramm im Download-Archiv verdeutlicht dies.
Während die Lego-Kommandos kaum zu erraten wären, kommt man bei Fischertechnik auch ohne Dokumentation relativ schnell zu Ergebnissen. So finden die einleitend beschriebenen Suchmechanismen genau einen Dienst mit zwei Funktionen und zwei mit je vier Funktionen.
Wichtigste herstellerspezifische Funktionen bei Fischertechnik BT-Smart-Controller | |
Funktion | Kommunikationskanal-LED schalten |
Servive-UUID | 8ae87702-ad7d-11e6-80f5-76304dec7eb7 |
Funktions-UUID | 8ae87e32-ad7d-11e6-80f5-76304dec7eb7 |
Daten | 1 Byte schreiben: 00 =blau, 01 = orange |
Funktion | Ausgang schalten |
Service-UUID | 8ae883b4-ad7d-11e6-80f5-76304dec7eb7 |
Funktions-UUID Ausgang M1 | 8ae8860c-ad7d-11e6-80f5-76304dec7eb7 |
Funktions-UUID Ausgang M2 |
8ae88b84-ad7d-11e6-80f5-76304dec7eb7 |
Daten |
1 Byte schreiben, gültiger Wertebereich: –100..100 |
Funktion | Eingang konfigurieren |
Service-UUID | 8ae88d6e-ad7d-11e6-80f5-76304dec7eb7 |
Funktions-UUID Eingang I1 |
8ae88efe-ad7d-11e6-80f5-76304dec7eb7 |
Funktions-UUID Eingang I2 | 8ae89084-ad7d-11e6-80f5-76304dec7eb7 |
Funktions-UUID Eingang I3 |
8ae89200-ad7d-11e6-80f5-76304dec7eb7 |
Funktions-UUID Eingang I4 | 8ae89386-ad7d-11e6-80f5-76304dec7eb7 |
Daten | 1 Byte schreiben: 0x0a = Spannung, 0x0b = Widerstand |
Funktion | Eingang lesen |
Service-UUID | 8ae8952a-ad7d-11e6-80f5-76304dec7eb7 |
Funktions-UUID Eingang I1 |
8ae89a2a-ad7d-11e6-80f5-76304dec7eb7 |
Funktions-UUID Eingang I2 | 8ae89bec-ad7d-11e6-80f5-76304dec7eb7 |
Funktions-UUID Eingang I3 |
8ae89dc2-ad7d-11e6-80f5-76304dec7eb7 |
Funktions-UUID Eingang I4 | 8ae89f66-ad7d-11e6-80f5-76304dec7eb7 |
Daten |
2 Bytes lesen: 16-Bit-Wert in Millivolt bzw. Ohm |
Da der BT-Smart-Controller über je zwei Ausgänge und vier Eingänge verfügt, liegt der Verdacht nahe, dass es sich um zwei Funktionen zum Schalten der Ausgänge sowie um je vier zum Konfigurieren und Auslesen der Eingänge handelt. Ein paar Experimente mit gatttool und der nRF-Connect-App bestätigten diese Annahme. Das Ergebnis dieser Untersuchung haben wir in nebenstehender Tabelle zusammengefasst.
Wie beim Lego-Controller können auch hier LEDs und Ausgänge gesteuert sowie die Eingänge abgefragt werden. Während die intelligenten Lego-Sensoren gleich vorverarbeitete Werte liefern, kann man bei Fischertechnik nur Spannungen und Widerstände messen und muss diese dann selbst je nach Sensor in Helligkeitswerte, Temperaturen und so weiter übersetzen. Auch bei Fischertechnik kann man Benachrichtigungen nutzen. Wechsel von Sensoren und Aktoren erkennt der Fischertechnik-Controller indessen nicht.
So gut sich das gatttool für einfache erste Tests eignet, so wenig brauchbar ist es für komplexe Programmierung. Für einige Programmiersprachen gibt es inzwischen Anbindungen an die BlueZ-GATT-API. Ich nutze exemplarisch python-gatt (Beispielprogramme für Lego und Fischertechnik zum Download), um direkt aus Python-Programmen auf die Controller zuzugreifen.
Ich habe je ein einfaches Beispielprogramm zur Steuerung des Karussell-Modells aus dem Fischertechnik-Baukasten respektive des Dinosauriers aus dem WeDo-2.0-Set geschrieben. Diese Beispielprogramme ft_karussell.py und lego_dino.py finden sich ebenfalls im Software-Archiv zu diesem Artikel, ebenso eine Beschreibung, wie man das eventuell nötige Update auf BlueZ 5.44 auf dem Raspberry Pi vornimmt, das für Python-GATT erforderlich ist.
Ausblick
Dank Bluetooth-Schnittstelle lassen sich Raspberry Pi und aktuelle Spielzeug-Controller mit geringem Aufwand koppeln. Die hier kurz vorgestellten Beispiele sind so beliebig zu erweitern und zu verändern. Dank der im Vergleich zu den Lego-EV3- und Fischertechnik-TXT-Controllern höheren Flexibilität und Leistungsfähigkeit eines aktuellen Raspi 3 bei deutlich geringerem Preis eröffnet sich in Kombination mit den Konstruktionsbaukästen eine solide Basis für spannende Robotik-Experimente. (tig)