Raspberry PiとArduino間で、Pythonを使ったI2Cでのデータ列の送受信
研究の一環で、Raspberry PiとArduino間で、I2Cを使ってある程度まとまったデータ列の送受信をすることになった。
ただ、動かすまでが大変だった…
何せ詳しいリファレンスが探しても出てこないのだ。
使えるメソッドを表にしてくれてるサイトはあったのでどんなメソッドを使えばいいのかは分かっていたものの、詳しい説明がないからどうしようもない。
cmdが一体何に使われているのかとか、Arduino側ではどう認識されるのかとか、どっこにも書いてなくて途方に暮れてた。
ちなみに見つけたリファレンスっぽいサイトは以下。
オシロで観測した波形を載せてたり、write_i2c_block_dataのコード例が載ってたりしてちょっと参考になったサイト↓
最終的には、なんとかArduino Forumの中で答えにたどり着いた。
この人のテストプログラムがあってよかった。
動いた時はびっくりした。
上記を参考にして例示用のコードを書いたので、参考にしてみてほしい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # -*- coding: utf-8 -*- import sys import smbus import random SLAVE_ADDRESS = 0x40 try: # I2Cバスにマスタとして接続 bus = smbus.SMBus(1) # 10byteの送信データの作成 send = [] for i in range(10): send.append(random.randint(0, 255)) # データの送信 bus.write_i2c_block_data(SLAVE_ADDRESS, 0, send) # 5byte受信する result = bus.read_i2c_block_data(SLAVE_ADDRESS, 1, 5) print(result) except KeyboardInterrupt: sys.exit(0) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | #include <Wire.h> #define SLAVE_ADDRESS 0x40 static int cmd = 0; static byte buf[50]; static int num = 0; void setup (void) { // I2Cパスにスレーブとして接続 Wire.begin(SLAVE_ADDRESS); // マスタからデータが送られてきたときのハンドラを設定 Wire.onReceive(receive); // マスタからリクエストが来たときのハンドラを設定 Wire.onRequest(send); } void loop(){ } // 送信処理 void send(){ // 何か送信する for(int i = 0; i < num; i++){ Wire.write(buf[i]); } } // 受信処理 // n: 送られてきたデータのbyte数(cmdも数に含まれていることに注意) void receive(int n){ num = n; // cmdを受信 cmd = Wire.read(); // cmd = 0ならデータが送られてきているので受信処理を行う if(cmd = 0){ // 何かする // 全データ受信だけしてみるならこんな感じ for(int i = 0; i < n-1; i++){ buf[i] = Wire.read(); } } } |
にしてもさー、read_block_dataの第3引数に受信するバイト数を指定できるとか、公式っぽいリファレンスには一切載ってないんだけど。
いや、バイト数指定できることはさっきのちょっと参考になったサイトに書いてあったけど、何のために指定するのか書いてないんだけど。
見つけた人はすごいけど、その前に実装した引数くらいきちんと使えるようにリファレンスに載せてくれよ…
しかもさぁ、どんな長さのバイト数でも受信できるみたいに書いといて32バイトまで(受信だけならcmd含め33バイト)しか読めないってどういう事よ〜。ちゃんと書いとけよぉ〜〜。
んあーー!!!
リファレンスの少ないライブラリとかメソッド使うのちょ〜〜〜苦労するんなああぁあぁぁもぉぉ!!!!!
追記(2018/07/12);
>>どんな長さのバイト数でも受信できるみたいに書いといて
あらためて確認してみたら、ここにはちゃんと書いてあったね…
まぁメソッド名微妙に違うし関係ないと思ってたのかな。
I2C block transactions do not limit the number of bytes transferred but the SMBus layer places a limit of 32 bytes.
あと、この投稿をした1ヶ月後くらいに各メソッドを日本語訳してくださった方がいらっしゃるようだ。
英語を読みたくない人は参照すると良いかもしれない。
この方が参考にしたリファレンスもコード例が載ってたりしてマシな感じ。
でも相変わらずread_block_dataの第3引数については書いてないし、各引数の意味も書いてないのでアレではあるが…
この記事へのコメントはこちら