In diesem Beitrag möchte ich nun zeigen, wie man mehrere Servomotoren mit dem Modul PCA9685 am Raspberry Pi steuern kann.
Im Beitrag Raspberry PI Tutorial #7: Servomotor steuern habe ich beschrieben, wie man einen Servomotor am Raspberry PI steuern kann.
An diesem Modul kann man bis zu 16 PWM steuerbare Geräte anschließen (RGB / LED Stripes, Servomotoren usw. ). Der Vorteil ist das man mehrere solcher Module hintereinander Schalten kann (nennt man auch Kaskadieren). Wenn man mehrere Module vom Typ PCA9685 hintereinander schaltet, kann jedes Modul mit einer definierbaren Adresse angesprochen werden.
Das Modul PCA9685 habe ich bereits im Beitrag Weekend Project: 7 Segmentanzeige mit Servomotoren verwendet, jedoch habe ich dort einen Arduino verwendet.
benötigte Bauteile
- einen Raspberry PI,
- Ladekabel,
- Netzwerkkabel
- ggf. HDMI Kabel & Tastatur
- vier Breadboardkabel, weiblich – weiblich, 20 cm,
- externe Spannungsversorgung mit 5V*
* Je nach verwendetem Servomotor muss auf die Stromstärke geachtet werden. Ich verwende ein 5V Netzteil mit 2A Leistung.
Anschluss und Schaltung
Nun möchte ich dir gerne zeigen, wie du das Modul an deinen Raspberry PI anschließen kannst. Wie bereits erwähnt verwende ich in diesem (und weitere) Beitrag das Model „Raspberry PI Modell B+“.
Wenn du ein anderes Model verwendest musst du ggf. auf eine andere Pinbelegung achten.
Anschluss
Das Modul PCA9685 verfügt über 6 Pins, welche wie folgt an den Raspberry PI angeschlossen werden.
PCA9685 | Raspberry PI |
---|---|
GND | GND (Pin6) |
OE | |
SCL | GPIO 3 / SCL |
SDA | GPIO 2 / SDA |
VCC | 3,3V (Pin 1) |
V+ |
Die beiden Pins OE & V+ werden in diesem Aufbau nicht verwendet.
Wenn du mehr als die möglichen 16 Geräte anschließen möchtest, so kannst du ein weiteres Modul, kaskadierend anschließen.
Dazu nutzt du den Pins auf der gegenüberliegenden Seite.
Schaltung
In der nachfolgenden Schaltung möchte ich zeigen, wie man das Modul PCA9685 am Raspberry PI anschließt. Für den Aufbau habe ich eine Power Supply Modul für ein Breadboard und einer 9V Blockbatterie als Stromversorgung genutzt.
Der Vorteil des Modules PCA9685 ist, dass die Servomotoren direkt angeschlossen werden können, da der Stecker quasi passend vorkonfektioniert ist.
Installieren der Bibliotheken und Pakete
Bevor wir die benötigten Bibliotheken installieren können, müssen bzw. sollten wir einmal ein Update durchführen.
sudo apt-get update
Nach diesem Update können wir nun die Pakete für die spätere Verwendung von I2C und der Bibliothek „Adafruit PCA9685“ mit nachfolgendem Befehl installieren.
sudo apt-get install build-essential python-dev python-smbus i2c-tools python-pip --yes
Je nach verwendetem Raspberry Pi kann dieses etwas länger dauern. Bei meinem Raspberry PI Modell B+ dauerte dieses ca. 4 min.
aktivieren von I2C
Nachdem die Pakete installiert wurden, müssen wir (soweit nicht bereits geschehen) die I2C Funktionalität am Raspberry PI aktivieren.
Zunächst wird der Befehl
sudo raspi-config
eingegeben und wie in den folgenden Grafiken gezeigt I2C aktiviert.
In dem „Fenster“ kann mit den Pfeiltasten navigiert werden, ein Menüpunkt wird jeweils mit der Enter Taste bestätigt.
Wenn das Modul PCA9685 bereits am Raspberry Pi angeschlossen ist, dann kann geprüft werden, ob ein I2C Gerät erkannt wird.
Dazu wird der Befehl
i2cdetect -y 1
eingegeben.
In meinem Fall werden werden 2 Geräte erkannt.
installieren der Adafruit Bibliothek PCA9685
Zum installieren der Bibliothek wird einfach der nachfolgende Befehl auf der Konsole ausgeführt:
sudo pip install Adafruit-PCA9685
Alternativ kann natürlich auch die Bibliothek vom Adafruit GitHub Repository geladen werden. Jedoch muss diese dann etwas umständlicher in den späteren Quellcode importiert werden.
Quellcode
Im GitHub Repository zur Adafruit Bibliothek PCA9685 findet man auch ein gutes und wie ich finde ausführliches Beispiel. Und genau dieses Beispiel möchte ich nutzen um 3 Servomotoren zu steuern.
Das Skript kann entweder per Copy & Paste in den Editor kopiert werden oder per
wget https://raw.githubusercontent.com/adafruit/Adafruit_Python_PCA9685/master/examples/simpletest.py
in das aktuelle Verzeichnis heruntergeladen werden.
# Simple demo of of the PCA9685 PWM servo/LED controller library. # This will move channel 0 from min to max position repeatedly. # Author: Tony DiCola # License: Public Domain from __future__ import division import time # Import the PCA9685 module. import Adafruit_PCA9685 # Uncomment to enable debug output. #import logging #logging.basicConfig(level=logging.DEBUG) # Initialise the PCA9685 using the default address (0x40). pwm = Adafruit_PCA9685.PCA9685() # Alternatively specify a different address and/or bus: #pwm = Adafruit_PCA9685.PCA9685(address=0x41, busnum=2) # Configure min and max servo pulse lengths servo_min = 150 # Min pulse length out of 4096 servo_max = 600 # Max pulse length out of 4096 # Helper function to make setting a servo pulse width simpler. def set_servo_pulse(channel, pulse): pulse_length = 1000000 # 1,000,000 us per second pulse_length //= 60 # 60 Hz print('{0}us per period'.format(pulse_length)) pulse_length //= 4096 # 12 bits of resolution print('{0}us per bit'.format(pulse_length)) pulse *= 1000 pulse //= pulse_length pwm.set_pwm(channel, 0, pulse) # Set frequency to 60hz, good for servos. pwm.set_pwm_freq(60) print('Moving servo on channel 0, press Ctrl-C to quit...') while True: # Move servo on channel O between extremes. pwm.set_pwm(0, 0, servo_min) time.sleep(1) pwm.set_pwm(0, 0, servo_max) time.sleep(1)
Zerlegen wir zunächst einmal das Beispiel „Stück für Stück“.
Zunächst müssen wir die für den Code benötigte Bibliotheken importieren.
from __future__ import division import time import Adafruit_PCA9685
Wenn man das PCA9685 Modul per Default d.h. ohne das eine Adresse über einen Lötpunkt „eingerichtet“ wurde betreiben möchte dann wird das PWM Objekt wie folgt initialisiert:
pwm = Adafruit_PCA9685.PCA9685()
Sollte jedoch eine andere Adresse gewünscht sein so muss dem Konstruktor diese Adresse übergeben werden.
pwm = Adafruit_PCA9685.PCA9685(address=0x41, busnum=2)
Im Beispielcode wird die PWM Frequenz auf 60Hz gesetzt, in meinem Fall verwende ich jedoch die „MicroServos SG90“ mit 50Hz laut Datenblatt wenn man jedoch den Wert auf 50Hz anpasst so arbeiten die Servos nicht. Daher belasse ich den Wert auf 60.
pwm.set_pwm_freq(60)
Mit dem Befehl „print“ kann man einen Text auf der Konsole ausgeben. In dem Beispielcode wird darauf hingewiesen dass, das Skript per Strg + C abgebrochen werden kann.
print('Moving servo on channel 0, press Ctrl-C to quit...')
Zum Schluss kommt eine Endlosschleife in welcher wir den Servo / die Servos bewegen.
while True: # Bewegen des Servos am Port 0, von 0 bis 180 Grad pwm.set_pwm(0, 0, servo_min) # eine Pause von 1 Sekunde time.sleep(1) pwm.set_pwm(0, 0, servo_max) time.sleep(1)
Um nun alle 3 Servos gleichzeitig zu betreiben muss man nur den Aufruf der Methode „pwm.set_pwm(…)“ kopieren.
In meinem Fall sieht das dann wiefolgt aus:
while True: pwm.set_pwm(0, 0, servo_min) pwm.set_pwm(7, 0, servo_min) pwm.set_pwm(15, 0, servo_min) time.sleep(1) pwm.set_pwm(0, 0, servo_max) pwm.set_pwm(7, 0, servo_max) pwm.set_pwm(15, 0, servo_max) time.sleep(1)
Wenn man auf der Konsole das laufende Skript mit der Tastenkombination „Strg + C“ abbricht so wird eine zusätzliche Ausgabe getätigt das ein KeyboardInterrupt aufgetreten ist.
Um nun diese zusätzliche Ausgabe zu unterdrücken, können wir das Event mit einem „try except“ Block abfangen:
try: while True: pwm.set_pwm(0, 0, servo_min) pwm.set_pwm(7, 0, servo_min) pwm.set_pwm(15, 0, servo_min) time.sleep(1) pwm.set_pwm(0, 0, servo_max) pwm.set_pwm(7, 0, servo_max) pwm.set_pwm(15, 0, servo_max) time.sleep(1) except KeyboardInterrupt: pass
Wenn man nun das Skript abbricht wird keine Fehlermeldung ausgegeben, denn wir fangen diese ab. (Man könnte nun eine zusätzliche Ausgabe mit dem Befehl „print“ tätigen.)
Die Methode „set_servo_pulse(channel, pulse)“ kann auskommentiert oder entfernt werden denn diese wird in dem Skript nicht verwendet.
Prima Tutorial !
Habe das Beispiel mit einem Raspberry zero wh nachgebaut und zum Laufen gebracht.
Problem war die Installation mittels dem oben aufgeführten Befehl :
sudo apt-get install build-essential python-dev python-smbus i2c-tools python-pip – yes
Ich bekam eine Fehlermeldung.
Bei mir reichte nur der Installationsbefehl: sudo pip install Adafruit-PCA9685
Anmerkung: ich habe die aktuelle Buster-Version mit den angebotenen Zusätzen installiert.
Vielleicht helfen diese Angaben anderen Usern.