arduino を TJ3B のスレーブとして使う(その3)
Arduino の Wire ライブラリを使い、スレーブデバイスを作る時には、次の関数を使う。
- Wire.onReceive(handler) マスタからデータが送られてきたときに呼ばれる関数を登録する。応答はしない。
- Wire.onRequest(handler) マスタからデータのリクエストが来たときに呼ばれる関数を登録する。 応答あり。
まずはデータを受けるだけで応答しない onReceive の対応を考える。
マスター側TJ3Bのプログラムでは、スレーブ側に何かをセットする。
スレーブ側のarduinoのプログラムを作るには、TJ3Bをスレーブ設定した場合のI2Cのアドレスを調べる必要があるが、上のC-Codeを見ると「sub_io_set_gV(1, VAR_A, gV[VAR_A]);」なる関数が使用されているので、まずはこの関数について調べてみる。
サクラエディタの「検索」→「Grep」を使うと、所定のフォルダ配下のファイルに含まれるキーワードが記載された場所を調べることができる。とりあえず、以下で検索し、プログラムのソースとして妥当なファイルをチェックすれば、「sub_io_set_gV」の定義内容を調べることができるので、そこのI2Cアドレス設定を流用して、スレーブ側の arduino をプログラムを準備する。
- 条件 : sub_io_set_gV
- ファイル:*.*
- フォルダ:(ビルドパス)
とりあえず、マスタ側TJ3Bから送られたデータをそのまま arduino のシリアルモニタに表示するだけのプログラムの例はこんな感じに。Wire ライブラリは、onReceiveもonRequestも同じ7ビットアドレスを使うため、最下位のビットは右シフトで落としておく。
//--------------------------------------------------------------------------- //I2C test receive //master:tj3b, slave:arduino //--------------------------------------------------------------------------- #include <Wire.h> //TJ3B設定 #define SUB_ADRS 0x30 #define I2C_BUFSIZE 10 byte i2c_recv_buf[I2C_BUFSIZE]; boolean is_received = false; void setup() { //Slave addressスレーブアドレス変換 int adrs = SUB_ADRS >> 1; Wire.begin(adrs); Wire.onReceive(receiveEvent); Serial.begin(9600); } void loop() { if (is_received) { for (int i = 0; i < I2C_BUFSIZE; i++) { Serial.print(i2c_recv_buf[i]); if (i < I2C_BUFSIZE - 1 ) { Serial.print(","); } else { Serial.println(""); } } is_received = false; } } /** マスターからの書き込み要求(R/W=0)を受けた時の割込み関数 @param int bytesReceived データ長(byte) */ void receiveEvent(int bytesReceived) { for (int i = 0; i < I2C_BUFSIZE; i++) { if (i < bytesReceived) { i2c_recv_buf[i] = Wire.read(); } else { i2c_recv_buf[i] = 0; } } is_received = true; }
arduinoのシリアルモニタを動かした状態で、TJ3Bもシリアルモニタを開き、プログラムをスタートさせる。
問題なければ、TJ3B から送られたデータが arduino のシリアルモニタに表示される。
スレーブ側でデータを受けとり、何らかの応答をする onRequest のテストをする場合は、TJ3B側でも受け取った値を表示してデバッグを進める。
(連載終わるかも)