Danach überprüfen Sie mit dem Kommando i2c-detect, ob sich das PCA9685-Modul korrekt am Bus meldet (Listing 2). Sie sollten in der Ausgabe zwei I2C-Adressen sehen: Zum einen die reguläre 0x40, die sich über die Lötpads auf der Platine verändern lässt, und zum anderen die sogenannte Allcall-Adresse 0x70. Befinden sich mehrere PCA9685-Module an einem I2C-Bus, kann man über die Allcall-Adresse alle gleichzeitig programmieren – eine praktische Funktion für das Setup oder um alle verbundenen Module gleichzeitig zu schalten. Theoretisch dürfen Sie bis zu 62 PCA9685-Module an einem I2C-Bus anschließen.
Listing 2
Modul identifizieren
$ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
-- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70 -- -- -- -- -- -- --
Für einen ersten Test steuern wir einen einzelnen Servomotor über den Ausgang OUT0 an. Dazu verwenden wir das Tool I2cset. In Listing 3 initialisieren die ersten vier Befehle den PCA9685 mit einer Basisfrequenz von rund 50 Hz. Exakt 50 Hz erzeugt der eingebaute Taktgenerator des Moduls zwar nicht, aber immerhin eine sehr dichte Näherung. Die folgenden vier Kommandos setzen die Steuerregister für alle Ausgänge auf null, die letzten sechs erzeugen PWM-Signale mit einer Dauer von 1, 1,5 und 2 Millisekunden. Das bringt den Servo in beide Endlagen (1 ms und 2 ms) und in die Mittelposition (1,5 ms). Sie müssen immer zwei Werte (High- und Low-Byte) setzen, um eine bestimmte Impulslänge zu erhalten.
Listing 3
Kommandos zur Servosteuerung
$ i2cset -y 1 0x40 0x00 0x10 $ i2cset -y 1 0x40 0xFE 0x79 $ i2cset -y 1 0x40 0x01 0x14 $ i2cset -y 1 0x40 0x00 0x00 $ i2cset -y 1 0x40 0xFA 0x00 $ i2cset -y 1 0x40 0xFB 0x00 $ i2cset -y 1 0x40 0xFC 0x00 $ i2cset -y 1 0x40 0xFD 0x00 $ i2cset -y 1 0x40 0x06 0xCD # 1 ms $ i2cset -y 1 0x40 0x07 0x00 $ i2cset -y 1 0x40 0x06 0x33 # 1,5 ms $ i2cset -y 1 0x40 0x07 0x01 $ i2cset -y 1 0x40 0x06 0x9a # 2 ms $ i2cset -y 1 0x40 0x07 0x01
Falls Sie ein Oszilloskop besitzen, lesen Sie das Signal damit aus (Abbildung 4). Weitere Informationen zur genauen Bedeutung der Register des PCA9685 finden Sie im Datenblatt [8].
Programm
Um auf die I2C-Schnittstelle zuzugreifen, benötigt unser in C geschriebenes Testprogramm die Wiring-Pi-Bibliothek [9]. Eine Übersicht der Funktionen finden Sie in der Tabelle “Übersicht I2C-Funktionen”.
|
Funktion |
Beschreibung |
|---|---|
|
|
Gibt ein File-Handle zurück, das eine Verbindung zu einem Gerät am I2C-Bus besitzt. |
|
|
Einfaches Lesen des I2C-Busses. Es gibt nur wenige Fälle, die diese Funktion benötigen. Die meisten I2C-Geräte arbeiten über Register. |
|
|
Einfaches Schreiben. |
|
|
Lesen eines 8-Bit-Registers. Die meisten I2C-Geräte arbeiten mit solchen. |
|
|
Schreiben eines 8-Bit-Registers. |
|
|
16-Bit-Register lesen. |
|
|
16-Bit-Register schreiben. |
Beim Einsatz von Servomotoren in Projekten ist immer eine kleine Unschärfe bei der Positionierung zu erwarten. Die zum Erreichen einer bestimmte Position nötigen Signale hängen auch ein Stück weit vom mechanischen Aufbau und den Toleranzen der Servos ab.
Um diese Klippe zu umschiffen definieren wir ein Array für neun mögliche Positionen der Augen, das die konkreten Werte zur Signalerzeugung enthält. Die Tabelle “IDs für die Augen” führt den Index zu jeder einzelnen Augenposition auf (aus der Perspektive von Paul). Die Arrays mit den Werten für die Augen heißen right und left. Sie müssen die Werte darin vermutlich an Ihren eigenen Aufbau anpassen.
|
Index |
Position |
|---|---|
|
0 |
oben rechts |
|
1 |
oben Mitte |
|
2 |
oben links |
|
3 |
Mitte rechts |
|
4 |
Neutralstellung |
|
5 |
Mitte links |
|
6 |
unten rechts |
|
7 |
unten Mitte |
|
8 |
unten links |
Kommen wir nun zum Programm (Listing 4). Nach dem Import aller nötigen Bibliotheken definiert der Code die Arrays für die Augenpositionen sowie einige Konstanten. Danach folgen die Funktionen, mit denen sich Paul steuern lässt.
Die Funktionen eyeLeft und eyeRight übernehmen dabei das Bewegen der Augen. Sie bekommen als Übergabewert den Index aus der ID-Tabelle und positionieren die Augen mithilfe der beiden Arrays left und right. Innerhalb der Funktionen greift das Programm auf die entsprechenden Register des PCA9685 zu und teilt die Integerwerte mit ein wenig binärer Logik in zwei Bytes.
Die Funktionen teeth und neck bekommen je einen Integerwert für die Position, den die Software in die Byte-Register des PCA9685 schreibt. Auch hier gilt es wieder zu beachten, dass sich die Werte bei jedem Aufbau leicht unterscheiden. Dazu ein Tipp: Ermitteln Sie so gut wie möglich die Mittelposition. Danach arbeiten Sie sich vor, bis Sie nach rechts und links an die mechanischen Grenzen der Servos stoßen. Üblicherweise brummen diese beim Erreichen der Endposition recht laut. Wählen Sie für die Endposition einen Wert kurz vor Beginn des Brummens.
Zu guter Letzt gibt es noch die init-Funktion. Sie initialisiert den PCA9685 und setzt alle Steuerregister zunächst auf null. Beim genauen Hinsehen erkennen Sie, dass hier dieselben Werte zum Einsatz kommen, die wir schon in Listing 3 via Kommandozeile in die entsprechenden Register geschrieben haben. Die main-Funktion schließlich initialisiert zuerst den PCA9685. Anschließend ruft sie die schon beschriebenen Funktionen auf, um jede von Pauls Bewegungen zu testen.
Sie kompilieren das C-Programm mit dem Kommando cc paul.c -lwiringPi -opaul. Der C-Compiler erzeugt direkt ausführbare Binaries, das Beispielprogramm starten Sie mit dem Kommando ./paul auf der Konsole. Paul lässt sich mit den vorhandenen Funktionen nun so programmieren, dass er beliebige Bewegungsabläufe abspult. Ihrer Fantasie sind dabei keine Grenzen gesetzt, wie ein Youtube-Video [10] zeigt.






