ロータリーエンコーダー対応方法
考え方など基本は同じですので、TekuRobo工作室
ロータリーエンコーダーを使う を見てください
まずここをみればロータリーエンコーダーがわかるはずです。
上記HPにロータリーエンコーダー出力信号などについて説明が詳しくあります。
そこで出力信号の説明などがされているのですが、最終的には3048Fののタイマー機能を使いそこに設定として放り込むだけで出来ています。
見てみると
P1.DDR = 0xff; /* portB出力に設定 表示LED */
ITU.TMDR.BIT.MDF = 1; /* ITU2 位相係数モード */
ITU.TSTR.BIT.STR2 = 1; /* カウント開始 */
while(1){
P1.DR.BYTE = ITU2.TCNT; /* P1にカウント状態を出力 */
}
}
最初から3048Fにはロータリーエンコーダーに対応した、位相計数モードがついているのです!
3664Fでややこしいロータリーエンコーダー信号の判定をどうしようかと考えているとき、最初見て、ガク然としました。。。。わずか数行のプログラム。
3664Fにはそんな機能はない・・・・
機能がないからといって出来ないわけではないので、ロータリーエンコーダー出力信号を適切に読み取るプログラムを作成します。
なんでもマイコン機能に頼らず、自分でやることがそのぶん技量になります。。。(と言い聞かせましょう、 しかしこういうことの積み重ねがホントに技量になるはずです)
ロータリーエンコーダーの回転方向判別
TekuRobo工作室をみればわかるようにロータリーエンコーダーの出力信号は2本、
各 1か0
つまり2ビットの信号です。この2ビットの情報で回転方向を判別することになります。
ロータリーエンコーダーを試す
秋月にあるロータリーエンコーダーを使用します。
ロータリーエンコーダーはこんな出力信号ですよ、と説明されるより触って見て確かめましょう。
ロータリーエンコーダーにLEDを接続してみました。
つまみを回転させるとLEDがついたり消えたりします。
こんな感じの出力信号になると思えばわかりやすいです。
単に、キザミ角で接続がつながるというだけ。(このエンコーダー、、、回すとクボミでとまりやすく、
その中間でも信号は出力しますが止めにくいですね)
ロータリーエンコーダーの回転方向判定
出力信号は上記HP ロータリーエンコーダーを使う などをみればわかります。
さて、回転方向の判定をどうするか考えるといろいろな方法が考えられて、どれが簡単で、負担が少なく処理としては適切なのか、頭がかゆくなってきます。
どんな方法がいいかと考えると、秋月回路図集にも解説があり、わかりやすく、シンプルなのでコレを参考にさせていただきました。
秋月通商のキットにある、ロータリーエンコーダーの判定式を使用してみることにしました。
ロータリーエンコーダーの出力
ロータリーエンコーダーの出力は2本、2ビットですが、これだけでは回転方向の判別はできず、
1つ前の状態 → 現在の状態 (ビットの立ち上がり、立下り)
と1つ前の状態からの変化が必要になります。
つまり、ビットの状態を記憶しておく必要があり、その記憶値と、今読み取った入力値を比較することになります。
1つ前の状態 → 現在の状態 の2つの情報から、回転方向を判定します。
(記憶値) → (今読み取った入力値)
これを以下の判別式で回転方向を判定します。
回転方向判別式
ロータリーエンコーダーのプルアップした出力信号は 以下のように変わっていきます。
(1).時計回りに回した場合、出力信号は 図中のように
0 → 1 → 1 ・・・
0 0 1 ・・・
に変化していきます。
回転方向判別式D
D = ( F(t0) << 1 ) + F(t1) )
F(t0) : 1つ前の状態 << : ビットシフト
F(t1) : 現在の状態 + : 足し算
1つ前の状態F(t0)をビットシフトして、現在の状態F(t1)と足します。
その結果はこのようになります。
(1)時計回りの場合
F(t0) F(t1)
D0 = ( 00 << 1 ) + 01 = 01 → (10進数で) 1 .
D1 = ( 01 << 1 ) + 11 = 01 → (10進数で) 1
D2 = ( 11 << 1 ) + 10 = 00 → (10進数で) 0
D3 = ( 10 << 1 ) + 00 = 00 → (10進数で) 0
(2)反時計回りの場合
D0 = ( 00 << 1 ) + 10 = 10 → (10進数で) 2
D1 = ( 10 << 1 ) + 11 = 11 → (10進数で) 3
D2 = ( 11 << 1 ) + 01 = 11 → (10進数で) 3
D3 = ( 01 << 1 ) + 00 = 10 → (10進数で) 2
この判別式の結果
- 時計回りのとき 2ビット目が 0
- 反時計回りのとき 2ビット目が 1
となります。この2ビット目で回転方向を判定します
プログラムでは10進数で判定することになるので
- 時計周りのとき 判別式の結果が 10進数で 1以下
- 半時計周りのとき 判別式の結果が 10進数で 2以上 になります。
そして、タイマー割り込みで定期的に ビットの状態を監視して、変化していれば判別式を適用。
ロータリーエンコーダーの仕様書をざっと見ると、5kΩでプルアップした場合
チャタリング時間が2msとありました。ここでは回路でチャタリング対策はしないので、
割り込み間隔を 3ms にしたいと思います。
回した回転角度は カウンタ変数を用意し、
- 時計回りの回転検出するたび + 1(インクリメント) をして累積
- 反時計回りの回転検出するたび - 1(デクリメント) をして累積
していくと カウンタ変数で回転角度がわかることになります。
- twtter
- google+
- hatena