PCA9685を操作できるROSパッケージがあったので、Jetson Nanoからを使ってみた

スポンサーリンク

使用したROSパッケージは pwm_pca9685。デバイスファイルを経由してI2Cの制御を行うので、ラズパイ等でも使用できるはず。

わざわざROSノードにしなくてもいいような気もするけど、コマンドラインから制御できたり、複数ノードからアクセスできるので結構いい感じ。

動作確認環境

JetSon Nanoを使って、ソフトはJetBotのSDカードイメージにROS Melodicをインストールした状態。

項目 内容
CPUボード Jetson Nano A02
PCA9685 VKLSVAN PCA9685 16チャンネル 12ビット PWM ドライバー
OS Ubuntu 18.04
JetPack 4.4.1
JetBot 0.4.2
ROS Melodic

ノードの挙動

デフォルトのアクセス先デバイスファイルは/dev/i2c-1。
デフォルトのI2Cアドレスは0x40。

各チャンネルはデフォルトでは5秒以内に異なる値をセットしないとタイムアウトする。
異なる値という点が厳しい。
timeout パラメータの値を書き換えれば、タイムアウト時間を変更できる。値が0の場合はタイムアウトしない。
タイムアウトした場合は timeout_value パラメータで設定されている内容が書き込まれる。

/command トピックに値を送ることで、各チャンネルのPWMを操作できる.
PWMを操作する場合は0〜65535の値をセットする。
duty比0%の場合は0。
duty比100%の場合は65535。
16bitなので注意。実際にPCA9685に送られる値は12bitに丸めた値。 12bitに丸めた結果が0xfffや0以外なら、なぜか1が足される。
-1をセットした場合は、そのチャンネルは操作しない。

セットアップ

$ mkdir -p ~/catkin_ws/src
$ cd ~/catkin_ws/src
$ git clone https://github.com/dheera/ros-pwm-pca9685
$ cd ~/catkin_ws
$ catkin_make
$ source devel/setup.bash

ノード起動

$ rosparam set /pca9685_node/timeout "[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]"
$ rosrun pwm_pca9685 pca9685_node

タイムアウトしないほうが好みなので、タイムアウトは無効化

動作確認

ノード起動とは別ウィンドウで実行

$ i2cdump -y 1 0x40
No size specified (using byte-data access)
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 21 04 e2 e4 e8 e0 00 00 00 00 00 00 00 00 00 00    !?????..........
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
40: 00 00 00 00 00 00 XX XX XX XX XX XX XX XX XX XX    ......XXXXXXXXXX
省略

ノード起動時のduty比は0%なので、この内容でOK。

コマンドラインから全チャンネルのduty比を約3%に変更

$ rostopic pub /command std_msgs/Int32MultiArray -1 '{data:[1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888, 1888]}'
publishing and latching message for 3.0 seconds

もう一度確認

$ i2cdump -y 1 0x40
No size specified (using byte-data access)
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 21 04 e2 e4 e8 e0 00 00 77 00 00 00 77 00 00 00    !?????..w...w...
10: 77 00 00 00 77 00 00 00 77 00 00 00 77 00 00 00    w...w...w...w...
20: 77 00 00 00 77 00 00 00 77 00 00 00 77 00 00 00    w...w...w...w...
30: 77 00 00 00 77 00 00 00 77 00 00 00 77 00 00 00    w...w...w...w...
40: 77 00 00 00 77 00 XX XX XX XX XX XX XX XX XX XX    w...w.XXXXXXXXXX
省略

1888 >> 4 + 1 = 0x77 なので、想定通りの結果。

補足

I2Cの接続状況を確認

I2Cの接続状況を確認。コマンドを実行してスムーズに表示されない場合は、配線ミス。

$ 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: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: 70 -- -- -- -- -- -- --    

launchファイルでノード起動する場合のサンプル

<launch>
  <node name="pca9685_node" pkg="pwm_pca9685" type="pca9685_node" output="screen">
    <rosparam param="timeout">[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]</rosparam>
  </node>
</launch>

リンク

Github dheera / ros-pwm-pca9685