概要
VS-RC003HVとArduino(Arduino互換ボード)でI2C通信をする方法です。
UARTで通信する例は多いですがI2Cの例はあまり見当たらなかったので書こうと思います。
当時を思い出しながら書いている部分もありますので、一部不正確な部分もあるかと思います。ソースコードや設定をご使用なさる際は自己責任でお願いいたします。
前提
VS-RC003HVには拡張端子としてIXBUSポートが搭載されています。VS-RC003HV 取扱説明書には以下の記載があります。
CN7 IXBUS拡張
外部に IXBUS の拡張機器を接続するための端子です。IXBUS はフィリップス社の提唱するI2CバスとUART、電源(バッテリ電圧、5V、3.3V)、リセット信号等から成り、特にI2Cバスにより豊富な拡張性を確保しています。基板右下、ロータリースイッチ側が 1番ピンです。
このポートにはI2C端子があり、VS-RC003HVの純正拡張基盤「VS-IXxxx」シリーズはVS-RC003HVとI2Cで通信をしています。
仕組み
ArduinoをVS-RC003HVのIXBUS拡張基盤として認識させます。
Arduinoは自身を任意アドレスのI2Cスレーブとして設定できるので、IXBUS拡張基盤のI2Cアドレスとして起動してあげることで、VS-RC003HVは純正基盤だと認識して通信してくれます。
単純な方法ですのでI2Cポートがついているマイコンならどれでも可能だと思います。
できること
- RobovieMakerのポーズスライダ値を使用した条件分岐
- Arduinoに接続したセンサ値のVS-RC003HVでの利用(未検証)
などが可能です。
私がプログラムを担当した「METAL GEAR REX 参号機」では、この方法でVS-RC003HVでモーション再生と音声出力、ArduinoでLED発光を同期して行いました。
REX動かしました pic.twitter.com/jbZTH4KYKQ
— ツンの作業場@11/25~28ロボット出展します (@tn340) October 10, 2021
本編
ここでは「VS-RC003HV用 LED拡張ボード VS-IX004」として認識させる設定で進めます。
取扱説明書はダウンロードしておくと分かりやすいです。
VS-RC003HVとArduinoの接続
IXBUSのピンアサイン
ピン番号 | 端子名 |
---|---|
1 | TXD0 |
2 | RXD0 |
3 | RESET |
4 | SDA1 |
5 | SCL0 |
6 | SDA0 |
7 | VBATTD |
8 | +5V |
9 | +3.3V |
10 | GND |
5番ピン SCL0と6番ピン SDA0をそれぞれArduinoのSCLとSDAに接続します。
10番ピン GNDも接続しておくと良いです。
電源が欲しければ8番や9番ピンから取れます。便利ですね。
RobovieMaker2の設定
取扱説明書の 1. LED拡張ボードの基本設定 、2. ポーズスライダの設定 に従って設定してください。
1の途中で「I2Cバスアドレス」を設定する部分があると思いますが、ここでは0xc0
に設定しておいてください。ほとんどの場合はデフォルト値だと思います。
2-1.ポーズスライダのプロパティ設定 が終わると、33~38番のポーズスライダが追加されるはずです。
プログラムの書き込み
Arduinoに以下のプログラムを書き込みます。
Wire.begin();
のカッコ内には任意のI2Cスレーブアドレスを指定できますが、ここではWire.begin(0x60);
にしておいてください。
#include <Wire.h>
/* カウンタ変数 */
int count = 0;
/* 一時格納するためのバッファ */
byte dt;
/* 送られてきた数値を格納する配列 */
/* reg_add, PSC_0, PWM_0, PSC_1, PWM_1, LS_0, LS_1, LS_2, LS_3 */
byte reData[9];
void setup(){
Serial.begin(115200);
Wire.begin(0x60);
Wire.onReceive(receiveEvent); //割り込み関数の設定
}
void loop(){
for(uint8_t i=0; i<9; i++){
Serial.println(reData[i], BIN); // 値の確認
}
}
/* データを受信すると処理される割込み関数 */
void receiveEvent(int howMany){
while(Wire.available()){
dt = Wire.read();
reData[count] = dt; //reData[count]にRobovieMakerのスライダ値が入る
count++;
}
count = 0;
}
「I2Cバスアドレス」と「スレーブアドレス」違う理由
RobovieMakerで設定した 「I2Cバスアドレス」 は 0xc0
なのに、Arduinoスケッチでは Wire.begin(0x60);
と書いています。
これはVS-IX004に使用されているIC「PCA9532PW」の仕様によるためです。
データシートによると、接続時にマスターから送信して欲しいデバイスアドレス8bitのうち、スレーブアドレスは上位7bitなようです。
RobovieMaker2で設定した 「I2Cバスアドレス」 0xc0 = 11000000
の最下位1bitを削除すると 0x60 = 1100000
になり、これがArduinoで設定する本当のI2Cアドレスになります。
最下位1bitはICの動作を切替(1:Read / 0:Write)するために使用されます。マスター側が必要に応じて切り替える必要があるのでデバイスアドレス8bitは最下位ビットのみコロコロ変わり、RobovieMakerで設定する「I2Cバスアドレス」とは正確には違うアドレスになると思うのですが、設定ダイアログで7bitのスレーブアドレスのみにしない理由はよくわかりません。
接続確認
Arduinoの電源を入れ、PCとVS-RC003HVを接続しRobovieMakerの通信開始ボタンを押してください。
「プロジェクトの設定」>「CPUの設定」をクリックし、「拡張機器」タブから、先程追加した「VS-IX004」を選択し、「変更」をクリックしてください。
「拡張機器の追加 / 変更」ダイアログが開いたら、「デバイスの詳細設定」をクリックし、設定ダイアログを確認してください。「現在の接続状態」がOK
であれば成功です!
ArduinoIDEからシリアルモニタを開き、ArduinoがVS-RC003HVから受け取っている値を確認します。上手くいっていればRobovieMakerのポーズスライダを動かしたとき、次の表のように対応した値が変化するはずです。
10010 | Register_Address | reData[0] | ポーズスライダ番号 |
---|---|---|---|
0 | PSC_0 | reData[1] | 35 |
0 | PWM_0 | reData[2] | 33 |
0 | PSC_1 | reData[3] | 36 |
0 | PWM_1 | reData[4] | 34 |
10101010 | LS_0 | reData[5] | 37 |
10101010 | LS_1 | reData[6] | - |
11111111 | LS_2 | reData[7] | 38 |
11111111 | LS_3 | reData[8] | - |
まとめ
ここでは「VS-IX004」としてArduinoを接続しましたが、肝は Arduinoが純正拡張基盤と同じアドレスになること です。
VS-IXxxxシリーズの情報は説明書から回路図まで全て公開されているので、使用されているICのデータシートを見に行けば今回と同じ方法で「デジタル入出力拡張ボード VS-IX007」だろうと「アナログ入力拡張ボード VS-IX008」だろうと自作できてしまいます。
「あるモーション中の決まったタイミングで目を光らせたい」、「あるモーションではガトリングを模したLEDを点滅させたい」などのロボットの動きと発光のタイミング合わせが重要な場合に、RobovieMakerのポーズスライダで制御してモーションに組み込むことができるのは相性がとても良いです。
最後に
METAL GEAR REX参号機に携わってから3年経ちましたが、当時頑張っていたことをようやく書き出せてすっきりしました。