We recently added Servo Cape Device Tree Overlay for BeagleBone AI-64 and this post will be more like a detailed overview of how to use servo cape with BeagleBone AI-64.
Make sure your system is up to date,
debian@BeagleBone:~$ sudo apt update
debian@BeagleBone:~$ sudo apt upgrade
You can follow the link below for more information on updating BeagleBone AI-64 software
https://docs.beagleboard.io/latest/boards/beaglebone/ai-64/update.html
It’s very likely that by the time you read this post the overlay is already available on you board but, in case it’s now you can get the new device tree overlay from v5.10.x-ti-unified branch of BeagleBoard-DeviceTrees repository and install it on your board,
debian@BeagleBone:~$ cd
debian@BeagleBone:~$ git clone https://git.beagleboard.org/beagleboard/BeagleBoard-DeviceTrees.git
debian@BeagleBone:~$ cd BeagleBoard-DeviceTrees
debian@BeagleBone:~/BeagleBoard-DeviceTrees$ git branch
* v5.10.x-ti-unified
debian@BeagleBone:~/BeagleBoard-DeviceTrees$ make
debian@BeagleBone:~/BeagleBoard-DeviceTrees$ sudo make install_arm64
After confirming the overlay is in place, update the extlinux.conf
to load it,
debian@BeagleBone:~$ ls /boot/firmware/overlays/ | grep SERVO
BBORG_SERVO-00A2.dtbo
debian@BeagleBone:~$ sudo nano /boot/firmware/extlinux/extlinux.conf
After this the nano text editor will open the extlinux.conf
file and now you have to add the fdtoverlays /overlays/BBORG_SERVO-00A2.dtbo
line as shown below,
label Linux microSD
kernel /Image
append console=ttyS2,115200n8 earlycon=ns16550a,mmio32,0x02800000 root=/dev/mmcblk1p2 ro rootfstype=ext4 rootwait net.ifnames=0 quiet
fdtdir /
fdtoverlays /overlays/BBORG_SERVO-00A2.dtbo
initrd /initrd.img
Reboot the system and make sure the overlay is loaded correctly,
debian@BeagleBone:~$ sudo reboot
debian@BeagleBone:~$ sudo beagle-version | grep UBOOT
UBOOT: Booted Device-Tree:[k3-j721e-beagleboneai64.dts]
UBOOT: Loaded Overlay:[BBORG_SERVO-00A2]
debian@BeagleBone:~$ ls /proc/device-tree/chosen/overlays/
BBORG_SERVO-00A2 name
The servo cape uses PCA9685 PWM chip which is connected to i2c2
and on BeagleBone Ai-64 we have total 7
i2c buses. The bus number for i2c2
is 5
.
debian@BeagleBone:~$ dmesg | grep i2c
[ 0.912845] i2c /dev entries driver
[ 1.009396] omap_i2c 40b00000.i2c: bus 0 rev0.12 at 100 kHz
[ 1.009837] omap_i2c 40b10000.i2c: bus 1 rev0.12 at 100 kHz
[ 1.031383] omap_i2c 42120000.i2c: bus 2 rev0.12 at 400 kHz
[ 1.031967] omap_i2c 2000000.i2c: bus 3 rev0.12 at 400 kHz
[ 1.033025] omap_i2c 2010000.i2c: bus 4 rev0.12 at 400 kHz
[ 1.057095] omap_i2c 2020000.i2c: bus 5 rev0.12 at 100 kHz
[ 1.057679] omap_i2c 2030000.i2c: bus 6 rev0.12 at 400 kHz
[ 1.058172] omap_i2c 2050000.i2c: bus 7 rev0.12 at 400 kHz
Fun fact: The i2c2
bus number (5) is different from i2c number (2) because mcu_i2c
and wkup_i2c
are initialized before main_i2c
. The table below should explain it better,
Bus0 - Bus1 = mcu_i2c
Bus2 = wkup_i2c
Bus3 - Bus7 = main_i2c
With all the information above you know that the bus number is 5
for our device. Now let’s see if we have something on that bus at 0x70
which is the address of PCA9685.
debian@BeagleBone:~$ sudo i2cdetect -y -r 5
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- 54 -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: UU -- -- -- -- -- -- --
We indeed have a device at 0x70
and it seems it’s being used by the driver. Let’s check that,
debian@BeagleBone:~$ ls /sys/bus/i2c/drivers/pca9685-pwm
5-0070 bind uevent unbind
Now you are all set to control servos with your servo cape but, before going further you may want go through this piece of code from beagle-tester repository to get an idea of what we are doing to control the servos.
By default we have two PWMs exported already i.e pwm0
& pwm1
,
debian@BeagleBone:~$ ls /sys/bus/i2c/drivers/pca9685-pwm/5-0070/pwm/pwmchip0
device export npwm power pwm0 pwm1 subsystem uevent unexport
If you want to export 3rd PWM or any other PWM out of 16 available you can use the command below,
debian@BeagleBone:~$ echo 2 > /sys/bus/i2c/drivers/pca9685-pwm/5-0070/pwm/pwmchip*/export
debian@BeagleBone:~$ ls /sys/bus/i2c/drivers/pca9685-pwm/5-0070/pwm/pwmchip0
device export npwm power pwm0 pwm1 pwm2 subsystem uevent unexport
Now connect your servo to S1
header pin location on cape and supply 5V via terminal block for the servo. Follow the PWM configuration bits and you should see your servo moving.
Set pwm0
period to 100Hz (10ms)
debian@BeagleBone:~$ echo 10000000 > /sys/bus/i2c/drivers/pca9685-pwm/5-0070/pwm/pwmchip0/pwm0/period
Set pwm0
duty cycles to 1ms
debian@BeagleBone:~$ echo 1000000 > /sys/bus/i2c/drivers/pca9685-pwm/5-0070/pwm/pwmchip0/pwm0/duty_cycle
Enable pwm0
PWM output
debian@BeagleBone:~$ echo 1 > /sys/bus/i2c/drivers/pca9685-pwm/5-0070/pwm/pwmchip0/pwm0/enable
Set pwm0
duty cycles to 2ms
debian@BeagleBone:~$ echo 2000000 > /sys/bus/i2c/drivers/pca9685-pwm/5-0070/pwm/pwmchip0/pwm0/duty_cycle
Set pwm0
duty cycles to 1ms
debian@BeagleBone:~$ echo 1000000 > /sys/bus/i2c/drivers/pca9685-pwm/5-0070/pwm/pwmchip0/pwm0/duty_cycle
Disable pwm0
PWM output
debian@BeagleBone:~$ echo 0 > /sys/bus/i2c/drivers/pca9685-pwm/5-0070/pwm/pwmchip0/pwm0/enable
Congratilation if you got your servo moving. Let me know if you found any issue with the instruction above.