それでは、今度は Arduino から NXT にデータを送るサンプルです。
I2Cアドレスは 0x62 で、0x20 から 2バイトを読む、というようなプログラムです。
NXT側
#define I2C_PORT IN_1
int getData()
{
byte Wbuf[]={ 0x62,0x20 };
byte Rbuf[2];
int i=2;
int data;
I2CBytes(I2C_PORT, Wbuf, i , Rbuf);
data = Rbuf[0]+(Rbuf[1]<<8);
return (data);
}
task main()
{
SetSensorLowspeed(I2C_PORT);
ClearScreen();
NumOut(40,LCD_LINE6,getData());
Wait( 2000 );
}
Arduino側
#include < Wire.h >
#define I2C_SLAVE_ADDRESS 0x31
byte requestRegister, requestCommand;
void requestEvent()
{
byte d[2];
int j=-256;
if (requestRegister == 0x20)
{
d[0]=j & 0xff;
d[1]=j >> 8;
Wire.write(d,2);
}
}
void receiveEvent(int howMany)
{
requestRegister = Wire.read();
}
void setup()
{
Wire.begin(I2C_SLAVE_ADDRESS);
Wire.onReceive(receiveEvent);
Wire.onRequest(requestEvent);
}
void loop() { }
これで、NXTとArduinoの双方の通信ができるようになりました。
上の例では、単純に-256という数値をArduinoがNXTに返します。
この部分を、Arduinoに接続したセンサーの値を返すようにすれば、沢山のセンサーを接続することができます。
ところで・・・
上の例では、NXT側は Arduino側から 2byte のデータを受け取ります。
NXT側ではあらかじめ
I2CBytes関数の第3パラメータに2を指定して2byteをうけとります。
勿論 Arduino側でも、2byteを送出します。
だから問題は無いのですが・・・
例えば、I2CBytes関数の第3パラメータで何byteを受け取るかは、Arduino側には渡るのでしょうか? 普通のI2Cセンサーの場合は、読み出すレジスタ番号と何byte読み出すかを指定すれば、連続で読みだすことができます。 これと同じことがArduinoではできるのでしょうか? それともできないのでしょうか?
例えば、NXT側は2byteを受け取る、Arduino側は4byteを送出する・・・このようにして通信してみても、特に問題は無いようです。
じゃあ、今度は、NXT側は4byteを受け取る、Arduino側は2byteを送出します。
そうすると、特にエラーや処理待ちにはならずに、2byteが正しく送られて、残りの2byteは0xFFが返されます。
そうすると、Arduino側からは多めにデータを送出しておけば良いってことなのかなぁ。