Xavier NXでサーボモーターを動かしてみる


やりたいこと

Xavier NXを手に入れたので、モータを動かしてみます。
JETSON nano互換ということでしたので、参考書はJETSON nano超入門です。

方法

JETSON nano超入門のPart8 電子工作をしてみよう、を参考にします。
PCA9685をI2Cで制御します。
準備は教科書通りに配線して、ドライバをそのままつっこんでやってみます。

I2C通信デバイスを確認しますが、まったく繋がっていません。

$ sudo i2cdetect -r -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --      

配線間違えたかな?と思いましたが、グループを作成してユーザーを追加しないと動かせません。

$ sudo groupadd -f -r gpio
$ sudo usermod -a -G gpio ユーザ名
$ sudo usermod -a -G i2c ユーザ名

バリバリのSoCとSoM(2) Jetson NanoのI2Cにデバイスをつなぐ

このあたりを参考にして実行しましたが、NXのI2Cが動きません。
反応なしです。
NANOとは少し違うようです。

NXのI2C仕様

facebookで助けを求めたら回答していただけました。

I2C - pinが、以下の接続で認識しました。

Pins 3(SDA) and 5(SCL) are on I2C bus 8. For detection:
$ sudo i2cdetect -y -r 8
Pins 27(SDA) and 28(SCL) are on I2C bus 1. For detection:
$ sudo i2cdetect -y -r 1

つまり、私が接続した場所(pin3,pin5)では、

$ sudo i2cdetect -r -y 8
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: 70 -- -- -- -- -- -- --       

できました!
しかし、この場合ドライバ類は微妙な手直しが必要になりそうです。

超入門のサンプルを真似して動かしてみる

バスラインの番号に気をつけながら、PCA9685経由でサーボを動かしてみます。
ドライバのインストールと、pip3もインストールされていなかったので、ついでにインストールします。

sudo apt-get install python3-pip 
pip3 install Adafruit_PCA9685

そして、ドライバファイル(~/.local/lib/python3.6/site-packages/Adafruit_GPIO/I2C.py)のバス番号を書き直します。

~/.local/lib/python3.6/site-packages/Adafruit_GPIO/I2C.py
    #修正前
    if busnum is None:
        busnum = get_default_bus()
    return Device(address, busnum, i2c_interface, **kwargs)

    #修正後(あとでもう少し修正します)
    if busnum is None:
        busnum = get_default_bus()
    return Device(address, 8, i2c_interface, **kwargs)

サンプルプログラムをダウンロードして動かしてみます。

terminal
$ git clone https://github.com/adafruit/Adafruit_Python_PCA9685.git
$ cd Adafruit_Python_PCA9685/examples
$ sudo python3 simpletest.py

これで行けると思ったら、異常が出ました。

$ sudo python3 simpletest.py
Traceback (most recent call last):
  File "simpletest.py", line 17, in <module>
    pwm = Adafruit_PCA9685.PCA9685()
  File "/home/kuma/.local/lib/python3.6/site-packages/Adafruit_PCA9685/PCA9685.py", line 74, in __init__
    self._device = i2c.get_i2c_device(address, **kwargs)
  File "/home/kuma/.local/lib/python3.6/site-packages/Adafruit_GPIO/I2C.py", line 63, in get_i2c_device
    busnum = get_default_bus()
  File "/home/kuma/.local/lib/python3.6/site-packages/Adafruit_GPIO/I2C.py", line 55, in get_default_bus
    raise RuntimeError('Could not determine default I2C bus for platform.')
RuntimeError: Could not determine default I2C bus for platform.

get_default_bus()を呼ぶと異常になるようです。
どうせ使っていないので、ドライバを修正してコメントアウトします。

~/.local/lib/python3.6/site-packages/Adafruit_GPIO/I2C.py
    #修正前
    if busnum is None:
        busnum = get_default_bus()
    return Device(address, busnum, i2c_interface, **kwargs)

    #修正後
    # if busnum is None:
    #     busnum = get_default_bus()
    return Device(address, 8, i2c_interface, **kwargs)

これで、手持ちの適当なサーボモーターが動きました。
I2Cの信号だけではモータが動きませんので、PCA9685のV+にも5Vを繋いで動かしましました。