Mehrere Servo Motoren gleichzeitig per Raspberry Pi steuern (PCA9685)

5. November 2017
6 Comments

Mittels PWM kann ein Servo Motor am Raspberry Pi gesteuert werden. Möchte man mehr als einen Servo Motor lenken, so kann man entweder für jeden der Servos einen GPIO nutzen oder ein Treiber Board wie das PCA9685 am Raspberry Pi anschließen, womit per I2C fast beliebig viele Motoren separat gesteuert werden können.

In Projekten wie einem Roboterarm ist ein solches Treiberboard für mehrere Servomotoren unumgänglich, auch da die Motoren einen recht hohen Strombedarf haben.

 

Zubehör

Bis zu 15 Servo Motoren können pro PCA9685 gesteuert werden.

Je nach Stärke der Motoren wird die Stromversorgung über die GPIOs der Raspberry Pi’s nicht ausreichen. Daher solltest du über ein externes Netzteil nachdenken. Dies kann entweder ein einstellbares oder z.B. ein Schaltnetzteil mit 5V (wie hier verwendet) sein.

Folgendes Zubehör solltest du für dieses Tutorial haben:

Achte bei deinem Netzteil, dass es genügend Power für alle Motoren hat. Wenn wir bspw. von 6 Motoren und ~500mA pro Motor ausgehen, so sollte es 3A liefern können. Da allerdings z.B. beim 6DOF Robot Arm nur selten alle 6 Motoren gleichzeitig laufen, sollte auch ein Netzteil mit weniger Stromstärke ausreichen.

Im Grunde ist die Anzahl der Motoren für dieses Projekt egal (bis zu 16 pro Board). Falls du vorläufig also nur einen Motor zur Hand hast, sollte dies dennoch ausreichen, da sich die Programmierung super einfach auf weitere Servos zu übertragen.

 

Raspberry Pi PCA9685 – I2C Adressierung

Das PCA9685 hat außerdem noch einige Lötkontakte, welche zum Festlegen der I2C Adresse gedacht sind. Ist kein Kontakt verlötet, so hat es die I2C Hex Adresse 0x40. Wenn mehrere dieser Boards verwendet werden sollen, muss jedes eine eigene Adresse bekommen. Dafür sind die Lötstellen, wobei die Nummerierung einem Binär Wert entspricht:

  • A0 = 2^0 (bspw. 41)
  • A1 = 2^1 (bspw. 42)

Somit könnten theoretisch bis zu 2^6 (= 64) der Boards hintereinander geschaltet werden und alle über Ihre eigene Adresse angesprochen werden. Und jedes der Boards kann ebenfalls 16 Servos steuern. Das sollte in jedem Fall ausreichen. Mehr Details dazu findest du u.a. im Datenblatt.

 

PCA9685 Anschluss an den Raspberry Pi

Das PCA9685 Modul wird über den I2C Bus gesteuert (SDA und SCL). Der Bus wird über 3.3V mit Strom versorgt, wobei die Power für die Motoren aus einer anderen Quelle kommt.

PCA9685 Raspberry Pi
SCL GPIO 3 / SCL (Pin 5)
SDA GPIO 2 / SDA (Pin 3)
VCC / V 3,3V (pin 1)
GND GND (Pin 6)

Die restlichen Pins (V+ und OE) bleiben unbelegt. Falls du mehr als ein I2C Modul nutzt, kannst du vom anderen Ende die anderen Module in Reihe anschließen.

Raspberry Pi mehrere Servos anschließen

Stärkere Servos wie der MG996R können bis zu 1.5A verbrauchen, weshalb eine externe Stromversorgung bei entsprechender Belastung bzw. bei mehreren Motoren sehr zu empfehlen. Bei einem oder zwei Servo Motoren kannst du die „externe“ Stromversorgung auch vom Raspberry Pi beziehen (üblicherweise wollen Servos ~5V). Der Strom reicht aber nicht für viele Servos, weshalb du z.B. beim Roboter Arm Projekt o.ä. auf eine externe Stromversorgung zurückgreifen solltest.

 

 

Installation der benötigten Tools

Öffne ein neues Terminal (z.B. per SSH) und gib folgendes ein:

sudo apt-get install build-essential python-dev python-smbus i2c-tools python-pip --yes

Falls Python3 genutzt werden soll, so müssen die Paketnamen natürlich entsprechend angepasst werden. Wir aktivieren zunächst I2C, sofern nicht schon geschehen:

sudo raspi-config

Unter „Interfacing Options“ -> „I2C“ wird es aktiviert. Wir schauen nun, ob das Board auch erkannt wird:

i2cdetect -y 1

Hier solltest du die Adresse des Boards sehen. Falls du die Adresspins verlötet hast, hast du ggf. eine andere Adressierung (wie oben beschrieben). Ansonsten sollte die Ausgabe folgend aussehen:

pi@raspberrypi:~ $ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: 70 -- -- -- -- -- -- --

Anschließend installieren wir noch den Python Treiber für das Servo Board (wer den Code einsehen möchte bzw. lieber aus dem Repository installieren möchte, kann einen Blick in das GitHub Repo werfen). Einfacher ist es jedoch hiermit:

 sudo pip install Adafruit-PCA9685

 

Beispiele & Erklärung zur Nutzung des PCA9685 am Raspberry Pi

Alle folgenden Befehle sind in der Python Konsole auszuführen (sudo python) oder in ein entsprechendes Python Skript zu schreiben.

Zunächst einmal müssen wir die Bibliothek einbinden:

Als nächstes gilt es das PCA9685 Treiber Board zu initialisieren. Dabei hast du die Möglichkeit eine andere Adresse als 0x40 anzugeben, sofern gewünscht. Falls du den Parameter nicht angibst, wird automatisch 0x40 genommen:

Wie auch bei der gewöhnlichen PWM Steuerung über GPIOs müssen wir ebenfalls eine Frequenz angeben (in Hertz). Der Wert kann dabei zwischen 40 und 1000 liegen. Diese gilt für alle angeschlossenen Motoren:

Die gesendeten Impulse sind natürlich abhängig von der Frequenz und müssen ggf. angepasst werden.

Der zweite wichtige Befehl ist jener, mit dem wir den Puls für einen angeschlossenen Servo Motor senden. Der erste Parameter ist dabei der Channel (zw. 0 und 15), der zweite und dritte Parameter ist die relative Pulslänge im Verhältnis zu 4096 (was 2^12 entspricht). Die Differenz der beiden Werte darf nicht größer als 4096 sein.
Um den Motor in Stellung zu bringen können wir bspw. folgendes eingeben:

Dabei wird lediglich die Differenz berechnet. Der obige Aufruf ist also äquivalent zu diesem:

Das Signal wird im folgend berechnet: Möchtest du ein Signal von bspw. 0.5ms (=0.0005s) bei einer Frequenz von 50Hz (ein Puls ist 20ms breit) ausgeben, so müsste der relative Wert ~100 sein (50Hz * 0.0005s * 4096 = 102.4). Die üblichen Pulslängen von Servos sind 0.5ms (0°) bis 2.5ms (180°). Dazwischen wird interpoliert.

Wie auch im Beispiel des einfachen Servos gilt, dass wir das „Ruckeln“ des Servos ausstellen können, sofern wir den Puls auf Null setzen:

 

Wenn du ein vordefiniertes Beispiel testen möchtest, kannst du dies ebenfalls:

wget https://raw.githubusercontent.com/adafruit/Adafruit_Python_PCA9685/master/examples/simpletest.py

sudo python simpletest.py

Dieses Beispiel setzt die definierten Minimum / Maximum Signale, wodurch der Motor hin und Her rotiert.

 

Übrigens: Nicht nur Servos können mit diesem Board gesteuert werden. Auch LEDs oder andere Module, welche PWM nutzen, können damit sehr einfach angesprochen werden.

6 Kommentare

  1. Hallo,
    vielen Dank für diesen Beitrag.
    Zwei Fragen.
    1. Die Frequenz hast Du in der Erklärung bei 50 Hz angenommen, im Beispielcoding ist der Wert dann aber 60 Hz (macht vielleicht nichts am Ergebnis aus, aber wollte das nur verstehen).
    2. Die „Helper function“ wird nicht bei der Abarbeitung des Codes verwendet, oder?

    Eine Anmerkung:
    Wenn ein Servo z.B. das DS3218MG nur lahm ruckelt, dann liegt es daran dass das Netzteil mit z.B. 5V (800mA) zu schwach ist, dann helfen 6 V (1000 mA) wenn der PCA9685 verwendet wird.
    Gruß
    Dirk

    Antworten
    • Hallo Dirk,
      stimmt beides. In meinem Beispiel habe ich 50Hz genommen, die von Adafruit nehmen 60Hz und rufen die helper Funktiong gar nicht auf.
      Viele Grüße,
      Felix

      Antworten
  2. Hallo Felix,

    vielen Dank für das super Tutorial.
    Ich warte noch auf meine Servos und dann werde ich etwas mit dem PCA9685 experimentieren.
    Damit lassen sich sicher auch DC Motoren steuern oder?

    Antworten

Hinterlasse einen Kommentar

Deine Email Adresse wird nicht veröffentlicht.

Blog abonnieren

Abonniere Raspberry Pi Tutorials, um kein Tutorial mehr zu verpassen!