今回は、Jetson AGX XavierのI2Cを使いました。
JetsonシリーズやRaspberry PiシリーズにはGPIOが搭載されています。GPIOを使用すると、PCでありながらマイコンのようにLチカやボタン読み込み、シリアル通信などを行うことができます。
私は以前にモータドライバ用のI2Cモジュールを自作したことがあり、それを自律移動用ロボットの回転軸に使う予定です。
マイコンとPCはシリアルポートを使って通信するのが一般的ですが、I2Cをつかって接続することもできます。
I2Cは中心となるマイコンやコンピュータ(マスタ)がその他の複数台のマイコン(スレーブ)に対して指令を送り、スレーブ側がその値に対して動作を行ったり値を返却したりします。
基本的には予め決められたバイト数のデータを送受信するため、可変長の文字列の送受信は得意ではありません。SCLとSDAの2本で通信することが可能なので、パソコンに搭載されるファンコントローラやEEPROM、RTCなどにも使われることがあります。
I2Cの概要→http://www.picfun.com/c15.html
Raspberry Piピン互換のJetsonは2つI2Cポートがありますが、ポート番号が少し違うため注意してください。おすすめのJetsonピンマップサイトを紹介します。
Jetsonとマイコンを接続します。マイコンには3.3V電源、SCL、SDA、GNDを接続しました。電源を切ってから配線しましょう。

コマンド
基本的にはi2c-toolsというパッケージが提供されているので、それを使います。
インストール方法は$ sudo apt install i2c-toolsでインストールできます。
Jetson AGX Xavierの8番I2Cポートに接続されているモジュールを検索したい場合は、$ sudo i2cdetect -y -r 8と入力してください。
シンプルなプログラム
次に、シンプルなI2Cのプログラムを示します。Python3で記述しました。依存ライブラリはsmbus2です。pip3 install smbus2でインストールできます。
from smbus2 import SMBus, i2c_msg
import time
import math
class i2c_class:
def __init__(self, add_port: int, addr: int):
self.bus = SMBus(add_port)
self.address = addr
def read_bus(self, len):
read = i2c_msg.read(self.address, len)
self.bus.i2c_rdwr(read)
return list(read)
def write_bus(self, input_data):
write = i2c_msg.write(self.address, input_data)
print(input_data)
self.bus.i2c_rdwr(write)
if __name__=='__main__':
i2c = i2c_class(8, 0x10)
data = i2c.read_bus(5)
print(data)
write_bus([0x00, 0x10, 0x80])
I2Cデバイスは複数バイトのデータを送受信する場合がほとんどなので、複数バイトの送受信をシンプルな宣言で実現可能なクラスを作成しました。initでポートとI2Cデバイスのアドレスを指定し、read_bus(self, len)でlenバイト分のデータをリスト形式で受信します(lenは固定なのでコンストラクタで宣言してしまうのもアリですね)。また、write_bus(self, input_data)でリストに格納したデータをスレーブデバイスに送信します。
実際にはこのi2c_classを継承したクラスを作成し動作させました。
少し時間がかかりましたが、JetsonのGPIOからI2Cを引っ張り出してモータを回すことができました。
— Ar-Ray (@Ray255Ar) 2021年4月22日
(まさかの借りたMDがハズレ個体だったのか、片回転しかしません😅) pic.twitter.com/LLsBE15S5l
おわりに
自作モジュールでI2C通信する人はほとんどこの記事のような使い方で通信をするプログラムを書かれると思います。JetsonのGPIOシリーズの次回は、よく使われているI2CデバイスであるLCDディスプレイなどを使ってみようと思います。
また、これまでJetsonに電子部品をつなげたことがなかったので、JetsonでLチカをした!というレベルの内容でも記事を書きたいと思います。
最近記事の質が下がっているような気もしますが、1ヶ月前から始めている2日1本投稿を守りたいと思います。