#Arduino用のI2CデバイスドライバをRaspberry pi用としてPythonに翻訳する
ロボットを作ろうと思って使えそうな部品がないかと押し入れを探したところ、昔Raspberry pi用に買ったもののArduino用のライブラリしか用意されてなくてお蔵入りになっていたモータードライバ(GroveのI2C Motor Driver V1.3)を発見。補講日で暇だったのもありRaspberry pi用にpythonで翻訳することにした。
##I2C通信とはなんぞや
今回のモータードライバはI2Cという通信方式でマイコンと通信をするのでまずはその理解から始めることにした。
うまくまとめられないので詳しいことはこちらのサイトさん([I2C通信の使い方][1])に任せるとして、
ざっくりいうとこんな感じで通信するらしい。
1.通信の初期化後マスタ側から今から通信するスレイブのアドレスを送信
2.スレイブから応答があった後データを送信
3.通信の終了
##Arduinoの方のプログラムの理解
なんとなくI2C通信の方式が分かったのでArduino用のサンプルプログラムでどう書かれてるかを見た。(通信部分だけの抜粋)
Wire.begin();
delayMicrosecond(10000);
Wire.beginTransmission(i2c_add);
Wire.write(0x82);
Wire.write(0x0a);
Wire.write(0x01);
Wire.endTransmission();
ざっくり解説すると、1,2行目で通信の初期化をして、4行目でスレイブのアドレスを送信。5~7行目でデータの送信。9行目で通信の終了といった感じだった。
##Raspberry pi用に書き直す
I2C通信に関して一から作るのはめんどくさいので、Raspberry pi用の通信ライブラリsmbusを使うことにした。これを使うと、
import smbus
i2c = smbus.SMBus(1)
i2c.write_i2c_block_data(i2c_add,0x82,[0x0a,0x01])
こんな感じに3行で収まってしまった。
1行目はライブラリのインポート、二行目は通信用のインスタンス作成、Raspberry piではI2Cのバスは1を使う(よくわかってない)のでここはSMBus(1)らしい、三行目が通信の命令文。
ここで引数の0x82,[0x0a,0x01]で前一つ、後ろ二つで分かれている理由は、
Arduino側ではすべてWire.writeで書かれてる0x82,0x0a,0x01の三つに関して上では"データ"とひとくくりにしてしまったが、0x82がスレイブ内にあるレジスタのアドレス、0x0a,0x01がそのレジスタに書き込むデータと意味合いが少し違うものだからだった。
##まとめ
smbusを使えば大体上の三行で通信については書き換えできて、特に重要なのは
i2c.write_i2c_block_data(スレイブのアドレス,レジスタのアドレス,[書き込むデータ])
この一文。今回は書き込むデータが1byte以上なのでこの命令を使ったが、1byteなら
i2c.write_byte_data(スレイブのアドレス,レジスタのアドレス,書き込むデータ)
こちらを使用、どちらの命令文も二つのアドレスおよびデータはint型で指定でOK。
[1]:http://www.picfun.com/c15.html#:~:text=I2C%EF%BC%88Inter%2DIntegrated%20Circuit%EF%BC%89,%E3%82%92%E5%AE%9F%E7%8F%BE%20%E3%81%99%E3%82%8B%E6%96%B9%E5%BC%8F%E3%81%A7%E3%81%99%E3%80%82