Adafruit Motor HAT mit dem Banana Pi
Der Adafruit Motor HAT ist ein gutes Produkt, das ich sehr schätze. Im folgenden erkläre ich, wie man ihn unter Banana Pi verwendet, weil ich ein Bananen-Fan bin.
- Installiere Armbian auf die SD-Karte von
https://www.armbian.com/banana-pi-pro/
- Ich habe Armbian Buster verwendet:
Armbian_21.08.3_Bananapipro_buster_current_5.10.60.img.xz
- dieses Image bootet auch vom Banana Pi. Bei Fehlern ist immer zuerst die SD-Karte zu verdächtigen, auch mehrere hintereinander können nicht funktionieren!
Armbian_22.02.1_Bananapipro_bullseye_current_5.15.25.img.xz
Das .xz-Image kann direkt mit dem Programm usbimager auf die SD-Karte geflasht werden.
https://gitlab.com/bztsrc/usbimager
- Es empfiehlt sich immer, das System nach Installation auf einen USB-Stick zu verschieben, und die SD-Karte nur noch zum Booten zu verwenden. Dies steigert die Lebensdauer erheblich!
- Den Adafruit Motor Hat gilt es, zusammenbauen und am BananaPi montieren wie in der Orignal-Anleitung für den Raspberry beschrieben. Der GPIO-Steckverbinder ist zum Banana Pi Pro direkt kompatibel. Beim normalen Banana Pi kann man sich mit einem Adapter behelfen, dazu Stromlaufplan, Pinout und Layout betrachten.
Weitere Informationen auf der Original-Seite
https://learn.adafruit.com/adafruit-dc-and-stepper-motor-hat-for-raspberry-pi/assembly?view=all
- Zusammengebauter Hat am Banana Pi
- Zum Ansteuern wird die Bibliothek Wiring Pi verwendet, in der Programmiersprache C.
http://wiringpi.com/
-
Und zwar in einer Version, die für den Bananapi abgeändert worden ist. http://wiki.lemaker.org/BananaPro/Pi:GPIO_library
-
zuerst das Repository clonen For Banana Pro:
git clone https://github.com/LeMaker/WiringBP.git -b bananapro
For Banana Pi:
git clone https://github.com/LeMaker/WiringBP.git -b bananapi
- dann Bauen und installieren
# git clone https://github.com/LeMaker/WiringBP.git -b bananapro
# cd WiringBP
# chmod +x ./build
# ./build
wiringPi Build script
=====================
WiringPi Library
[...]
All Done.
- erster Test
# gpio readall
root@bananapipro:~/WiringBP# gpio readall
+-----+-----+---------+------+---+Banana Pro+---+------+---------+-----+-----+
| BCM | wPi | Name | Mode | V | Physical | V | Mode | Name | wPi | BCM |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| | | 3.3v | | | 1 || 2 | | | 5v | | |
| 2 | 8 | SDA.1 | ALT5 | 0 | 3 || 4 | | | 5V | | |
| 3 | 9 | SCL.1 | ALT5 | 0 | 5 || 6 | | | 0v | | |
| 4 | 7 | GPIO. 7 | IN | 0 | 7 || 8 | 0 | ALT0 | TxD | 15 | 14 |
[...]
-
Test mit blink.c von wiringpi dazu eine LED mit einem 330 Ohm Widerstand an den GPIO-Header zwischen GPIO0 und GND anbringen Vorlage: http://wiringpi.com/examples/blink/
- vi blink.c
#include <wiringPi.h> int main (void) { wiringPiSetup () ; pinMode (0, OUTPUT) ; for (;;) { digitalWrite (0, HIGH) ; delay (500) ; digitalWrite (0, LOW) ; delay (500) ; } return 0 ; }
- kompilieren, testen
# gcc -Wall -o blink -I/usr/local/include -L/usr/local/lib -lwiringPi -lwiringPiDev blink.c # ./blink
-
Unterschiede original Wiringpi <-> WiringBP die Beispile / API-Beschreibungen von wiringpi.com funktionieren im Grunde alle das Modul I2C, würde hier sunxi-i2c, kann nicht geladen werden. Es ist bereits im Kernel integriert. Kommandos wie gpio load i2c sind nicht nötig und geben eine Fehlermeldung aus.
- Bei I2C-Detect gibt es weitere Unterschiede. Beim Bananapi hängt wohl der GPIO-I2C am Bus 1, beim Bananapi Pro wohl am Bus 2. Das ist kein Problem, das gilt es nur beim suchen des HATs via i2cdetect zu beachten. Ausprobieren:
I2c-Tools installieren
apt-get install i2c-tools i2cdetect -y 0 i2cdetect -y 1 i2cdetect -y 2
Hier ist der HAT am Bus 2 an Adresse 60 erschienen. Gegenchecken, in dem man den HAT abzieht, und den i2cdetect nochmals aufruft.
Hinweis: die Adresse 0x70 ist die “All Call”-Adresse für alle Controllerchips an allen HATs, wenn man mehrere übereinander steckt. Wenn man dies tut, muss man bei der neueren Version mit zusätzlichem 24C32-EEPROM für eigene Verwendung dies wohl bei allen bis auf einem runterlöten, denn dieses EEPROM kann nicht adressiert werden. Dies betrifft aber nur, wenn man das nutzen will, es ist am anderen I2C-Bus angeschlossen, und beeinflusst nicht den PWM-Controller
i2cdetect -y 2
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: 60 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: 70 -- -- -- -- -- -- --
- Um den PCA9685 PWM-Controller anzusprechen, ist eine Bibliothek nötig, die unter WiringBP als Dev-Linstalliert wird https://github.com/Reinbert/pca9685
# git clone https://github.com/Reinbert/pca9685
# cd pca9685/src/
# make install
[Compile] pca9685.c
[Link (Dynamic)]
[Install Headers]
[Install Dynamic Lib]
- Einfaches Test-Programm, dass so PWM auf Kanal 0 erzeugt
vi simplepwm.c
#include <pca9685.h>
#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#define PIN_BASE 300
#define MAX_PWM 4096
#define HERTZ 100
#define CUR_SPEED 2048
/* PWM Pin Number on Adafruit Motor Hat */
#define PWM_PIN 0
int main(void)
{
int on, i;
if (wiringPiSetup() == -1 ) {
printf("setup wiringPi failed!\n");
printf("please check your setup\n");
return -1;
}
printf("Setting up PCA9685\n");
/* setup with pinbase 300 and i2c location 0x60
* find this with i2cdetect, try all busses 0, 1, 2
* figured out by Chrissie Brown
* # ./i2cdetect -y 2
* 0 1 2 3 4 5 6 7 8 9 a b c d e f
* 00: -- -- -- -- -- -- -- -- -- -- -- -- --
* 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* 60: 60 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
* 70: 70 -- -- -- -- -- -- --
*/
int fd = pca9685Setup(PIN_BASE, 0x60, HERTZ);
if (fd < 0) {
printf("Error in pca9685Setup: %i\n", fd);
}
printf("Setting up simple PWM\n");
pca9685PWMWrite(fd, PWM_PIN, 0, CUR_SPEED);
/*
* PWMread gives -1 if you chip cannot be read, ex
* if here was wrong address at setup
*/
pca9685PWMRead(fd, PWM_PIN, &on, 0);
printf("Reading Back PWM: %i\n", on);
/*
* Loop for smooth changing pwm
* on PMW ration > 50 % user rarely will see
* difference an LED brightness
*/
for (;;) {
for (i=0; i< 1500; i+=10) {
pca9685PWMWrite(fd, PWM_PIN, 0, i);
delay(50);
}
for (i=1500; i>=0; i-=10) {
pca9685PWMWrite(fd, PWM_PIN, 0, i);
delay(50);
}
}
}
vi Makefile
#DEBUG = -g -O0
DEBUG = -O3
CC = gcc
INCLUDE = -I/usr/local/include
CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe
LDFLAGS = -L/usr/local/lib
LDLIBS = -lwiringPi -lwiringPiDev -lpthread -lm -lwiringPiPca9685
SRC = simplepwm.c
OBJ = $(SRC:.c=.o)
BINS= $(SRC:.c=)
all: $(BINS)
simplepwm: simplepwm.o
@echo [link]
@$(CC) -o $@ simplepwm.o $(LDFLAGS) $(LDLIBS)
- kompilieren, testen
root@bananapipro:~/motorhat# make gcc -O3 -Wall -I/usr/local/include -Winline -pipe -c -o simplepwm.o simplepwm.c root@bananapipro:~/motorhat# ./simplepwm
- Banana Pi Con 3 Pinout
- Banana Pi Pro Con 6 Pinout
- Adafruit Head Schematic and Layout
- anderes Beispiele zur Benutzung zur Motorsteuerung
- Coole Hardare-Teile https://osoyoo.com/2020/11/06/osoyoo-pie-car-v2-0-for-raspberry-pi-lesson-1-basic-framework-and-programming-gpio-pca9685-c-version/