Aus Raspberry Pi Geek 12/2021

Halloween-Dekoration mit technischem Gruseleffekt (Seite 2)

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].

Abbildung 4: Die Anzeige des Oszilloskops bestätigt einen Impuls von 1,5 Millisekunden.

Abbildung 4: Die Anzeige des Oszilloskops bestätigt einen Impuls von 1,5 Millisekunden.

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

int wiringPiI2CSetup (int devId);

Gibt ein File-Handle zurück, das eine Verbindung zu einem Gerät am I2C-Bus besitzt.

int wiringPiI2CRead (int fd);

Einfaches Lesen des I2C-Busses. Es gibt nur wenige Fälle, die diese Funktion benötigen. Die meisten I2C-Geräte arbeiten über Register.

int wiringPiI2CWrite (int fd, int data);

Einfaches Schreiben.

int wiringPiI2CReadReg8 (int fd, int reg);

Lesen eines 8-Bit-Registers. Die meisten I2C-Geräte arbeiten mit solchen.

int wiringPiI2CWriteReg8 (int fd, int reg, int data);

Schreiben eines 8-Bit-Registers.

int wiringPiI2CReadReg16 (int fd, int reg);

16-Bit-Register lesen.

int wiringPiI2CWriteReg16 (int fd, int reg, int data);

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.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 6 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
RASPBERRY PI GEEK KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Raspberry Pi Geek bei Google Play Readly Logo
Nach oben