第七章 走行距離を測定する


光学マウスを解体


手元に古いこんなマウスがあった。
裏側はこんな感じ。
USBケーブルをカッターなどで中の線材を取り出す。
レンズ部分を接着させるために両面テープを両方につけておくと取れにくい。
接着後
ICの2,3,4,5番ピンに予備はんだをする。
力がかかって半田付け部分が取れにくくするために穴などに通しておくと安全。
信号のチェック用にブレッドボードを用意してここまでが正しかったかをチェックする。
USBケーブルを用いる場合は5VはCN10の24ピンに出ている。
光学マウスを解体して、信号を取り出し、これを用いて走行距離を求める。
裏から信号を取る場合。
裏だと配線が邪魔になるので、表から信号を貰う方が安全である。
新しい光学マウスだと直接USB出力になっていたりするので、古めのマウスを用いる。
オシロスコープを用いてX方向の情報のピンとY方向の情報のピンを探した結果、写真の4つのピンであるらしいことが分かった。

ICの信号について
1番ピンがGND JP3 青(J1)
2番   X1  左X1が先  橙色
3番   X2        黄色
4番   Y1        緑色
5番      Y2  前進Y1が先 白色

J1
1 +Vdd(5V)         白色
2 GND           青色

CPUへの接続
橙色------P50(CN10-20) 割り込みWkp0
黄色------P74(CN10- 8) 方向読み取り用
緑色------P51(CN10-19) 割り込みWkp1
白色------P70(CN10- 5) 方向読み取り用
C言語でマウスの信号が正常かテストする
前進方向のエンコーダーの値が読めているかどうかのチェックをします。
同様に他の信号もチェックしておくといいでしょう。
マウスを前後させると緑のLEDがチカチカするはずです。
床からの距離が微妙なので、どの位置が最適かをこの時点で決定しておきましょう。
チェックですから割り込みは用いません。

main.c
#include "iodefine.h"
#include "vs-wrc003.h"

void main(void);
void startInit(char* str);

void main(void)
{
  startInit("mouse encoder test\n");
  IO.PCR5 &= ~2;   // P51を入力に設定
  while(1){
    LED(IO.PDR5.BIT.B1);
  }
}

void startInit(char* str)
{
  const BYTE MainCycle = 60;
  Init((BYTE)MainCycle);  //CPUの初期設定
  InitSci3(CBR_115200,non,1);
  Mtr_Run(0,0,0,0);
  LED(1);                // 緑
  while(!getSW() );
  printf(str);
  LED(0);
}
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 P51のビットのみ0にする。
11 
12 P51の入力したデータをそのままLEDに送る。
13 緑のLEDが動きに応じてチカチカするはず。
14 
15 
16
17 
18 
19 
20 
21 

C++言語でマウスの信号が正常かテストする
main.cpp
#include "common.h"
#include "primary.h"

void main(void);
BYTE getSW();        //スイッチ読み込み
void startInit(char* str);

void main(void)
{
  startInit("mouse encoder test\n");
  Port forward(CPU.port5, 1);
  forward.setInput();   // P51を入力に設定
  while(1){
    LED(forward.readPin());
  }
}

void startInit(char* str)
{
  init();
  LED(1);  // 緑
  while(!getSW() );
  LED(0);
  printf(str);
}
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 P51ポートのオブジェクトを作る
12 P51のビットを入力に設定する。
13 P51の入力したデータをそのままLEDに送る。
14 緑のLEDが動きに応じてチカチカするはず。
15 
16
17 
18 
19 
20 
21 

方向の情報を用いて距離を求める。
前進距離を測定する
void main(void)
{
  startInit("mouse encoder test\n");
  Port forward(CPU.port5, 1);
  Port direction(CPU.port7, 0);
  forward.setInput();   // P51を入力に設定
  direction.setInput(); // P70を入力に設定
  int distance=0, before=0;
  while(1){
    int choice=forward*2+direction;
    switch(choice)
    {
      case 0: if(before==1) distance++;
              else if(before==2) distance--;
              before=0;
              break;
      case 1: if(before==3) distance++;
              else if(before==0) distance--;
              before=1;
              break;
      case 2: if(before==0) distance++;
              else if(before==3) distance--;
              before=2;
              break;
      case 3: if(before==2) distance++;
              else if(before==1) distance--;
              before=3;
              break;
    }
    printf("%d\n",distance);
  }
}
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 beforeは一つ前の状態
 9 
10 現在の状態を求める
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 距離の表示
31 
32 


前後左右の距離を求める main.cpp
void main(void)
{
  startInit("mouse encoder test\n");
  Port forward(CPU.port5, 1);
  Port direction(CPU.port7, 0);
  Port Right(CPU.port5, 0);
  Port Left(CPU.port7, 4);
  forward.setInput();   // P51を入力に設定
  direction.setInput(); // P70を入力に設定
  Right.setInput();     // P50を入力に設定
  Left.setInput();      // P74を入力に設定
   
  int distance=0, before=0;
  int distance2=0, before2=0;
  while(1){
    switch(forward*2+direction)
    {
      case 0: if(before==1) distance++;
              else if(before==2) distance--;
              before=0;
              break;
      case 1: if(before==3) distance++;
              else if(before==0) distance--;
              before=1;
              break;
      case 2: if(before==0) distance++;
              else if(before==3) distance--;
              before=2;
              break;
      case 3: if(before==2) distance++;
              else if(before==1) distance--;
              before=3;
              break;
    }
    switch(Left*2+Right)
    {
      case 0: if(before2==1) distance2++;
              else if(before2==2) distance2--;
              before2=0;
              break;
      case 1: if(before2==3) distance2++;
              else if(before2==0) distance2--;
              before2=1;
              break;
      case 2: if(before2==0) distance2++;
              else if(before2==3) distance2--;
              before2=2;
              break;
      case 3: if(before2==2) distance2++;
              else if(before2==1) distance2--;
              before2=3;
              break;
    }  
    printf("%d %d\n",distance,distance2);
  }
}
 1 上省略
 2 
 3 
 4 ポート設定
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 前後方向
14 左右方向
15 
16 前後方向
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 左右方向
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 


光学マウスで走行距離を測定する



以下のプログラムは割り込みのみで距離を求めている。大概の場合これで問題はないが、正確にしたい場合は、ポートの値を読む必要がある。

設定の部分
上省略
#include "interruptClass.h"
extern int wkCount, wkCount2, wkThermo, wkcnt[];
extern BYTE intKind;
void startInit(char* str);
BYTE getSW();        //スイッチ読み込み
void main()
{
  startInit("\n*** wkp interrupt test ****\n");
  interruptClass wkp;
  wkp.setWkpInt(0, 1);
  wkp.setWkpInt(1, 1);
  Port X1 = Port(CPU.port7, 4);
  Port Y1 = Port(CPU.port7, 0);
  X1.setInput();
  Y1.setInput();
  I2CLCD display;
  IrDistance robo;
  wkp.enable();
  wkCount=wkCount2=0;
  int diffx, diffy,oldx=0,oldy=0;
  char buff[15];
  robo.setForward();
  robo.setHighTime(robo.Ach, 0x4000); // 左
  robo.setHighTime(robo.Bch, 0x4000); // 右
  while(true)
  {
    diffx = oldx-wkCount;
    diffy = oldy-wkCount2;
    if(diffx != 0 || diffy !=0) {
      display.home();
      sprintf(buff,"%5d%5d", wkCount, wkCount2);
      display.write(buff);
      oldx = wkCount;
      oldy = wkCount2;
    }
    if(getSW())
    {
      oldx = wkCount=0;
      oldy = wkCount2=0;
    }
    CPU.delay(10000);
  }
}
 1 
 2 
 3 X及びY方向のカウンタなど
 4 割り込みの種類
 5 
 6 
 7 
 8 
 9 
10 割り込みオブジェクト
11 bit0を立ち上がりで割り込むように設定
12 bit1を立ち上がりで割り込むように設定
13 もう一つのXの状態を読むオブジェクト
14 もう一つのYの状態を読むオブジェクト
15 入力に設定する
16
17 LCDディスプレイオブジェクト
18 距離センサオブジェクト
19 割り込み許可
20 カウンタの初期化
21 
22 LCDディスプレー用バッファ
23 ロボットを前進させる設定
24 スピード設定
25
26 ここから全ての処理スタート
27
28 xの移動距離
29 yの移動距離
30 マウスがどちらかに移動したらば
31 LCDディスプレーをクリア
32 
33 カウントを表示
34 カウントを記憶
35 
36 
37 CPU基板上のスイッチが押されたら
38 
39 距離データをクリアする
40 
41 



重要
ヘッダファイルとライブラリのダウンロード
中身を全部プロジェクト・フォルダの中に入れて、serial.cをHEWでファイル追加する。

もう一つのマウスの解体

第八章に行く    ホームに戻る