Raspberry PiとArduino間で、Pythonを使ったI2Cでのデータ列の送受信

   2018/07/12

研究の一環で、Raspberry PiとArduino間で、I2Cを使ってある程度まとまったデータ列の送受信をすることになった。
ただ、動かすまでが大変だった…

何せ詳しいリファレンスが探しても出てこないのだ。
使えるメソッドを表にしてくれてるサイトはあったのでどんなメソッドを使えばいいのかは分かっていたものの、詳しい説明がないからどうしようもない。
cmdが一体何に使われているのかとか、Arduino側ではどう認識されるのかとか、どっこにも書いてなくて途方に暮れてた。

ちなみに見つけたリファレンスっぽいサイトは以下。

オシロで観測した波形を載せてたり、write_i2c_block_dataのコード例が載ってたりしてちょっと参考になったサイト↓


最終的には、なんとかArduino Forumの中で答えにたどり着いた。
この人のテストプログラムがあってよかった。
動いた時はびっくりした。

上記を参考にして例示用のコードを書いたので、参考にしてみてほしい。

# -*- 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)
#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引数については書いてないし、各引数の意味も書いてないのでアレではあるが…

 

 

タイトルとURLをコピーしました

この記事へのコメントはこちら

メールアドレスは公開されませんのでご安心ください。
また、* が付いている欄は必須項目となりますので、必ずご記入をお願いします。

内容に問題なければ、下記の「コメント送信」ボタンを押してください。

20 + three =

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください