かみやんの技術者ブログ

主にプログラムの話です

ロータリエンコーダの実験

さて、昨夜は、ロータリエンコーダマイコン H8/3069を接続するハーネスを作ってオシロスコープ スティングレイ(Stingray:アカエイ)(秋月のこれ)で、みてみました。


上記が試験用のパターン板


上記が36分割。


上記が72分割。


上記が144分割。


上記が288分割。

回す前から288分割は、幅が狭すぎてダメだろうを思っていましたが、案の定ダメでした。
フォトリフレクタは、透過型フォトインタラプタとは違って発光と受光で軸がずれるので細いパターンでは認識できないのです。透過型は軸が一致しているので指向性の高い発光器にできる。
あと当然ですが、黒のときの電圧0V、白のときの電圧2.4Vな訳で、フォトリフレクタがその間にあるときは当然その間の電圧になるので、完全に黒、完全に白の幅がなければ0Vと2.4Vを往復しない。

次にマイコンでの取り込みですが、下記が考えられるかなと。

  1. マイコンのタイマ機能を使ってカウントする
  2. マイコンの割り込み機能を使ってカウントはソフトウェアで行う
  3. A/D変換ポートにセンサの電圧を定期的に取り込み、ソフトウェアでカウントする

1)はほぼソフトウェアが不要で、2)は軽い、3)は恐らく実用的な速度でカウントできない。
ということでタイマ機能を使うことにした。

H8/3069Fは16ビットタイマが3本あるが、すでにモータを回すためにPWM用として2本使ってしまっている。ロータリエンコーダも2つなので残り1本では足りない。
8ビットタイマをデータシートで調べると、8ビットタイマは4本ある。
が、外部クロック取り込みポートのTCLKCとTCLKDはPWM0ポートと共有なのですでに使ってしまっている。
という訳で8ビットタイマとしてはTimer1と3がつかえる(しか使えないというか、0と2はPWM側をPWM0ではなくPWM2に変えればよいが)。
という訳で、早速コーディング。

//ロータリエンコーダ初期化
void InitializeRotaryEncoder()
{
	//8bit Timerの1と3を使う Timer1はTCLKA、Timer3はTCLKBが入力
	//タイマコントロールレジスタ 割り込みなし、カウンタクリアなし、外部クロックTCLKAの両エッジ
	sil_wrb_mem((VP)(H88TCR1), H88TCR_CKS2 | H88TCR_CKS1 | H88TCR_CKS0);//ch1
	sil_wrb_mem((VP)(H88TCR3), H88TCR_CKS2 | H88TCR_CKS1 | H88TCR_CKS0);//ch3
}

//ロータリエンコーダの値取得
uint8 GetRotaryEncoder(RotaryEncoderID id)
{
	if(id==ROTARY_L){//左
		return sil_reb_mem((VP)ROTARY_L_TIMER);
	} else {//右
		return sil_reb_mem((VP)ROTARY_R_TIMER);
	}
}

あっさりカウントできたが、取りこぼしや、カウントしすぎがあるかどうか、現状わからない。
パターン板が上下方向(センサ距離方向)に1cmぐらいガンガンぶれているので、カウント漏れがあると思われる。
カウントが正しいかどうかは、別の回転計(テスターみたいなやつ)とかも売っているが、このために買うのはもったいない。
という訳でロボットを作って走らせた時に、走った距離であっているかどうか調べるとしよう。

#あーちきしょう。PCのHDDが壊れた。WinXP,VistaでみれないがなぜかMacでみれたのでMacからコピー中。ここ2週間で3度目のデータ引っ越しだ。丸3日つぶしている。。