近藤科学ロボットコントロールボードRCB-4HVのユーザー変数を、外部のArduinoマイコンから書き換える方法を、ひとまず走り書きではあるが投稿。
近藤科学のライブラリを利用するとcomポートに繋いだArduinoマイコンから、
- RCB-4HVのI/Oポートにアクセス
- ロボットのモーション発動
等の機能を簡単に利用できるが、ユーザー変数に簡単にアクセスする関数は現在提供されていない。なので、RCB-4HVコマンドリファレンスにあるところの、MOVコマンドを生成しRCB-4に送信する必要がある
Arduinoスケッチ例
なにげにDFRobotの画像認識モジュールHuskyLensとRCB-4の連携の簡単な例にもなっている。
const long BAUDRATE =115200;
const int TIMEOUT = 100;
Rcb4HardSerialClass rcb4(&Serial,BAUDRATE,TIMEOUT);//RCB4HardSerialClassの定義
int destAddr = 1126; //rcb4ユーザー変数3のRAMアドレス 0x466
byte destData[] = {0,0,0,0}; //rcb4のRAMに送るデータを入れる配列
int destDataSize = 4; //rcb4のRAMに送るデータのバイト数
byte send_rcb[11];
byte receive_rcb[4];
const int16_t objRed = 1; // HUSKYLENSに学習させた色のID
const int16_t objGreen = 2; // HUSKYLENSに学習させた色のID
int blockwidth=0;
int blockheight=0;
int x=160;
int y=120;
int16_t xDev;
String cstmtxt;
const int ledPin = 13; //13番(PB5)には実装済みLEDがある
int buttonState = 0;
byte loopCounter =0 ;
void setup()
{
// put your setup code here, to run once:
pinMode(ledPin, OUTPUT);
Wire.begin(); //I2c
rcb4.configData.word = 0xFFFF; //configdata初期化
rcb4.open();
//RCB4 configdata取得と、Huskylensとの通信ができるまでループ
while ( (!huskylens.begin(Wire)) || (rcb4.open()==false))
{
digitalWrite(ledPin, HIGH);
delay(100);
digitalWrite(ledPin, LOW);
delay(100);
//Serial.println(("Begin failed!"));
}
while ( !huskylens.clearCustomText() ) { }
}
void receiveHuskylens()
{
//huskylensから認識結果受信する関数
if ( !huskylens.request() ) { }
else if( !huskylens.isLearned() ) { }
else if( !huskylens.available() ) { blockwidth=0, blockheight=0, x=0, y=0; }
else
{
HUSKYLENSResult result = huskylens.read();
//digitalWrite(ledPin, HIGH);
if (result.command == COMMAND_RETURN_BLOCK)
{
if(result.ID == objRed)
{
x = result.xCenter;
y = result.yCenter;
blockwidth=result.width;
blockheight=result.height;
//赤色認識したときユーザー変数に送り付けるデータ
destData[2]= 0xFF; //下側8bit
destData[3]= 0x00; //上側8bit
}
if(result.ID == objGreen)
{
x = result.xCenter;
y = result.yCenter;
blockwidth=result.width;
blockheight=result.height;
//緑色認識したときユーザー変数に送り付けるデータ
destData[2]= 0x00; //下側8bit
destData[3]= 0x7F; //上側8bit
}
}
}
cstmtxt = String(x,DEC);
cstmtxt = String("x: " + cstmtxt);
if( !huskylens.customText(cstmtxt,220,20) ) { }
cstmtxt = String(y,DEC);
cstmtxt = String("y: " + cstmtxt);
if( !huskylens.customText(cstmtxt,220,40) ) { }
}
void loop()
{
// put your main code here, to run repeatedly:
digitalWrite(ledPin, LOW);
buttonState = digitalRead(buttonPin);
while( rcb4.configData.word == 0xFFFF); //RCB4 configdataが読めてない場合ループ
receiveHuskylens();
while(blockwidth != 0) //認識したときblock辺長が取得されているのでループ入り
{
digitalWrite(ledPin, HIGH);
//対象物の見かけの座標x,y スクリーン中点座標160,120との差からミキシング量算出
xDev = x - 160;
destData[0]= xDev & 0xFF; //RCB4送信用に下側8bit抽出
destData[1]= xDev >>8; //上側8bit抽出
//rcb4ユーザー変数へミキシング量送信
rcb4.moveComToRamCmd(send_rcb,destAddr,destData,destDataSize);//RCB4コマンドを生成し、第一引数の配列に格納する関数
rcb4.synchronize(send_rcb, send_rcb[0], receive_rcb, 4); //第一引数にRCB4コマンドを格納した配列を指定し、RCB4と送受信を行う。
delay(105); //ウェイト関数[msec]適当な時間待機
receiveHuskylens();
}
destData[0]=0,destData[1]=0,destData[2]=0,destData[3]=0; ; //rcb4ユーザー変数へ0送信
rcb4.moveComToRamCmd(send_rcb,destAddr,destData,destDataSize);
rcb4.synchronize(send_rcb, send_rcb[0], receive_rcb, 4);
}
- destAddr
アクセスしたいユーザー変数(ここではユーザー変数3)のRAMアドレス
値はRCB-4プログラミングマニュアルを参照 - destData[], destDataSize
RAMに送るデータを入れる配列とそのサイズ
RCB-4プログラミングマニュアル記載の通り、ユーザー変数の大きさは2byte。
なので、この例のように4byteのデータを送り付けると隣のアドレス、つまりアドレス0x468~0x469のユーザー変数4も一気に書き換えられる。 - send_rcb[11], receive_rcb[4]
それぞれ、生成されたMOVコマンドが格納される配列と、RCB-4からの返信が格納される配列。
なぜ要素数がこの値なのかについてはRCB-4HVコマンドリファレンスのMOVコマンドの項を参照。
これらを引数としてmoveComToRamCmd()を実行すると、RCB-4のMOVコマンドが生成されsend_rcbに格納される。
コマンドが格納された配列、返信を受ける配列、それらの要素数を引数としてsynchronize()を実行するとRCB-4との送受信が実行される。
RCB4Library for Arduinoのドキュメントも参照のこと。
まだアプデ予定