既に、何度か自分でも書いていますし、他のブログでも丁寧に解説されていますので、この記事は単なる自分の備忘録のつもりです。
Mindstorms NXT には入力ポートが4つしかありません。
ですので、普通に考えると4つのセンサーしか接続できません。
M&Yが RoboCupJunior に参加した頃の 2007年のレスキュー競技でも 4個のセンサーでは十分ではなかったと思います。それでも、重ね技とかを駆使して、みんな何とかしていました。(最近では、ポートスプリッタですね)
しかし、ある時、NXTにセンサーコントローラとして、AVRを接続することができることを知りました。(それ以前に、2007年のアトランタ世界大会で、すでにスペインのレスキューチーム「Complbot」が、それを実現していました。やっぱり、すげ~!)
それが、NicoSensor です。
このキットとの出会いが、その後の M&Y の活動に大きく影響しました。
この NicoSencor 自体は、自作用のセンサーを1個接続できるだけなので、ポート数の拡張には役に立たなかったのですが、このプログラムを解析してちょっと改造すれば、いくつでもセンサーを接続できることが分かりました。
で、その時には、直にAVRのプログラミングをして研究していたのですが・・・おかげで、私とYは AVR のプログラムがちょこっと書けるようになりました。
今は、同様のことが Arduino を使ってできますので、とっても手軽になりました。
はい、前置きが長くなりました。
ここからが本文です。
NXT と Arduino を接続して I2C で通信します。
(M&Yでは、I2Cを「あいすくえあどしー」と発音します。)
接続するのは4本の線です。
NXT(緑:VCC) - (VCC) Arduino
NXT(赤:GND) - (GND) Arduino
NXT(黄:SCL) - (A5) Arduino
NXT(青:SDA) - (A4) Arduino
さらに、A4、A5の2つは 100KΩの抵抗でプルアップします。
配線は、これだけです。
まずは、NXT からデータを Arduino に送るサンプルです。
Arduino の I2C アドレスを 0x62、書き込むアドレスを 0x42 にします。
ここに 0x11 を書き込むと LED を点灯し、0x10 を書き込むと LED を消灯するプログラムです。
NXC側
#define LED_ON 0x10
#define LED_OFF 0x11
#define I2C_PORT IN_1
void sendCom(const byte cmd)
{
byte Wbuf[3]={0x62,0x42,0x00};
byte Rbuf[];
int n=0;
Wbuf[2]=cmd;
I2CBytes(I2C_PORT, Wbuf, n, Rbuf);
}
task main()
{
SetSensorLowspeed(I2C_PORT);
while (TRUE)
{
sendCom(LED_ON);
Wait(200);
sendCom(LED_OFF);
Wait(800);
}
}
Arduino側
#include < Wire.h >
#define I2C_SLAVE_ADDRESS 0x31
#define LED_RED 13
#define RED_ON 0x10
#define RED_OFF 0x11
byte requestRegister, requestCommand;
void receiveEvent(int howMany) {
requestRegister = Wire.read();
if (Wire.available() > 0) {
requestCommand = Wire.read();
if (requestRegister == 0x42)
if (requestCommand == RED_ON)
digitalWrite(LED_RED, HIGH);
else if (requestCommand == RED_OFF)
digitalWrite(LED_RED, LOW);
}
}
void setup() {
pinMode(LED_RED, OUTPUT);
digitalWrite(LED_RED, LOW);
Wire.begin(I2C_SLAVE_ADDRESS);
Wire.onReceive(receiveEvent);
}
void loop() {
}
これを実行すると、NXT側の指示で Arduino の LED が1秒ごとに点滅します。
過去に実験したことをもう一度やっただけなので、すんなりいくはずだったのですが・・・
世の中そんなに甘くありません。
Arduino の A4、A5 には 10kΩ の抵抗が付いていたのですが・・・このままだと、なぜかデータが 1byte しか NXT に渡りません。2byte 目以降が 0xff になりました。
原因は良く分かりませんが、プルアップしていた 10kΩの抵抗を外すと、ちゃんとデータが渡せます。それで、NicoSensor の回路図を確認して、とりあえず 100kΩの抵抗を入れました。
それと、上のサンプルプログラムですが・・・これが正解なのかは知りません。
とりあえず、目的の動作はします。
・・・という程度のものです、悪しからず・・・