ロビのシリアルバスその1
2015年11月25日
11月28日改訂
12月3日改訂
12月14日改訂
前回まではロビの目に仕込んだドットマトリックスLEDをロビのプログラムで制御してきました。
両目のLEDのRGBの制御電圧を拾ってコード化してそのコードのパターンを表示してきましたがそれぞれ3ビット(RGB)で両目を使っても6ビットのデータしか表せません。
目のパターンだけならこれで十分ですが2桁の数字を表そうとしても64までしか表示できません。
実際は消灯などのコードも必要で0〜59の範囲の数字しか表示できませんでした。
またArduino Nanoで制御していますがI/Oピン数が22本しかありません。
7×5のドットマトリックスLEDを左右別の表示をするためには7+5×2=17本の出力ピンが必要で入力ピンに6ポン使うと1本足らなくなってしまいます。
そこでマイコンカードが音声認識ボードなどとのデータのやり取りに使っているシリアルバスを使えないか調べ始めました。
ロビのシリアルバスは、マイコンボード、音声認識ボード、テレビリモコンボード、LED基板(目と口のLEDおよび人感センサー)これらをつないでいる4本の黒いケーブルです。
このシリアルバスの規格はI2C(アイスクエアーシーまたはアイツーシ)といって電子機器同士をつなぐのによく用いられる規格のようです。
パソコンの場合USB(ユニバーサルシリアルバス)が主流ですが少ない部品数で実現できるので転送速度が要求されない小スペース低コスト用としてよく用いられるようです。
I2Cについての情報はネット検索で調べられますのでここでは詳しくは述べません。
I2CはGND(-),VCC(+),SCD(データ),SCL(クロック)の4本の信号線から成ります。
ロビのケーブルこの順の並びとなっています(下配線図参照)。
これらを制御するには規格に合わせた信号をやり取りしなければいけないのですが幸いArduinoのIDE(開発環境)にはWireライブラリィというものがあってこれを使えば簡単にデータのやりとりができそうです。
データのやりとりにはマスターとスレーブというふたつのやり方があります。(通常のコンピュータと同じ)
簡単に言うとXXさん、調子はどう?と聞いて返事を待つのがマスター型で、私はXXさんですよと宣言して何か話しはない?とか調子はどうか聞かれた時の返事をしてあげるのがスレーブ型だと思ってください。
ロビの場合、マイコンボードが音声認識ボードに何か音声認識した?と聞くのがマスター型で音声認識ボードがあったよと応えるのがスレーブ型と考えてください。
しかしこれはあくまで私の想像なので実際のプログラムの作りはそうではないかも知れません。
XXさんにあたるのがアドレスでそれぞれの基板に与えられた番号です。
例えば音声認識ボードはある固定のアドレスが割り当てられているはず。
しかしロビのスペックは公開されていないので自分で調べるしかありません。
調べるのにあたってロビのシリアルバスとArduinoとを接続しなければいけません。
写真はArduino Nanoとの接続ですが他のArduinoでもピンの名称は同じです。
シリアルバスはLED基板のコネクターと接続していますがどの基板のコネクターでも構いません。
黒線がGNDでArduinoのGNDと接続します。
赤線が電源でArdduinoのVINと接続します。
青線がSCD(データ)でArduinoのA4(アナログピン)と接続します。
緑線がSCL(クロック)でArduinoのA5(アナログピン)と接続します。
通常I2Cの信号線にはプルアップ抵抗でVCCと接続する必要ですが他のロビの基板でプルアップしてくれていると思いますので割愛しても構わないと思います。
私も最初4.7kΩの抵抗でプルアップして試していたのですが外しても変化はないようです。
この写真ではロビのマイコンボードとつながっていないのでこのままでは動きません。
マイコンボードとつなぐシリアルバスから分岐させるケーブルを作る必要があります。
ロビのシリアルケーブル(黒の4本)の途中にメスのジャンパー線を結線しました。(ケーブルの色は配線図の色とは異なっています)
ケーブルは配線図のコネクターと合わせてください。
最初はロビのケーブルを切断したくなかったのでコネクターの隙間に一芯のケーブルを突っ込んでいたのですが接触不良の恐れがあるのでちゃんと切断してハンダ付けをしました。
なおしっかり結線すればハンダ付けをしなくてもテープを巻けば大丈夫だと思います。
各基板のアドレスを調べるにあたってこちらのスケッチを使わせてもらいました。
シリアルモニタの通信速度が9600になっていますがArduinoとPCの通信速度は通常115200なので修正してください。
ツール→シリアルモニタの実行画面がこちらです。
なお時々関係のないようなアドレスがひっかかるのでelse if (error==4)の部分をコメントアウトして実行しています。
それぞれの基板を外していって表示されないのがその基板のアドレスとなります。
そうやって調べると0x03(3)と0x04(4)がLED基板、0x20(32)がTVリモコン基板、0x28(40)が音声認識基板だという事が分かりました。
全部の基板を抜いても0x4C(76)が残ったのでこれはマイコン基板だと思います。
その後の実験でこのアドレスはマイコン基板にあるジャイロセンサーのような気がします。
ロビの体を前後に傾けるとこのアドレスから読み取ったが変化しました。
LED基板がふたつアドレスがあるのは人感センサーと違うアドレスを使っているのかも知れません。
後の実験で分かったのですが0x04の方が口と目のLEDのようです。
なお再販版のLED基板は0x04でなく0x05のようです。
他のボードも初販版から変わっている可能性があるのでアドレスのスキャンプログラムで実際のアドレスを調べてください。
アドレスが分かったところで次は「調子はどう?」にあたる部分を調べてみます。
こちらもロビのスペックがないので手当たり次第のデータで聞いてみます。
手始めに音声認識ボードに対して聞いてみました。
こちらのスケッチを使いました。
遅くてやってられないという方は最後のdelayの時間を短くしてください。(あまり速いとArduinoがハングする頻度が上がります)
ツール→シリアルモニタの実行画面がこちらです。
33に音声認識番号らしきものが返ってきています。
これを実行する前に「あいさつして」という言葉をロビに認識させていました。
確かに「あいさつして」の認識番号と一致します。
こちらは「今月ピンチ」という言葉を認識させています。
この認識番号は266ですが1バイトで表せるのが0〜255なのでそれ以上は32が1(256で割った値)となり33には16進の下4桁(256で割った余り)が返されると思われます。
なおこのプログラムは途中でArduinoがハングする事があります。
そうなるとI2Cを使ったロビの音声認識やLEDの点滅も止まってしまいます。
その場合はArduinoのリセットボタンを押したりArduinoのI2Cケーブルを抜くと音声認識やLEDの点滅も復活します。
以上の結果を踏まえて音声認識をロビ目に表示するプログラムを作ってみました。
実際にこのプログラムを動かした時の動画です。
I2Cの制御に2本しかピンを使っていないので7×5のドットマトリックスLEDに違ったパターンが表示できています。
同様にLED基板に対してこのプログラムを実行すると目のLEDを制御しているデータも取り出す事ができました。
しかし実行中にArduinoがハングしてしまうという課題が残っています。
使用しているArduino(中国製の互換機)のファームバクなのかマスター型でロビの基板にアクセスしてはいけないのか分かりません。
これからまだまだ調べる必要がありそうです。
おそらくマイコンボードもマスターなので同じI2Cネットワーク内でマスターが2つ存在することになりバス衝突という現象が起こっているのだと思います。
I2Cの仕様ではマルチマスターを許しているのですがIDEのWireライブラリィがマルチマスターをサポートしていないのかも知れません。
現在Wireライブラリィを使わない方法を検討しています。(11月28日追記)
Wireライブラリィを使わない方法はこちらを参照してください(12月3日追記)
一応今回の目的とするI2Cに対してのアクセスはできました。
興味のある方はこれをベースにロビのシリアル通信のコマンド仕様を調べていきませんか。
なお本改造はロビ本体への影響を及ぼす可能性があるのであくまでも自己責任という事でお願いします。
目次に戻る