なんでも作っちゃう、かも。

Arduino/Make/フィジカルコンピューティング/電子工作あたりで活動しています。スタバの空きカップを使ったスタバカップアンプなど製作。最近はもっぱらArduinoと3Dプリンタの自作に興味があります。

Arduinoで光学式マウスのCMOSセンサーを乗っ取って移動距離を計測する

Posted by arms22 on 2015年01月07日 1  0

IMGP0612

昨年末の話。勤務先の大掃除の日にいらなくなった光学式マウスを頂戴してきたので、マウスに内蔵されているCMOSセンサーを使って移動距離を計測する実験を行いました。この記事ではArduinoを使ってセンサーから座標を取得し、マウスの移動した距離をシリアルモニタに出力する方法を紹介します。

IMGP0601

写真はマウスを分解したところ(マウスの型番は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線式シリアル
※CMOSカメラの画素数は不明。
※このICはカメラ映像を抜き出すことはできない様子。

IMGP0598

IMGP0597

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


ハードウェア


IMGP0617

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
バッファロー (2013-06-28)
売り上げランキング: 745


↓いわゆるPCゲーマー向けのマウスは高速・高解像度のセンサを搭載したモデルが多いようです。こいつも1度バラしてみたい。

LOGICOOL ゲーミングマウス G300r
ロジクール (2013-04-19)
売り上げランキング: 83

Ads by Google

1 Comments

says...""
専用ドライバ無しで動くタイプ(Windows準拠のドライバで動く)マウスならUSB経由の出力信号がほぼ同じです。
使用するドライバについてはオンラインマニュアル等に明記されているので、判断基準として良いかと。
ただ、USBを経由しない場合はどうなるか・・・試して無いので分かりませんが。

今回のコレ、ちょうどやりたかった事なので、助かりました。
実際にやりたいのは、2つ使って搭載機体の回頭速度と方向から現在の機体の向きを取得することですが。。。
とりあえず、どうにかなりそうです。GPSとあわせて、方位をきっちり出せるようにしてみます。
ありがとうございました!!
2015.04.13 12:44 | URL | #- [edit]

Leave a reply






管理者にだけ表示を許可する

該当の記事は見つかりませんでした。