小ネタ 2009-017

Wii MotionPlusの解析

Wii MotionPlus(Wiiモーションプラス)を入手した。分解したり、解析してみる。(2009-06-15)


1. 外観

 既に出回っている資料のとおりの品物(北米版)で、特に変わりはないようだ。
 
 
 最初からジャケット内に収納されている。

 
 後ろ側にクラシックコントローラーやヌンチャクを接続するためのコネクタが付いている。穴位置がちょっと下になっている。

 
 NYKOのワイヤレスヌンチャクヌンチャクワイヤレス化アダプタの受信器との比較。

 Wii MotionPlusの方がNYKOのワイヤレスヌンチャクヌンチャクワイヤレス化アダプタ受信器より大きい。
 任天堂がNYKOのワイヤレスヌンチャクを訴えていたが、逆にNYKOの製品に似た機器を任天堂が後出ししてるのが皮肉だ。
 出荷時にジャケットとくっつけた形で売って、ジャケットまで含めてWii MotionPlusと呼ぶことにすれば回避できるのかも。

(後日加筆 2009-06-18)
 上記でNYKOのワイヤレスヌンチャク受信器と書いたが間違いで、正しくは、ヌンチャクをワイヤレス化するアダプタの受信器である。
 どちらもNYKOの製品なのは違いがなく、外見も以前こちらで書いたとおりで非常に似ている。
 
 そして、困ったことにこれらのワイヤレス受信器は、Wii Motion Plus付きWiiリモコンには物理的に干渉して取り付けることができないのである。
 ワイヤレスヌンチャクのメーカーのNYKOから、形状を変更したワイヤレスヌンチャクが出てくれるといいのだが、あるいは自前で干渉しないようにケースを削る改造をする必要があるかもしれない。




2. 分解

 Wii Motion Plusを分解してみた。(2009-06-15)

 
 基板A面 - ジャイロセンサーが搭載されている

 
 基板B面 - 「RVL-GU」とマーキングされたICが載っている (GUは Gyro Unitの略か?)

 このIC(RVL-GU)は、FNURVL等と同じNECエレクトロニクス製の78K0/KC2マイコン「μPD78F0511」と思われる。

 
 ジャイロセンサーは2部品搭載されている。
 1つは、INVENSENSE製の2軸ジャイロセンサ「IDG-600」で、
 もう1つは、EPSON-TOYOCOM製の1軸ジャイロセンサ「XV3500CB」である。
 2つの部品で合わせて3軸分のジャイロセンサとして使っている。

 ちなみにXV3500CBは、PLAYSTATION3用のDualShock3にも内蔵されている。


 Wii MotionPlusを買えば、3軸分のジャイロセンサ部品を格安で入手することができる。かなりお得だ。




3. 解析 その1

 既にWiiBrewというサイトに情報が出ていた。(2009-06-15)
 register 0xA60000 にアクセスすると書いてある。Wii Remote hack界隈ではregisterと呼んでいるのだが、実際にはI2Cのバスに流すデータ列である。 多くのWiiリモコン関係のI2C機器が2バイトで読み書きのアドレス指定しているので、先頭の1バイトと併せて3バイトのレジスタアドレスと解釈されているが、1バイトでアドレス指定するI2C部品もあるので、この表現は正確でないと思う。

 ちなみに、ヌンチャク等がregister 0xA40000と言っているが、これはI2CのICのアドレスが0x52ということである。
 Wii Motion PlusのI2Cのアドレスは0x53ということである。

 以前2007年に、Wiiリモコン内蔵の赤外線ポインティング用センサを取り出して使う方法を解析したのだが、このポインティング用センサのI2Cのアドレスは0x58である。
 また、同じく2007年にWiiリモコンにジャイロセンサーを接続する自作周辺機器を作ったのだが、そのときはI2Cのアドレス0x49を使った。

 解析が進めば、WiiMotion Plusの基板から Vcc, GND, I2C_SDA, I2C_SCLの4本の配線をつなげてWiiリモコン以外からでも3軸ジャイロセンサを利用することがおそらく可能である。マイコンなどに接続して使うのが期待できる。


 (後日加筆 2009-06-21)
 WiiBrewの情報が更新されている。BluetoothでPCに接続する方法が出ている。
 参考にしつつ、I2Cデバイス向けのI2Cバスデータ送受信方式の自分オリジナル方式に直して自前でソフトを作ってみた。
 作ってみたのだが、どうもうまく動かなくて、いまのところジャイロセンサーの回転量を読み出すことができなかった。
 とりあえず、内部データを読み出すところまで作ってみた。途中まで一応は動いているようなので、ソフトを公開しておくことにする。

 [ Wii Motion Plus の内部データ読み出しソフト 実行ファイルとソースコード (download) ]
  (後日加筆 ジャイロセンサ値の読み出しソフト(download)を作った。詳細は、2009-07-05の加筆分を参照のこと。)


 (後日加筆 2009-06-22)
 少し、うまくいかなかった部分の原因を考え中。

 Wii Motion Plusにデイジーチェーンでヌンチャク等が接続できるので、ヌンチャク等とI2Cバス上で共存するためにI2Cのアドレスが重複しない値に変わっている。そうすると、今までのヌンチャク等の周辺機器のようにタイマー割り込み処理で自動に周辺機器ICにアクセスして結果を取りまとめてBluetoothで通信して送るということが、Wii Motion Plusの場合にはできなくなってしまう。
 そのため、素のWii Motion Plusからセンサ値を取り出すには、汎用のI2Cバス制御コマンド(Report 0x16)を使うしかないのだが、これだと、Bluetooth通信部分のオーバーヘッドが大きくて高速にデータを取り出すことができない。

 どうも任天堂は苦肉の策で、Wii Motion Plusにイモヅル式にヌンチャク等の他の周辺機器が接続されていない場合に限って、Wii Motion Plusのモードを切り替えることで、ヌンチャク等の周辺機器と同じI2Cアドレスを使うようにできるようにしたらしい。動的にWii Motion Plusのアドレスを切り替えるということだ(そういう挙動に見える)。この方法だと今までのヌンチャク等と同様にタイマー割り込み式の自動読み出しでセンサ値を読み出して、それを取りまとめて1回のBluetooth通信で通信することができ、高速かつ効率的にデータを渡すことが可能となる。
 その代償で、Wii Motion Plusを高速で使うモードにしていると、ヌンチャク等を同時に使うことができない。Wii Motion Plusを低速のままヌンチャクと同時に動作させることもできそうだが、Wii Motion Plusの応答性が落ちるのではあまり意味がない。ヌンチャクとうまく共存できないというのは、ちょっと制約としては大きい気がする。
 (どのくらい応答性が落ちるのか実際にWii Sports Resortが入手できたら測定してみたい。)
 (後日加筆 2009-07-04 MotionPlusの中身をもう少し詳しく調べてみた。詳しくは下記の解析その2を参照のこと。)


 (後日加筆 2009-06-27)
 Shiraiという方がWii Motion PlusをPCに接続するソフトを試している。gl.tter氏のWiiYourself!という名前のWiiリモコン制御ライブラリが最新beta版1.13でWii Motion Plusに対応したので、そのライブラリとサンプルコードをビルドして試したということらしい。




4. 解析 その2

 Wiiモーションプラスを更に買い増しして、壊しても大丈夫になったので、また分解して中身の基板をもう少し詳しく調べてみた。(2009-07-04)
 
 調べた結果、今までにWii Motion Plusの挙動から中身を予想していたものとは、実際は異なっているようだ。
 とりあえず、図に書いてみる。
 
 この図の上側の部分が、最初に考えていた書いた予想図で、実際には下側のような回路になっている。

 予想図は、RVL-GUという部品が、NECエレクトロニクス製の78K0/KC2マイコンであるということで、このマイコンにI2Cバス機能が1つしか備わっていないことから、最初に書いた予想で図のような回路だと考えたのである。
 実際には、マイコンのI2Cスレーブ機能は今まで通りI2CバスAそのまま使って、もう1つ別に拡張ポート側のI2CバスBというのを分離して、RVL-GUのマイコンをI2Cのマスターにして使っている。マイコンにI2Cのスレーブ機能とマスター機能の両方を持たせているのである。
 そして、普段はI2CバスAのデータとI2CバスBのデータを相互に受信&再送信するバス・リピーターとしてのソフトが動作するようだ。

 最初に電源投入時には、RVL-GUは前述のI2Cバス・リピーターとして起動する。
 そのあと、特定のコマンドをWiiリモコン側から受け取ると、リピーター機能が無効になり、RVL-GUがI2Cアドレス0x52の周辺機器として使えるようになる。この状態だと、従来の周辺機器と同様にアクセスすることが可能。

 リピーター機能が無効になっていると、拡張ポートに接続したヌンチャク等の周辺機器を従来の方法では読み出すことができなくなってしまう。これを併用可能にするために従来の方式から拡張されて、I2CバスBを制御して周辺機器からデータをRVL-GUが受け取って、なんらかの拡張コマンドで読み出せるようにしているのではないかと予想される。このあたりは今度時間があったらWii Sports Resortのアーチェリー等を動かしている最中にI2Cバスを観察して調べてみたいと思う。




5. 電子工作に応用

 AVRマイコンにWii Motion Plusを接続して、3軸ジャイロセンサーの出力を読み出してみた。(2009-06-24)
 
 使った電子回路は、以前にWiiリモコン内蔵の赤外線ポインティング用センサを取り出して使ったのと同様に、Arduinoというマイコンキットの基板を使った。だだしマイコン内のArduinoファームウェアは使わずに消して、普通にAVRマイコンボードとして用いた。それに加えて、Arduino用に前回作成したI2C電圧変換回路の拡張基板をそのまま用いた。

 Arduino基板に少しだけ改造して、発振用の水晶を14.7456MHzに交換した。シリアル通信のbpsの精度を良くするためである。あと、RESET-ENをカットしておくこと(DTR信号でリセットが掛かるのを防止するため)。

 ソフトウェアは、WinAVR + AVR Studioの環境で作成した。ソースコードのコンパイルは、compile_avr.batというバッチファイルでビルドする。

 [ avr_motionplus_01.zip (download) 187KB ]

 動作させると、シリアルポートに3軸のジャイロセンサー出力値を10進数でコンマで区切った形式(例. 「8799,9423,9298」)で出力する。通信速度は921600bpsで、データ長8bit、パリティ無し。zip内に簡易ターミナルソフトも入れてあるので、それを使ってCOMポートを自動検出させて通信して通信内容を表示させることができるはずである。
 実際に動作させ、センサーの数値を確認できた。


 (後日加筆 2009-07-04)
 上記のソフトウェアで少し問題があったので修正した。
 ・I2Cの通信の一部にウェイトを入れる処理を追加した。
 ・測定レンジの切り替えの状態の出力処理を追加した。 ただし、まだレンジが切り替わった場合の計算式がよく分かっていない。初期値を引いてから8倍する計算か?
 ・ジャイロの出力値とレンジ値(0か1)を6つの数字で出力する。
 ・出力形式は、10進数でコンマで区切った形式(例. 「8799,9423,9298,0,0,0」)

 [ avr_motionplus_02.zip (download) 277KB ]

 このソフトで使用する前に、あらかじめWii Sports Resort等で動かしておかないと、Wii Motion Plusの初期化がうまくいかず、正しく3軸の値が出なくなることがある。(かも?)


 実際に出力された結果をグラフにプロットしてみた。
 
 9600くらいの初期値から始まって、最初に軽く振った波形が3800から15800位までの振幅で上下に振れている。
 そのあと、高速に数回振った波形の部分でレンジ切り替えが起こっている。

 (後日加筆 2009-07-12)
 上記のソースコード中のコメントのyaw,roll,pitchが間違っていたようだ。あとで修正の予定。




6. PCからBluetoothでWiiリモコン経由で使ってみる

 Shiraiという方がWii Motion PlusをPCに接続するソフトを試している。gl.tter氏のWiiYourself!という名前のWiiリモコン制御ライブラリが最新beta版1.13でWii Motion Plusに対応したので、そのライブラリとサンプルコードをビルドして試したということらしい。(2009-06-27)


 WiiYourselfの処理を真似して、自分もMotion Plus対応のソフトを作ってみた。(2009-07-05)

 [ Wii Motion Plus のジャイロセンサ値の読み出しソフト 実行ファイルとソースコード (download) ]


 AVRマイコン用に作成したソフトの処理でI2Cバスに直接書き込んでいた処理を、Bluetooth_HID経由でWiiリモコンのI2Cバス制御コマンド(Report 0x16)を使って書き直しただけである。詳細は前項のAVRマイコン用のソフトの説明部分を参照のこと。

 汎用コマンドのI2Cバス制御コマンド(Report 0x16)のみを使って読み出しているので、あまり高速に読み出せていない。マイコンに直結の場合には高速になるのだが、Bluetooth経由だとオーバーヘッドとなる部分で大きく差が出る。
 Wiiリモコン内の加速度センサの読み出し処理と同じようにWiiリモコン内部で自動でタイマー割り込みで動作させた方が高速に読み出せるはずである。応用デモソフトを作るときには書き直す予定。




7. PCとWiiリモコンをBluetoothで接続する方法の復習

 Wiiが発売された当初からWiiリモコンをBluetoothでPC等に接続して制御する方法のhackが発表されて、WiiLiやWiiBrewというサイトを中心に色々な人がWiiリモコンを解析して、結果が発表されている。

 自分なりに振り返って、復習がてら、ちょっと以下に書いてみる。(2009-07-19)

 (1)PCのOSの選定
 LinuxやMacOSなどUNIX系のhackも存在するが、Windows PCを使ったhackが多い。
 しかしWindowsの場合、OSがWindows XPかWindows Vista(Windows 7)かでBluetoothのドライバの使い方が異なっていたり、Microsoft以外のBluetoothドライバの存在と、それらの非互換の問題がある。
 とりあえず、自分の場合はOSをWindows XP SP2をメインにしてhackを進めた。(当時はまだVistaが出ていなかった)

 (2)Bluetoothドングルとドライバソフト(Bluetoothスタックソフト)の選定
 BluetoothのI/Fは、PCに内蔵していたり、USBドングルだったりする。PCカードタイプの古いBluetooth I/Fも自分は持っているのだが、WindowsXP用のドライバがなかったり、Bluetooth1.1しかサポートしていなかったり、HID(ヒューマンインターフェースデバイス)が使えなかったりする。
 Bluetoothドングルを購入すると、大抵サードパーティ製のドライバが付属のCDに入っている。
 「東芝 Bluetooth Stack」、「WIDCOMM BTW 3.0」、「BlueSoleil」の3種類のどれかが付属してくることが多い。
 これらのどれかのドライバをインストールすると、それぞれ使い方の異なるBluetooth機器の管理ソフトの1つが常駐する。
 いくつかのドングルは、付属CDのドライバをインストールしないでPCに挿した場合、Microsoft製のドライバが自動的にインストールされる。
 その場合、ドングルは「Microsoft Bluetooth stack」で動作し、Windowsの標準のBluetooth管理ソフトで使用する。
 それぞれのBluetooth Stack場合で、管理ソフトが異なっており、Wiiリモコンを接続する操作方法が異なるので注意が必要である。

 (3)Bluetoothを制御するソフトの作り方
 まず、Bluetooth機器を検索して接続する方法について、上記のそれぞれのBluetooth Stackで開発方法が異なる。APIが公開されていなかったり、有償で契約しないと入手できなかったりする。唯一、Microsoft Bluetooth Stackについては、Bluetooth機器の検索や認証して接続するAPIが公開されている。ogaという方がWii Balance boardのhackで自動接続方法を開発した。そのソースは公開されていないが、どのAPIを使えばよいのかblogに書いていたので、自分も真似してWiiリモコンの自動接続ソフトを作ってみた。
 WiiリモコンとPCとの接続は、Microsoft Bluetooth Stackを使っている場合にはそういった自動接続ソフトで接続すればよい。
 それ以外のBluetooth Stackを使っている場合には、手動で接続しなくてはならない。認証のためのPINコード無しで接続しなければならないので、いくつかのBluetooth Stackでは操作が分かりにくいかもしれない。

 一旦Wiiリモコンが接続されたあとは、PCからはHID(ヒューマンインターフェースデバイス)として認識される。マウスやゲームパッドと同類である。マウスやゲームパッドの場合には専用のAPIがあるのだが、それ以外のHIDの場合には汎用のRead/WriteのAPIで直接制御しなくてはならない。ただし、ドライバから自分で作るよりは遙かに楽である。
 自分の場合は、Wiiリモコンでなく、それ以前からUSB用のHIDを使った電子工作を「USB Complete」という書籍を参考に作っていた。USB-IOというような商品と似たようなものを自作で作っていて、そのときのソフトのサブルーチン部分をWiiリモコンに応用して、それを切り取ってライブラリにして、tiny_hid_dllという形にした。「USB Complete」の著者のホームページで公開されているコードをほぼそのまま使っているので、自分が作ったライブラリと言えるようなものでなかったりする。DLLとして切り出してあるおかげで、WinDDKをインストールしなくても使うことが出来るのでそれなりに便利に使えてたりする。

 ここで1つ問題になるのが、Microsoft Bluetooth Stackの場合に汎用のWriteのAPIではデータ出力ができないという非互換性問題である。Readについては問題がないのだが、Writeで出力しても出力がされないし、エラーが出ないのである。この問題について も ogaという方がWii Balance boardのhackで解決方法を開発した。そのソースは公開されていないが、どのAPIを使えばよいのかblogに書いていたので、自分も真似してMicrosft Bluetooth Stack対応版のtiny_hid_dllというのを作成した。

 自分以外にも多数のWiiリモコンhackが出ている。それらはWiiリモコンの接続は手動で、そのあとの部分のみを作ったものが多い。それらのソフトの機能は、初期のhackではtiny_hid_dllのような単純なRead/Writeでデータの読み書きをするものから始まって、徐々に進化して、Read/Writeデータの意味を解釈して十字キーを読んだりセンサーを読んだり振動をon/offしたりするものが作成された。多くはWiiLiやWiiBrewというサイトに書いてある情報が増えていったのを読んでそのままコードに書き下ろしただけのものである。唯一、GlobePIEは独自で進んだhackをしているのだが、ソースとか解析情報を公開しないのが残念である。

 (4)Wiiリモコンhackの応用
 Wiiリモコンを分解して中身の基板上の回路を調べると、WiiLiやWiiBrewといったサイトに書いていない情報を調べることができる。
 これにより、Wiiリモコン回路のメインCPUが、I2Cという汎用バスで内蔵の周辺ICや周辺機器(ヌンチャク等)を制御するという構造が明らかになった。
 I2Cバス上の通信データをモニタする装置は、BluetoothのSnifferなどより安く、自作も可能なので、I2Cバスを観察することでWiiリモコン内蔵の周辺ICや周辺機器(ヌンチャク等)のhackが進んだ。
 特にI2Cバスで接続されたCMOS赤外線センサの使い方のhackが進んで、より正しい初期化とパラメータ制御ができるようになった。また、このセンサーをWiiリモコンから取り出して、I2Cバスでマイコンに接続して自作機器に使うこともできるようになった。
 他にも、外付けの周辺機器について、
 ・ヌンチャク/クラシックコントローラー/ギターコントローラー/MotionPlusの解析やEncript方式の解読やマイコンへの接続
 ・Wiiリモコンに接続するAD変換器やI2C-GPIOを使ってテンキーやジャイロセンサーなどの自作周辺機器をWiiリモコンに接続
 といったhackの応用範囲が広がっている。






参考Link
 Wii.com JP - 社長が訊く『Wiiモーションプラス』
 Wii.com JP - 社長が訊く『Wiiモーションプラス』圧力なべを買ってやったこと
 Wii.com JP - 社長が訊く『Wii Sports Resort』
 AiLive LiveMove 2: Motion recognition and tracking
 InvenSense Library
 EPSON TOYOCOM QMEMSセンサー
 XV-3500CB 50.300000kHz
 WII Motion Plus Gyro - Parallax Forums
 Arduino Forum - Wii Motion Plus Request
 Make: Gyrating Arduino with Motion Plus
 WiiMotionPlus動作確認デモbyWiiYourself!v1.13 - 王様の耳はロバの耳


- See Also -

 Wiiリモコンに接続する周辺機器の中身の解析
 Wiiのワイヤレスヌンチャクを試してみる (+無線クラシックコントローラー)
 Wiiクラシックコントローラーとヌンチャクの中身の互換性
 Wiiリモコン用の自作周辺機器を作ってみる - その2 ジャイロ
 Wiiリモコン用の自作周辺機器を作ってみる - その1 テンキー
 Wiiリモコンのポインティング用赤外線センサ部品の解析
 WiiリモコンをPCで使うサンプルソフトを作ってみる