Computer, Technik

„Pi3D2“: Ein kleiner Roboter im Eigenbau đŸ€–

Es ist schon lange her, dass ich ĂŒberlegt hatte, was ich mit einem Raspberry Pi so alles anstellen könnte. Eine von vielen Ideen, die ich beim Stöbern im Netz hatte, war es, einen eigenen, kleinen Roboter zu bauen, inspiriert von R2-D2. Hier möchte ich nun schildern, wie ich vorgegangen bin, welche Tutorials und Bauteile ich verwendet habe und was letzten Endes (vorerst) dabei herausgekommen ist. Dies ist keine Schritt-fĂŒr-Schritt-Anleitung, sondern vielmehr eine Zusammenfassung des Projektes.

Ein kurzes Demo-Video des vorlÀufigen Ergebnisses mit Fernsteuerung und Sound-Wiedergabe.

VorĂŒberlegungen und Recherche

Was sollte so ein Roboter können, und vor allem: wie geht das? NatĂŒrlich gibt es völlige Over-the-top-Versionen von voll funktionsfĂ€higen R2-D2s wie diesem hier. Aber das ist fĂŒr einen blutigen AnfĂ€nger wie mich zu viel des Guten. GrundsĂ€tzlich sind die Ideen aber nicht schlecht, und so wollte ich zunĂ€chst folgende Dinge verwirklichen:

  • Fahrender Roboter mit Fernsteuerung
  • Er sollte auch autonom fahren und Hindernissen ausweichen können.
  • Installierter Sprachassistent (Alexa, Google o.Ă€.)
  • Gesichtserkennung

Bevor ich loslegte, suchte ich im Netz nach Ă€hnlichen Projekten, von denen ich klauen lernen konnte. Einerseits fand ich viele Ergebnisse und Anleitungen fĂŒr Pi-basierte Roboter generell, daneben aber auch welche, die sich speziell an R2-D2 orientierten. Folgende Projekte habe ich also ausprobiert bzw. in irgendeiner Form weiterverwendet:

Neben diesen Roboter-Tutorials habe ich auch vieles an Software ausprobiert. FĂŒr den fertigen Prototyp habe ich diese beiden Anleitungen genutzt:

Getting started!

Das HerstĂŒck des Roboters ist ein Raspberry Pi 3, daher auch der Name „Pi3D2“. Zu Beginn folgte ich der oben verlinkten Anleitung auf tutorials-raspberrypi.de. In einzelnen Schritten ist beschrieben, wie man den Roboter zusammenbaut und welche Funktionen man hinzufĂŒgen kann. Auch die nötigen Programme sind enthalten. Da dort schon alles ausfĂŒhrlich erklĂ€rt ist, werde ich das Tutorial nicht wiederholen, sondern nur meine Erfahrungen damit schildern.

GrundsĂ€tzlich wird fĂŒr den Raspberry Pi in solchen Projekten ĂŒbrigens die Programmiersprache „Python“ benutzt, die in zwei Versionen existiert: Python 2 (Standard) und Python 3. Hierbei muss man dann beachten, fĂŒr welche Version man programmiert bzw. Beispiele heruntergeladen hat, damit es hinterher auch funktioniert. Das war in manchen FĂ€llen eine (von vielen!) Fehlerquellen.

Entsprechend der Anleitung hatte ich mir einen Bausatz zu meinem Raspberry Pi bestellt sowie die anderen benötigten Kleinteile. Der Vorteil des Tutorials ist die AusfĂŒhrlichkeit und das Aufbauen „from scratch“, also z.B. ohne vorgefertigte Motorensteuerungen. Man muss tatsĂ€chliche die Elemente auf dem Breadboard aufsetzen und alles selbst genau verbinden und entsprechend in den Programmen anpassen. Das Resultat kann dann schnell unĂŒbersichtlich (und fehleranfĂ€llig) werden. Zudem gefiel mir die Form nicht, und in dieser Variante gelang es mir nicht, das ganze in die notwendige „Eimerform“ zu bringen.

Upgrade: der MĂŒlleimer-Look

Ein MĂŒlleimer als GehĂ€use.

Bevor ich zu Software-VerĂ€nderungen ĂŒberging, wollte ich das Aussehen anpassen. In einem gĂŒnstigen Hauswarenladen fand ich einen passenden PlastikmĂŒlleimer, der mit Deckel ca. 20 cm hoch ist und somit gerade genug Raum bietet, um den Raspberry Pi mit Powerbank und anderen Teilen unterzubringen. Allerdings war das Fahrgestell des Bausatzes ungeeignet und passte nicht. Außerdem wollte ich Beine haben, um dem Look von R2 nĂ€her zu kommen. Da es hierzu keine passenden Teile gibt, habe ich entsprechende Beine mit dem kostenlosen Online-3D-Designprogramm Tinkercad kurzerhand selbst entworfen und dann am 3D-Drucker ausgedruckt. Alle RĂ€der habe ich entsprechend mit Schrauben am Eimer montiert und das Gelenk des kleinen Vorderrads mit der Heißklebepistole fixiert, da es sonst hin- und herwackeln wĂŒrde.

Die Schwingklappe des Eimers habe ich mit blauem Isolierband fixiert, was auch ganz gut aussieht. Als „Auge“ dient der Deckel eines Deosprays, hinter dem sich eine LED verbirgt. Diese ist einfach als Power-LED geschaltet und leuchtet, sobald der Pi Strom bekommt (zur Verkabelung siehe unten). Über eine USB-VerlĂ€ngerung ist ein kleines Mikrofon angeschlossen (das ist das schwarze Dinge hinter der Kuppel im letzten Bild), sodass man mit Alexa sprechen kann. Außerdem ist ĂŒber den Klinkenausgang ein kleiner Lautsprecher angeschlossen.

Murphy’s Law …

Im unteren Bereich hatte ich das ovale Loch ausgeschnitten, um hier den Ultraschallsensor fĂŒr die Hindernis-Erkennung einzubauen. In ersten AnlĂ€ufen hat das Programm des Tutorials auch funktioniert. Da es mir etwas zu umstĂ€ndlich war, ĂŒber mehrere Programme hinweg die Funktionen aufzurufen, verwendete ich dann den Code von circuitdigest.com. Dieser ist einfacher und erfĂŒllt den Zweck genauso.

Durch die SchrĂ€gstellung des Eimers wurden aber nicht immer alle Hindernisse erkannt. Außerdem erfolgte die Erkennung hĂ€ufig zu spĂ€t, sodass ein Ausweichen nicht mehr möglich war. Was ich zu diesem Zeitpunkt noch nicht wusste: der Chip zur Motorsteuerung funktionierte scheinbar nicht richtig, weshalb der Roboter generell viel zu langsam fuhr und reagierte.

Fernsteuerung, aber wie?

Das erste Tutorial beinhaltet auch die Möglichkeit von Fernbedienungen. Die einfache Variante schien mir die Verwendung einer Infrarot-Fernbedienung, die genauso funktioniert wie z.B. die Fernbedienung des Fernsehers. Aus einem anderen Bausatz hatte ich alle nötigen Teile, doch aus irgendeinem Grund hat es nie richtig funktioniert. Nur manche TastendrĂŒcke wurden erkannt, aber nicht immer reagierte der Roboter.

Noch ein Fehlschlag. Im Grunde konnte der Roboter also nicht fahren, weder autonom, noch ferngesteuert. Der Frust war groß, hatte ich doch Stunden und Tage investiert. Das Projekt blieb daher zunĂ€chst auf Eis …

May the pHAT be with you!

Aufgeben kam aber nicht in Frage. Ich hatte nun so viel Zeit und Geld investiert und auch Spaß an der Arbeit, dass ich das unmöglich auf mir sitzen lassen konnte. Die Anleitung zum Mini-R2, der auf dem Pi Zero basierte, brachte mich auf die Idee, den Explorer pHAT fĂŒr den Pi zu kaufen und es damit noch einmal zu probieren. Der Vorteil: solch ein Aufsatz wird direkt auf den Pi gelötet und beinhaltet alle nötigen Chips. Außerdem steht entsprechende Software zur VerfĂŒgung, die einem das Programmieren ungemein erleichtert. Wichtige Funktionen wie das Fahren sind bereits vordefiniert und lassen sich kinderleicht aufrufen.

Und tatsĂ€chlich: mit dem Explorer war das Fahren kein Problem mehr. Plötzlich drehten sich die RĂ€der schnell genug. Ein weiterer, enormer Vorteil: im Gegensatz zum kompletten Eigenbau des ersten Tutorials, das fĂŒr den Betrieb der Motoren vier AA-Batterien erforderte, kommt nun der Strom allein aus der Powerbank. Das senkt das Gesamtgewicht enorm und spart auch Platz im GehĂ€use, das sowieso nicht besonders groß ist. Der Explorer war also ein voller Erfolg!

Die Verkabelung

Schaltplan des Pi3D2, hier mit Explorer HAT Pro statt pHAT. Der Aufbau ist jedoch gleich.

Wie man im rechten Foto oben sehen kann, sind die verfĂŒgbaren Pins beschriftet. Die vier Pins ganz rechts sind fĂŒr die Motoren (je Seite einmal + und -). Man kann sie auch einfach ausprobieren, indem man sie verbindet und den Pi fahren lĂ€sst. Sollten sich die RĂ€der falsch herum drehen, so muss man + und – vertauschen. Zum Testen kann man das unten eingefĂŒgte Python-Skript fĂŒr die Fernsteuerung benutzen oder fĂŒr den Anfang z.B. das Beispiel aus dem Artikel von techradar.com.

Wie weiter unten beschrieben ist ein kleines Lautsprecher-Board ĂŒber den „5V“-Pin (Stromzufuhr) und den „GND“-Pin (Erdung) verbunden. Das gleiche habe ich mit einer roten LED gemacht, die auf diese Art als Power-LED funktioniert. Die LED benötigt aber noch einen 330Ω-Widerstand, damit sie nicht verbrennt.

Bonus: zusÀtzliche Status-LED

Man kann auch eine Status-LED hinzufĂŒgen (oder die rote LED so verwenden), die bei Auslastung blinkt, wie man es auch vom PC kennt. Dazu wird die LED neben 5V nicht mit GND, sondern mit einem Output verbunden. In meinem Fall musste ich die 5V ĂŒber ein Mini-Breadboard umleiten, denn fĂŒr zwei LEDs und den Lautsprecher benötigt man insgesamt drei Stromzufuhren, der Explorer bietet jedoch nur zwei.

Die Verwendung als Status-LED muss noch dem Pi mitgeteilt werden. Am besten verwendet man „Output 4“, da dieser mit dem Pi direkt verbunden ist und vom Explorer pHAT noch nicht anderweitig verwendet wird. Um dem Pi mitzuteilen, dass Output 4 nun fĂŒr den Status verwendet werden soll, muss man die config.txt Ă€ndern. Das geht ĂŒber das Terminal (direkt am Pi oder SSH-Zugriff) so:

sudo nano /boot/config.txt

In dieser Datei scrollt man ganz nach unten und fĂŒgt dort diese Zeilen hinzu:

# Status-LED an Output 4
dtoverlay=pi3-act-led,gpio=16

Der Pi bekommt hier mitgeteilt, dass der Pin GPIO16 auf dem Board als „act-led“ verwendet werden soll. GPIO16 ist wiederum ĂŒber den Explorer pHAT verbunden mit Output 4. Wenn alles richtig verkabelt ist, sollte nun die LED bei Auslastung blinken.

„Do or do not. There is no try.“

Die Fernsteuerung – Teil 2 🎼

Da die bisherigen Lösungen nicht funktionierten, versuchte ich nun eine neue Methode fĂŒr die Fernsteuerung. FĂŒr den NESPi hatte ich ursprĂŒnglich noch einen Bluetooth-Controller gekauft, den ich ĂŒbrig hatte. Diesen wollte ich als Fernsteuerung benutzen. Leider ist das ohne Aufwand nicht möglich, denn Treiber und Anleitungen findet man eher fĂŒr Konsolen-Controller wie z.B. von der PlayStation. Die Lösung fand ich nach langem Suchen in dem YouTube-Video von Core Electronics, deren Anleitung auch in Textform unter dem Video verlinkt ist. Das Ganze lĂ€sst sich so zusammenfassen: das Gamepad wird ĂŒber Bluetooth verbunden. Dann werden schrittweise die Daten ausgelesen, die beim DrĂŒcken der Knöpfe empfangen werden. Diese werden so lange gefiltert, bis man genau weiß, welcher Knopf welche „Meldung“ ausgibt. Nun kann man diese Meldungen mit Namen versehen – z.B. den Tasten A, B, X, Y – und in Programmen einbinden.

Das Lautsprecher-Problem

PAM8403 VerstÀrker

Bisher hatte ich einen kleinen Lautsprecher ĂŒber Kabel angeschlossen, den ich vor Jahren fĂŒr die Schule benutzt hatte. Das Problem: der Lautsprecher besitzt einen Akku, weshalb ich ihn nicht permanent ĂŒber USB an den Pi anschließen wollte, da der Stromverbrauch zusĂ€tzlich zu den Motoren wahrscheinlich zu hoch wĂ€re. Außerdem war der Lautsprecher recht groß und schwer. Ich hatte aber noch einen gĂŒnstigen Bluetooth-Lautsprecher, der sich nie richtig verbinden ließ. Diesen nahm ich auseinander, um nur den Lautsprecher selbst zu verwenden. Nun fehlte noch eine Anschlussmöglichkeit mit VerstĂ€rker. Zum GlĂŒck gibt es entsprechende kleine VerstĂ€rkermodule, die sogar einen LautstĂ€rkeregler besitzen. Dazu braucht man noch ein Audiokabel mit Klinkenstecker, das man auf einer Seite öffnet und abisoliert. Die Enden werden am „Input“ des VerstĂ€rkers angelötet, die Kabel des Lautsprechers kommen an „rout“ (oder „lout“). Der Strom kommt vom 5V-Ausgang des Explorers. Der Minuspol ist immer die Erdung („GND“ fĂŒr „ground“).

Die Software

Im Grunde ist nur ein Programm nötig, um den Roboter fernzusteuern. Vieles kommt bereits aus der Software, die man fĂŒr den Explorer pHAT installiert (hier die Anleitung). Voraussetzung ist außerdem ein funktionierender Controller, der korrekt verbunden ist und dessen Eingaben erkannt werden. Mein Gamepad wird erkannt als „/dev/input/event1“, das wird entsprechend im Programm definiert und muss ggf. angepasst werden. Folgt man der oben verlinkten Anleitung sollte das aber bereits geklĂ€rt sein.

Außer der Fernsteuerung habe ich zum Ausprobieren noch Sounds eingebaut, die man mit den Buttons abspielen kann. Hier ist der Code, den man als *.py-Datei speichert. Ich habe die Datei „explorer-gamepad.py“ genannt. Achtung: Es handelt sich um Python 3, also muss die Software auf dem Pi entsprechend vorhanden und aktuell sein. Außerdem muss das Programm dann auch ĂŒber „python3“ aufgerufen werden.

#!/usr/bin/python3
# coding: utf-8

import explorerhat
from time import sleep
from random import randint
import time
import sys, signal
import simpleaudio as sa
from evdev import InputDevice, categorize, ecodes

gamepad = InputDevice('/dev/input/event1')

aBtn = 36
bBtn = 37
xBtn = 50
yBtn = 23
up = 103
down = 108
left = 105
right = 106
start = 21
select = 19

def signal_handler(signal, frame):
    print("\nprogram exiting gracefully")
    stop()
    sys.exit(0)

signal.signal(signal.SIGINT, signal_handler)

def stop():
    print("stop")
    explorerhat.motor.stop()

def forward():
    explorerhat.motor.one.forward(50)
    explorerhat.motor.two.forward(50)
#    explorerhat.output.one.blink(0.5,0.5)
    print("forward")

def back():
    explorerhat.motor.one.backward(50)
    explorerhat.motor.two.backward(50)
#    explorerhat.output.one.blink(0.5,0.5)
    print("backward")

def turnleft():
    explorerhat.motor.one.backward(50)
    explorerhat.motor.two.forward(50)
#    explorerhat.output.one.blink(0.5,0.5)
    print("left")

def turnright():
    explorerhat.motor.one.forward(50)
    explorerhat.motor.two.backward(50)
#    explorerhat.output.one.blink(0.5,0.5)
    print("right")

for event in gamepad.read_loop():
    if event.type == ecodes.EV_KEY:
        if event.value == 1:
            if event.code == up:
                wave_obj = sa.WaveObject.from_wave_file("/home/pi/sounds/R2b.wav")
                play_obj = wave_obj.play()
                play_obj.wait_done()
                forward()
                time.sleep(1.0)
                stop()
            elif event.code == down:
                back()
                time.sleep(1.0)
                stop()
            elif event.code == right:
                turnright()
                time.sleep(1.0)
                stop()
            elif event.code == left:
                turnleft()
                time.sleep(1.0)
                stop()
            elif event.code == start:
                stop()
            elif event.code == aBtn:
                wave_obj = sa.WaveObject.from_wave_file("/home/pi/sounds/R2c.wav")
                play_obj = wave_obj.play()
                play_obj.wait_done()
            elif event.code == bBtn:
                wave_obj = sa.WaveObject.from_wave_file("/home/pi/sounds/R2a.wav")
                play_obj = wave_obj.play()
                play_obj.wait_done()
            elif event.code == xBtn:
                wave_obj = sa.WaveObject.from_wave_file("/home/pi/sounds/R2e.wav")
                play_obj = wave_obj.play()
                play_obj.wait_done()

Die Zeilen, die mit # auskommentiert sind, hatte ich ursprĂŒnglich genutzt, um die rote LED blinken zu lassen. Voraussetzung ist, dass die LED an „5V“ und an „Output 1“ angeschlossen ist.

Zugriff auf den Pi đŸ“±

Ein Problem bleibt noch: die Software lĂ€sst sich nur ĂŒber Fernsteuerung auf dem Pi starten. Weder Alexa noch die Fernsteuerung konnte ich automatisch starten lassen, obwohl ich sĂ€mtliche Verfahren ausprobiert habe. Das Problem ist bei Alexa, dass es in einem Terminal-Fenster ausgefĂŒhrt werden muss, das nicht ĂŒber Autostart zu öffnen ist. Warum aber das Python-Programm nicht funktioniert kann ich auch nicht nachvollziehen. Da ich aber sowieso eine Verbindung brauche, ist das egal.

In Termux Verbindung herstellen und Alexa starten.

Zu Hause nutze ich den PC, um ĂŒber WLAN eine SSH-Verbindung herzustellen. Das bedeutet ich greife auf den Pi zu und logge mich von außen als Nutzer ein, wodurch ich dann in der Konsole Befehle eingeben kann, als wĂ€re ich direkt am Pi eingeloggt. Somit ist eine Fernsteuerung möglich. Diese Funktion muss zunĂ€chst im Pi freigeschaltet werden. Voraussetzung ist, dass Pi und der PC, den ich nutze, im selben WLAN sind. Wer es mobiler möchte und ĂŒber ein Android-Smartphone verfĂŒgt, kann auch dieses nutzen. Man benötigt lediglich eine Terminal-App wie z.B. das kostenlose und hervorragende Termux. Dort muss man noch ssh nachinstallieren ĂŒber „pkg install ssh“.

Die Verbindung mit dem Pi stellt man grundsÀtzlich so her:

ssh pi@IP.Adresse.des.Pi

Nach der Verbindung wird man noch nach dem Passwort gefragt. Dieses kann man zuvor auf dem Pi einstellen. Ist man verbunden, so hat man Zugriff auf die Funktionen des Pi. Wenn man Alexa und die Fernsteuerung parallel starten möchte, muss man zunÀchst eins von beiden aufrufen und dann ein neues Terminal-Fenster öffnen, damit das erste Programm im Hintergrund weiterlaufen kann. Alexa startet man aus dem Home-Verzeichnis heraus mit diesem Befehl:

sudo bash startsample.sh

In einem neuen Terminal-Fenster startet man die Fernsteuerung:

sudo python3 explorer-gamepad.py

Sonderfall: Verwendung außerhalb des heimischen WLANs

Möchte man per Smartphone außerhalb von zu Hause auf den Pi zugreifen, so ist das auch möglich, indem man einen Hotspot mit dem Handy herstellt. Allerdings muss man zuvor Zugriff auf den Pi haben, um im Voraus die Zugangsdaten fĂŒr den Hotspot zu speichern. Am einfachsten geht es, wenn man Monitor und Maus am Pi hat, einen Hotspot erstellt und sich verbindet. Der Zugang wird gespeichert fĂŒr zukĂŒnftige Verwendungen. Es geht aber auch ohne Monitor, wenn man sich ĂŒber SSH vom PC aus auf dem Pi einloggt und die passenden Daten ĂŒber das Terminal ergĂ€nzt. Dazu muss man die Datei wpa_supplicant.conf editieren:

sudo nano /etc/wpa_supplicant/wpa_supplicant.conf

In dieser Datei sind die WLAN-ZugĂ€nge gespeichert. Hier fĂŒgt man einfach die Daten des Handy-Hotspots hinzu:

network={
   ssid="WLAN-SSID"
   psk="WLAN-PASSWORT"
}

Mit Strg + X beendet man den Texteditor und schon ist nach einem Neustart der Zugriff auch mobil möglich. Wenn der Pi ĂŒber den Hotspot verbunden ist, kann man am Handy das GerĂ€t antippen und sieht die IP-Adresse, um sich dann ĂŒber Termux zu verbinden.

Fertig ist der kleine, ferngesteuerte Roboter mit Alexa-UnterstĂŒtzung. Es gibt auch eine R2-D2-Skill fĂŒr Alexa, die man verwenden kann, um den Roboter piepen zu lassen. Alternativ kann man ĂŒber die Tasten des Gamepads verschiedene Sounds abspielen lassen, wenn man möchte. Der Code ist in meinem Beispiel enthalten und lĂ€sst sich leicht anpassen.


Hinterlasse einen Kommentar