PCA9685

Raspberry Pi 4本体にはPWMに対応したGPIOポートが4つしかないので、 このままだと最大でも4つのモータしか同時に動かせない。 そこで、I2C接続で16チャンネルのPWMサーボを制御できる、 マルチチャンネルPWMサーボドライバーボード(PCA9685)を導入してみる。

動作テストに用いるサーボモータは、 Amazon.jpで買えるだいぶお安い中華サーボモータを試しに買ってみた。

1
2
% sudo apt install i2c-tools
% pip3 install adafruit-pca9685

/boot/firmware/config.txt

ブートローダの設定(config.txt)に項目が存在しない場合、下記を追記する。 (ubuntu 21.10 arm64ではデフォルトで有効)

1
dtparam=i2c_arm=on

Raspberry Pi OSの場合は、これに加えi2c-devカーネルモジュールを 読み込むよう設定せよとの情報があったものの、ubuntu 21.10の標準カーネルの場合は そもそもカーネルモジュールファイルが存在しない (CONFIG_I2C_CHARDEV=yでカーネルに組み込まれている)ようだったので無視する。

うまく設定できていれば、/dev/i2c-1が存在するはず。

1
2
% ls -l /dev/i2c-1
crw-rw---- 1 root i2c 89, 1 Dec 17 10:55 /dev/i2c-1

i2cグループに所属していないとアクセスが拒否され操作できないので、あらかじめ確認しておく。 (もし参加していない場合はsudo usermod -A -G i2c ユーザ名などで参加できる)

1
2
% id
uid=10000(gloria) gid=10000(trainers) groups=10000(trainers),20(dialout),44(video),124(i2c)

接続

ごくふつうのi2c接続と基本は同じだが、サーボの駆動に外部電源を用いる必要がある。 (Raspbery Piの5Vに繋いでも一応動くようだが、Raspberry Piが壊れる可能性があるためやらない方がよい) 今回はそこらへんに転がっていたUSB-ACアダプタから給電することにした。

PCA9685側 Raspberry Pi側 外部電源側
GND GND GND
OE    
SCL SCL  
SDA SDA  
VCC 5V power  
V+   5V power

(画像を作る時間がなかった) PCA9685写真

V+は電源供給用ポートが別途用意されていた(緑色のポート)のだが、そちらに給電してもなぜか全く反応しなかったので、 左側のポートに接続した。

制御用プログラムのソース

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/python3

import Adafruit_PCA9685

def convert_deg(self, deg, freq=50):
  step = 4096
  max_pulse = 2.5
  min_pulse = 0.5
  center_pulse = (max_pulse - min_pulse) / 2 + min_pulse
  one_pulse = round((max_pulse - min_pulse) / 180, 2)
  deg_pulse = center_pulse + deg * one_pulse
  deg_num = int(deg_pulse / (1.0 / freq * 1000 / step))
  return deg_num

servo_port = 0
pwm = Adafruit_PCA9685.PCA9685()
pwm.set_pwm_freq(50)
pwm.set_pwm(servo_port, 0, convert_deg(45))