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

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

![A6E0A54A-585C-4E44-B40C-D78F46B93698.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328520/de48e24d-c5f4-85c4-2e16-27e62d8318d5.jpeg)

#方法

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にデバイスをつなぐ](https://jhalfmoon.com/dbc/2019/11/20/%e3%83%90%e3%83%aa%e3%83%90%e3%83%aa%e3%81%aesoc%e3%81%a8som2-jetson-nano%e3%81%aei2c%e3%81%ab%e3%83%87%e3%83%90%e3%82%a4%e3%82%b9%e3%82%92%e3%81%a4%e3%81%aa%e3%81%90/)

このあたりを参考にして実行しましたが、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
```

![1BE6D99B-0671-40BF-9A8A-1FD4C30E4260.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328520/5db907a5-bf22-3c40-40f6-69975c02e272.jpeg)

つまり、私が接続した場所（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)のバス番号を書き直します。

```python:~/.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)
```

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

```bash: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()を呼ぶと異常になるようです。
どうせ使っていないので、ドライバを修正してコメントアウトします。


```python:~/.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)
```
![08EB140D-AC49-4933-B012-D59B2B7D2334.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328520/34a6f537-a58c-4d8c-7385-c1bc2052c870.jpeg)

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