2013年1月24日木曜日

Wiimote IRカメラとのたたかい

Wiimoteの赤外線カメラと格闘している。

Wiiリモコン先端の黒い窓、いわゆる赤外線リモコンを連想する部分なんだけれども、よく知られているように、このなかには、画像処理するマイコンを内蔵した赤外線カメラが存在している。

マイコンでは赤外線の光点を4つまで追跡して、それぞれのカメラ上の座標をI2Cで出力するような処理が行われるので、単にI2Cで出てくる数値をとるだけでアプリケーションが簡単に作れるという仕様。

いわゆるWiimote Hackでは、BluetoothでWiimoteとPCなどを接続してセンサのデータをとったりするのだが、過去に作成されてきたソフトウェアはどれもWindows 7またはMac OS Lion、あるいはLinuxに限られていて、Windows 8とMac OS Mountain Lionしかない状況ではどうにもならないのであった。

それで、世界中が感動した、このカメラの解析ページをもとに、中古で買ってきたWiimoteを分解して、このページと同じように2.54mmピッチの8pinヘッダをとりつけたのだった。これはもう、自分で自分をほめるしかないタフな作業。というのは、Wiimote IRカメラは2mmピッチの千鳥足なんである。つまり、前列4pinと後列4pinは1mmずれていて、ただでさえピッチが合わないのに、前と後ろがずれているので、合わせる場所が本当に8つのピンの中央にしかない。また、カメラの極細の足を曲げないといけないので、空中配線になる。さまざまな試行をしたが、結果として、ヘッダーピン側を水平になるよう、うまく固定して、その隣に、コピー用紙5枚(試行錯誤で、この枚数で上側の端子と高さが合った)に載せたカメラユニットを置いて、そっと中央を合わせ、その2本をはんだ付けし、それから左右を少し開いてはんだを流し、片側を完了させたあと、裏返して再び横からじっくり眺め、高さが揃うように今度は前後の間隔を開くよう、適当な定規で持ち上げ、中央2本をつけ、残りを開いてつけるという作業で完了した。老眼で細かいものが全く見えないうえ、電気スタンドで強い光をあてないと細かいものが見えなくなっているので、ルーペを片目で眺めながら、片目だから距離感がないのを時計職人のつもりで慎重に位置をはかりながらの作業であった。

続いて、カメラのCPUを動作させるためのクロック回路とリセット回路の製作に入った。回路図の定数通りに部品を揃えるのだが、リセット回路の30kΩというのは謎である。E24系列でも存在しない値だから。とはいえ、これは単にプルアップしているだけなので、適当でよいはず。22kΩにしておいたら、海外で商品化した人の回路図も22kΩであった。

ひとまず完成したように見えたので、簡単に導通テストだけをやって、少なくとも電源のショートという情けない状態ではないことを確認して、クロック発振を確認してみた。手軽なので使っている、Seed StudioのDSO Nano Duoで見ようと思ったのだが、ちっとも確認できない。いくら回路を調べても、テスターで電圧を調べてもわからないので、テクトロのちゃんとしたデジタルオシロで確認したら、25MHzのはずが75MHzで発振していた。3倍の異常発振だ。

実はクロック回路を自分で組み立てるのは初めてで、ネットに助けを求めたところ、水晶発振子の異常発振の現象と対策についての解説があり、まさに3倍のケースだったので、Rsを追加することで解決をはかった。幸い抵抗はE24系列すべて100本ずつ揃えてあるので、100Ωから順に10kΩまで試してみた。1kΩでようやく25MHzが出たものの、過電流のせいか、振幅が大きく、3.3Vの給電なのに5V近くまで上がり、逆にマイナスにも振れてしまっていた。10kΩでそれはおさまったけれどもまだ歪みがあるので22kΩにしたら、50MHzになってしまったので10kΩに戻した。ほかにも、CLを大きくするというアドバイスがあったので、15pFを4つ買ってあったのを幸いに、それぞれ2個並列にしてみたが、あまり効果はなかった。

そうしてようやく、デバイスを壊さないであろう程度のクロックが得られたのでカメラユニットをソケットに挿してみたのだが、I2Cのクロックさえ出てこないうえに、しばらく調べながらふとユニットを触ってみたら熱いこと。危ないので即座に取り外して、基板を調べてみると、よくわからないのだけれどVcc-GND間が19kΩしかない。はては、I2Cの端子に至っては34kΩとかで、電圧を測ってみると2V以上出ていた。配線ミスなんだろうけれど、やり直す時間も体力もないので、再び海外の商品の回路図を眺めてみたところ、クロックはオシレータユニットを使っているのであった。秋月ならこれで済ませられるところ。

クロックまわりを除けばあとは単に電源とI2Cの引き出しをするだけなので、せっかくがんばったクロック回路はとりやめることにした。それで、なんとなく検索をしていたら、ARMマイコンであるmbedに接続したよという例があって、クロックはCoretex-M3内蔵のPWMで生成してしまい、結局リセット端子のプルアップとI2C端子のプルアップをするだけの簡単回路になっていた。

当初はArduinoに接続するつもりで、Arduinoの5V端子に接続するため、手持ちのSparkfunのレベルコンバータ基板まで実装していたのだけれど、mbedで済むならこれさえいらない。また、mbedでシリアルに流してやれば、当初予定していたNode.jsとの連携もArduinoでやるのと変わらない。この人のように、シリアル(USBだが)に出力するように素直に書けば、Arduinoとやってることは同じだ。

なんだかすごく遠回りをしたような、まぁ勉強になったのではあるが、そんじゃあ、ということで、mbed+StarBoard Orangeを取り出してきたところである。StarBoard Orange使うならWebSocketで出力する例で、さらにUSB HostにもなるからWi-Fiドングルつければいいんじゃないかとか、そんな意見もあるかもしれないが、BluetoothがWi-Fiに置き換わっただけなんだがそれってうれしいのか、とか、それならBlueUSBで無改造のWiimoteと直接ペアリングしてWebSocketしゃべれよとか、いままでの努力はなんだったのかと悲しくなってくるので、シリアルでデータを流すところで勘弁して貰いたいと思っているところだ。

(2013年1月26日追記:昨日mbed接続用の基板を作ってカメラユニットを装着し、見事に4つずつのXY座標をシリアルポートで得ることに成功した。ちなみに、mbedのPWMが出していたクロックは20MHz前後だった。したがって、水晶発振子でクロック回路を自作する人も25MHzにこだわることなく、入手しやすいクリスタルなりオシレータを使っても大丈夫なようだ。また、mbedの出力は結構ジッターがあるので、クリスタルでなくセラロックでも大丈夫かもしれない。あと、Mac OSでシリアルポートと通信するのは、screenコマンドだというのが新鮮だった。古いUNIXユーザなので、POSIXならcuと頭から決め込んでいたのだけれど、cuの仕様も変わっているし、しばらく迷ってしまった。シリアルポートの速度設定はsttyで。だがめんどくさいのでmbed側のプログラムで9600bpsにして、デフォルトから変更しなくてもよいようにした。)