Arduinoで光学式マウスのCMOSセンサーを乗っ取って移動距離を計測する
Posted by arms22 on 2015年01月07日

昨年末の話。勤務先の大掃除の日にいらなくなった光学式マウスを頂戴してきたので、マウスに内蔵されているCMOSセンサーを使って移動距離を計測する実験を行いました。この記事ではArduinoを使ってセンサーから座標を取得し、マウスの移動した距離をシリアルモニタに出力する方法を紹介します。
写真はマウスを分解したところ(マウスの型番はFMU−HOP1-PW)。真ん中の8本足のICが今回の主役CMOSマウスセンサー「PAN3101」。PAN3101はDSPを内蔵したローコストの光学式マウスセンサーの1つで、ICに内蔵されたCMOSカメラで机やマウスパッドの表面を連続して撮影し、その映像から移動方向や距離を測定します。シリアルインターフェースを通してレジスタの値を読むことで現在のX/Y座標を知ることができます。PAN3101の横の細長いICはUSBインターフェースだと思います。
PAN3101の仕様
- 電源:4.75V〜5.5V
- システムクロック:18.432MHz
- 速度:21インチ/秒
- 解像度:400 or 800カウント/インチ
- フレームレート:3000fps
- 動作電流:10mA(移動中)、5mA(停止)、100uA(パワーダウン)
- インターフェース:2線式シリアル
※このICはカメラ映像を抜き出すことはできない様子。


ICの裏側にピンホールが開いていてプラスチック製のレンズが取り付けられている。
ハードウェア

USB ICとマウスセンサの間のSCLK/SDIOのパターンをカットしSCLK/SDIOにワイヤに接続します。USBケーブルが接続されていたスルーホールをArduinoとの中継ポイントとして利用するためUSB ICに接続されているD+/D-のパターンもカットします。
次のようにArduinoと接続します。PAN3101のピン割り当てはデータシートを参照してください。
マウス to Arduino
VDD(7) 5V
SCLK(4) 2番
SDIO(3) 3番
GND(6) GND
ライブラリ
幸いにもArduino用のライブラリを見つけることができました。OptiMouseはPAN3101以外にAgilentのADNS-2051・ADNS-2083・ADNS-2610に対応しています。
OptiMouse
https://github.com/zapmaker/OptiMouse
スケッチ
//使用するデバイスに合わせてインクルードするヘッダファイルを選択すること
#include "PAN3101.h"
// #include "ADNS2051.h"
// #include "ADNS2610.h"
// #include "ADNS2620.h"
// #include "ADNS2083.h"
//ピン割り当て
#define SCLK 2
#define SDIO 3
//PAN3101デバイス作成
PAN3101 Optical1 = PAN3101(SCLK, SDIO);
// ADNS2051 Optical1 = ADNS2051(SCLK, SDIO);
// ADNS2610 Optical1 = ADNS2610(SCLK, SDIO);
// ADNS2620 Optical1 = ADNS2620(SCLK, SDIO);
// ADNS2083 Optical1 = ADNS2083(SCLK, SDIO);
//マウスの現在値
signed long x = 0;
signed long y = 0;
void setup()
{
//シリアルポートを初期化
Serial.begin(38400);
//マウスセンサ初期化
Optical1.begin();
}
void loop()
{
signed char tx, ty;
//最後のモーションステータスを取得(PAN3101とADNS2051のみ対応)
//Optical1.updateStatus();
//注意事項
//updateStatusコマンドを使う場合、
//PAN3101.hのDelta_Yを0x18に、Delta_Xを0x17に変更すること。
//モーションステータスビットがセットされていれば
//if (Optical1.motion())
{
//dX/dYレジスタを読み出して現在値に加算する
//dX/dYレジスタには前回読み出してからの相対値が格納されている
//dX/dYレジスタは8bit(-127〜128)なのでオーバーフローする前に読み出すこと
tx = Optical1.dx();
x += tx;
ty = Optical1.dy();
y += ty;
//dX/dYレジスタに値がセットされていれば
if (tx || ty)
{
//現在値をmmに変換してシリアルポートに出力する
Serial.print("x=");
Serial.print((25.4 * (float)x) / 800.0);
Serial.print("mm y=");
Serial.print((25.4 * (float)y) / 800.0);
Serial.println("mm");
}
}
}
スケッチをアップロードしシリアルモニタを開くとマウスの移動した距離が次のように出力されます。x=46.99mm y=5.11mm
x=47.05mm y=5.02mm
x=47.05mm y=4.95mm
x=47.09mm y=4.86mm
x=47.12mm y=4.79mm
x=47.15mm y=4.70mm
x=47.15mm y=4.64mm
x=47.18mm y=4.57mm
x=47.18mm y=4.54mm
x=47.21mm y=4.51mm
今回使用したマウスは2007年頃の製品で同じICを使ったマウスを手に入れるのは難しいと思います。けれども安いマウスはどれも同じようなセンサーを使っていると思うので取りあえず光学式マウスを見つけたらバラしてICの型番を確認してみてください。そしてGoogleで検索すればきっと対応するライブラリが見つかると思います。参考リンク
PAN3101
http://www.pixart.com.tw/upload/PAN3101_V10_20051121170653.pdf
Interfacing an optical mouse sensor to your Arduino
http://www.martijnthe.nl/2009/07/interfacing-an-optical-mouse-sensor-to-your-arduino/
↓最近は青色LEDを採用した光学式マウスが主流になってきているみたいですね。
iBUFFALO 有線BlueLEDマウス Mサイズ レッド BSMBU16MRD
posted with amazlet at 15.01.07
バッファロー (2013-06-28)
売り上げランキング: 745
売り上げランキング: 745
↓いわゆるPCゲーマー向けのマウスは高速・高解像度のセンサを搭載したモデルが多いようです。こいつも1度バラしてみたい。
LOGICOOL ゲーミングマウス G300r
posted with amazlet at 15.01.07
ロジクール (2013-04-19)
売り上げランキング: 83
売り上げランキング: 83
Ads by Google
6 Comments
専用ドライバ無しで動くタイプ(Windows準拠のドライバで動く)マウスならUSB経由の出力信号がほぼ同じです。
使用するドライバについてはオンラインマニュアル等に明記されているので、判断基準として良いかと。
ただ、USBを経由しない場合はどうなるか・・・試して無いので分かりませんが。
今回のコレ、ちょうどやりたかった事なので、助かりました。
実際にやりたいのは、2つ使って搭載機体の回頭速度と方向から現在の機体の向きを取得することですが。。。
とりあえず、どうにかなりそうです。GPSとあわせて、方位をきっちり出せるようにしてみます。
ありがとうございました!!
使用するドライバについてはオンラインマニュアル等に明記されているので、判断基準として良いかと。
ただ、USBを経由しない場合はどうなるか・・・試して無いので分かりませんが。
今回のコレ、ちょうどやりたかった事なので、助かりました。
実際にやりたいのは、2つ使って搭載機体の回頭速度と方向から現在の機体の向きを取得することですが。。。
とりあえず、どうにかなりそうです。GPSとあわせて、方位をきっちり出せるようにしてみます。
ありがとうございました!!
このコメントは管理人のみ閲覧できます
Arduino Leonardoを組み合わせれば可能だと思います。
https://www.switch-science.com/catalog/968/
http://ht-deko.com/arduino/leonardo.html
https://www.switch-science.com/catalog/968/
http://ht-deko.com/arduino/leonardo.html
Leave a reply
該当の記事は見つかりませんでした。