はじめに
ADNS-3090とADNS-9800というゲーミングマウスのセンサが、マウスパッドをどのように「見て」いるのか、というセンサの視界を人にも見える化するシステムを作りました。こういったシステムがあると、
ソール厚に関する知識を深めたり 、
特定のマウスパッドへの相性問題を解決したり 、
モヤモヤした画像を見て悦に入ったり と色々なことが出来ます。
要するに、マウスとマウスパッドの間に問題が起きた時にデバッグしたり、更にマウスの性能を引き出したりする時に手助けとなる道具です。ただ闇雲にデバイスを買って試すのではなく、色々な道具を作って科学的/工学的な観点でデバイスを評価するのも私は良いと思うのです。
前の記事 との差分としては、現役で活躍しているゲーミンググレードのレーザーセンサとLEDセンサの双方で「見る」ことが出来るようになったのは意義があるでしょう。記事のような色々なマウスパッドの表面画像についてはそのうちまとめます。
ハードウェア
まずはセンサとMCUについてハードウェアの面で説明します。
ADNS-9800
ADNS-9800は色々と訳あってセンサモジュールを購入しました。
ADNS-9800のセンサモジュール with ジャンパワイヤ
代理店を介さずにゲーミンググレードのセンサを購入できる場所は少ないです。結構探したのですが
このサイト しかありませんでした。送料が$60という恐ろしい数字だったので非常に痛い出費ですが、個人に売ってくれるだけありがたいです。
送料分を取り返すためにモジュールに加えてバニラなセンサとレンズのセットを数組購入しましたが、使用予定は・・・In progressということで。
センサモジュールはピンアサインがはっきりしているので説明通りに繋ぐだけで大丈夫です。
このモジュールは探せばArduinoのサンプルもあるので、Arduino持っていれば誰でも動かせると思います。
ADNS-3090
ADNS-3090は
ELECOM M-XG3G のセンサを使用しました。
3000円程度で完動するセンサモジュールが手に入るのは素晴らしい・・・(とか考えてるのは日本で私くらいしか居ないのかもしれません。)
購入した時はマウス自体のMCUがセンサのマスタになっているので、データパスを切る必要があります。
ADNS-3090のSROMがなかなか見つからないのでデータパスを切る前にSROMを事前に吸い出す予定でしたが、「ADNS-3090は部品としては手に入らないセンサなのでSROMを持っておく必要もないのかな」と考えてデータパスをぶった斬りました。RIP。
データパス切断の図。中央の傷の部分でレジストごと配線を切っています。
切る必要があるのは、NCS、MISO、SCLK、MOSI、RESET、NPDです。
最近のマウスはほとんどが両面基板なのでビアを追うのが面倒ですが、センサ付近から追っていって切りやすい部分で切ればいいと思います。
外観は
ゴミを寄せ集めたみたいな 手作り感溢れるアットホームな感じです。自分のMCUからの配線はセンサの足に直付けしています。こうすると基板の上側から配線を引き出せるので非常に便利です。
システム外観。
MCU
センサを制御してもらうMCUはいつものCY8CKIT-042 PSoC 4 Pioneer Kitです(上写真右の赤いボード)。
プログラマ不要の開発ボードで、
秋月で税込み3000円で買えます 。Arduinoみたいなピンアサインで、しかもリセットしてもCOMポートの接続が切れないのでとても便利です。
センサから生やしたジャンパワイヤをしかるべき所に繋ぐだけで準備完了。
ソフトウェアの実装
あんまり面白いことはしていないのですが、概要は下のようになります。
MCUがセンサにFrameCaptureをリクエスト
センサが画素データを返す
MCUが画素データのバイナリをUART→USB経由でPCに転送
ホストのアプリがバイナリを受け取り、グラフとして描画
1~4を繰り返す
ホスト(PC)のプログラム
ホスト側はネイティブアプリを書くのも面倒なのでPythonのserialモジュールと、matplotlibモジュールでお茶を濁していくスタイル。matplotlibは動画も撮れたり、画像の補完方法も豊富なので結構便利ですね。
MCUのファームウェア
MCU側はフンハフンハ言いながら実装するとできます。いくつかセンサを触った経験から言うと、とりあえずProductIDを取得出来るようにする→大体の事は出来るようになる。という感じなのでデータシートをよく読みながら実装すればよいでしょう。
注意する点としては、ADNS系のセンサはNCSの扱いが特殊なので、そこに工夫が居る点です。
MCUからのレジスタアドレスとして1バイトの送信が終わってNCSをHIGHにしていまうと、うまく動きません。なので、NCUはMCUのSPIの処理とは別に制御する必要があります。
PSoCの場合は、SPIのNCS(SS)はSPIコンポーネントには接続せず、別にDigital Output Pinを用意すれば良いです。
基本となるRead/Write Operationsコードはこんな感じになります。ここでは、NCSとしてSSというピンを用意して、適宜HIGHにしたりLOWにしたりしています。
--------
void Write_Operation(uint8 address , uint8 value )
{
address = address | 0b10000000; //MSBを1にしてWriteだと伝える
SPIM_ClearRxBuffer(); //バッファクリア
SPIM_ClearTxBuffer();
SPIM_ClearFIFO();
SS_Write(0); //NCSをLOWに。送信開始
CyDelayUs(1); //ディレイが必要。時間はセンサによる。
SPIM_WriteTxData(address); //書き込み先のレジスタアドレス送信
SPIM_WriteTxData(value); //書き込み先のレジスタに書き込む値を送信
while(!(SPIM_ReadTxStatus() & SPIM_STS_SPI_DONE)){}; //終わるまで待つ
CyDelayUs(1);
SS_Write(1); //NCSをHIGHに。送信終了
SPIM_ReadRxData(); //SPIのRxに入ったゴミデータを捨てる
SPIM_ReadRxData(); // SPIのRx に入ったゴミデータを捨てる
CyDelayUs(120u); //ディレイが必要。時間はセンサによる
}
uint8 Read_Operation(uint8 address)
{
address = address | 0b00000000; //MSBを0にしてReadだと伝える
SPIM_ClearRxBuffer(); //バッファクリア
SPIM_ClearTxBuffer();
SPIM_ClearFIFO();
SS_Write(0); //NCSをLOWに。送信開始
CyDelayUs(1); //ディレイが必要。時間はセンサによる
SPIM_WriteTxData(address); //取得先のレジスタアドレス送信
while(!(SPIM_ReadTxStatus() & SPIM_STS_TX_FIFO_EMPTY)){}; //送信が終わるまで待つ
CyDelayUs(100); //ディレイが必要。時間はセンサによる
SPIM_WriteTxData(0x00); //0x00を送る間にデータが帰ってくる
while(!(SPIM_ReadTxStatus() & SPIM_STS_TX_FIFO_EMPTY)){}; //送信が終わるまで待つ
while(!(SPIM_ReadRxStatus() & SPIM_STS_RX_FIFO_NOT_EMPTY )){}; //RxFIFOに1個目のデータが来るまで待つ
SPIM_ReadRxData(); //一個目はゴミなので捨てる
while(!(SPIM_ReadRxStatus() & SPIM_STS_RX_FIFO_NOT_EMPTY )){}; //RxFIFOに2個目のデータが来るまで待つ
SS_Write(1); //NCSをHIGHに。送信終了
CyDelayUs(120u); //ディレイが必要。時間はセンサによる
return SPIM_ReadRxData(); //レジスタから取得したデータを呼び出し元に返す
}
--------
弱いコードですが大目に見て下さい。
ちなみにFrameCaptureを動かすだけならSROMは必要ないので色々なセンサで試すことが出来るでしょう。
動かしてみた
画像や動画はCOUGAR Control Mouse Padの滑走面を撮影したものです。
ADNS-3090の画像
ADNS-3090は画素が0~63の値をとるようなので、ADNS-9800(0~127)の値から2倍になるようにしています。
ADNS-3090
ADNS-5090(下図)を高解像度化したような印象です。センサ素子がADNS-5090は19x19ですが、ADNS-3090は30x30になったためですね。視野の範囲などの考察はまたいずれ。
ADNS-5090
ADNS-3090の動画
動画にするとこんな感じです。適当に動かしています。後半でマウス全体を一度持ち上げていますが、3090ではシャッター値がMAXになると白飛びに近い状態になるようです。
VIDEO
ADNS-9800の画像
ADNS-9800はこんな感じに映ります。
ADNS-9800
見た印象だと全然同じマウスパッドに見えません。これはLED式センサと比較すると、見えている範囲がものすごく小さいためです。LED式センサでは「山」が2個くらい画面内に映るのですが、「山」ひとつでフレームアウトするような感じです。詳細な比較はまたいずれ。
また、ADNS-5090やADNS-3090のようなLEDセンサと比較すると、「のっぺり」とした印象になります。これは、レーザの射角が滑走面に対して深いためです。LED式センサではほぼ真横にLEDが付いていて、それをレンズで屈折させて滑走面を照射しており射角が浅いのですが、レーザ式の場合はセンサダイの真横にレーザ素子があり、そこから下図のようにレンズで屈折させて射角が深くなっています。射角が深いため、「影」となる部分が少なく、LED式と比較してコントラスト比が小さくなると考えれます。
Pixart ADNS-6190-002 データシートより
他にも「レーザースペックルがどうのだからDPIが・・・」みたいな考察もあるので、もう少し裏を取ってから別記事で上げたいと思います。