次にスレーブ側arduinoからデータを返す Wire.onRequest の対応を考える。
マスター側TJ3Bのプログラムでは、スレーブ側から何か値を取得するようにしておく。
スレーブ側arduinoのプログラムは先日のプログラムを若干直しし、経過時間(ミリ秒)を返すプログラムにしてテストする。
//--------------------------------------------------------------------------- //I2C test request //master:tj3b, slave:arduino //--------------------------------------------------------------------------- #include <Wire.h> //TJ3B設定 #define SUB_ADRS 0x30 #define I2C_BUFSIZE 10 typedef union { long bbbb; struct { byte b1; byte b2; byte b3; byte b4; }; } U_LNG; boolean is_received = false; byte i2c_recv_buf[I2C_BUFSIZE]; //I2C受信バッファ byte i2c_send_buf[I2C_BUFSIZE]; //I2C応答バッファ void setup() { //Slave addressスレーブアドレス変換 int adrs = SUB_ADRS >> 1; Wire.begin(adrs); //マスターからの書き込み要求(R/W=0)を受けた時の割込み関数を登録 Wire.onReceive(receiveEvent); //マスターからの読み出し要求(R/W=1)を受けた時の割込み関数を登録 Wire.onRequest(requestEvent); Serial.begin(9600); } /** マスターからの読み出し要求(R/W=1)を受けた時の割込み関数 */ void requestEvent() { U_LNG w; w.bbbb = millis(); i2c_send_buf[0] = w.b1; i2c_send_buf[1] = w.b2; i2c_send_buf[2] = w.b3; i2c_send_buf[3] = w.b4; Wire.write(i2c_send_buf, 4); Serial.println("request"); } /** マスターからの書き込み要求(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; Serial.println("receive"); } void loop() { U_LNG v; 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; } }
スレーブ側arduinoとマスター側TJ3Bのシリアルモニタを開き、TJ3Bでプログラムをスタートさせる。
問題なければ、次の表示が1秒毎に追記される。