Last Updated on 31. Mai 2019 by sfambach
Ansteuerung eines Servos mit dem Raspberry PI 3.
Hierbei geht es nur um die grundlegende Technik, der Einsatz könnte beispielsweise ein Mobiler Roboter sein.
Der Servo soll hierbei über den Software PWM angesteuert werden um die Hardwar PWMs für andere Funktionen frei zu halten.
Zusätzlich soll der Servo nicht wie üblich über Integer Werte gesteuert werden sondern über eine Gradzahl im Bezug zur Mittelstellung des Servos.
Das unten stehende Bild zeigt was hiermit gemeint ist.
Auf die eigentliche Funktionsweise eines Servos gehe ich hier nicht ein, dies kann bei Bedarf bei http://rn-wissen.de/wiki/index.php/Servos oder anderen Websites nachgelesen werden.
Benötigte Hardware
- PI3 (oder älter bitte auf die richtigen Pins achten)
- Standard-Servo
- Diverse Kabel ( Vorgefertigte Pin-Header Kabel)
Aufbau der Schaltung
Die Ansteuerung des Servos geschieht in meinem Fall über GPIO 27. Die Spannungsversorgung liefert der PI. Für größere Servos müsste evtl. auf eine externe Spannungsversorgung zurückgegriffen werden.
(Die GPIOs gelten nur in Verbindung mit pi4j und wirePi)
Software
Als Entwicklungsumgebung verwende ich BlueJ auf dem PI selbst. Hiermit habe ich die folgenden Klassen erstellt.
Code
Ein Erster Test
Ein guter Anfang ist immer den im Internet gefundenen Code eine Main Funktion zu packen, um zu schauen ob überhaupt was klappt. Dies habe ich in Form der FirstTest Klasse getan. Sie fährt alle Positionen des Servos ab. Die Funktionalität ist hier nicht gekapselt.
Gekapselter Code
Als nächsten Schritt habe ich den Code aus dem ersten Test genommen und ihn mit ein paar Änderungen in eine Klasse gepackt. Hierbei habe ich auch die Umrechnung von absoluten Werten in Grad implementiert. Für den Test der Klasse habe ich wiederum eine Main-Klasse erstellt die alles mal aufruft.
Servo-Klasse
Klasse zur Steuerung des Servos. Die zwei wichtigsten Methoden sind:
- setPos – Setzen der Position, Wertebereich von posMin bis posMax wobei (posMax-posMin+1) die Mittelstellung ist.
- setDeg – Diese Methode projeziert die angegebene Gradzahl auf die möglichen Positionen (aktuell sehr ungenau )
Test-Klasse
Klasse mit Main-Methode zum Testen der Servo-Klasse. In der Main-Methode werden alle Positionen abgefahren wobei die Positionierung über den Winkel relativ zur 0 Position erfolgt.
Tips
Das Positionieren über die PI4j Lib ist sehr ungenau für die 180° Bewegungsspielraum des Servos stehen gerade mal rund 20 (+-2) Positionen zur Verfügung. Das sind rund 9° pro Position. Evtl. sollte man vorher testen welche Positionen für den Aktuellen Zweck am besten geeignet sind. Sollte der genaue Winkel wichtig sein, ist es besser diesen vorab zu messen als ihn über die setDeg Methode berechnen zu lassen.
Es gibt noch weitere Lib’s (Servoblast, … ) die evtl genauer sind, man könnte auch überlegen die Programmiersprache zu wechseln und dann den Ensprechenden Code über das Nativ-Interface anzusprechen. Als nächsten Versuch klingt Servoblast ersteinmal vielversprechend.
Weitere Schritte
PWM in Thread
Ich habe versucht den Software PWM innerhalb eines Threads laufen zu lassen, jedoch ohne Erfolg. Der Servo weigert sich zu funktionieren. Über die Ursache hierfür bin ich mir noch im unklaren. Ich nehme allerdings an, dass hierdurch der Timer zerschossen wird.
ServoBlast
Nach diversen Tests mit unterschiedlichen Frequenzen habe ich mich entschlossen ServoBlaster od. besser die PI variante (PiBits) zu verwenden. Die Installation gestaltet sich einfach wie folgt.
Programmierbeispiel
An dieser Stelle sollte nun eigentlich ein Code-Beispiel mit ServoBlast folgen. Da ich aktuell aber die Arbeiten am PI eingestellt habe und mit dem ESP8266 und ESP32 unterwegs bin, sei auf die folgenden Links verwiesen:
Problembehandlung
Exec Funktioniert nicht
Wenn die exec Funktion von Java nix macht ist hier ein guter Link zum Bugfixing.
http://www.javaworld.com/article/2071275/core-java/when-runtime-exec—won-t.html
Probleme mit println
Weiterhin könnte es helfen nicht die println Methode zu verwenden, sondern die print. Da zumindest mein PI den Abschluss der Zeile nicht richtig interpretieren konnte. print( „5=100\n“) hat jedoch funktioniert.
Verwandte Beiträge
Quellen
http://razzpisampler.oreilly.com/ch05.html
https://github.com/Pi4J/pi4j/blob/master/pi4j-example/src/main/java/MaestroServoExample.java
https://phyks.me/2015/05/controlling-servomotors-on-a-raspberry-pi.html
https://github.com/richardghirst/PiBits/tree/master/ServoBlaster
http://rn-wissen.de/wiki/index.php/Servos
Dafür, dass der Artikel über ein Jahr alt ist finde ich es recht schade, dass man an einigen Stellen weiterhin „… kommt noch“ lesen muss.
Ebenso fehlt wohl irgendwas bei den „gistpen id“-Zeilen.. – oder ich verstehs nicht.
Hallo und danke für deinen Kommentar.
Ja das mit dem Alter des Beitrags ist so eine Sache, ich habe diesen im letzten Urlaub angefangen und bin dann nicht mehr dazu gekommen, bzw. habe mich in letzter Zeit mehr mit dem ESP8266/ESP32 beschäftigt. Ich bin leider noch zu keinem dokumentierten Test mit ServoBlast gekommen vielleicht im nächsten Urlaub ;). Ich habe den Beitrag mal dementsprechend angepasst um den Leser hierüber zu informieren. Es sind nun nochmal die zwei Seiten gelinkt, welche die Verwendung von ServoBlast aus meiner Sicht ganz gut beschreiben.
Das mit der Gistpen id ist ärgerlich. Eine Version von Gistpen hatte leider nicht funktioniert, diese führte dazu, dass jede Seite mit Quellcode nicht mehr angezeigt wurden. Aus diesem Grunde hatte ich es leider deaktivieren müssen und wie immer hatte ich keine Zeit die alten Seiten zu überarbeiten. Auf neunen Seiten biete ich jetzt einen Download an. lange Rede kurzer Sinn, Ich habe Gistpen in der aktuellen Version reaktiviert und es scheint wieder zu funktionieren.
Gruß SFA