前の記事のGPIO割込みを利用して、ロータリーエンコーダの回転方向を検出するテストをします。
回転方向の検出は、秋月電子でロ-タリーエンコーダを買うとついてくる説明用紙に出ている方法を使います。
ロータリーエンコーダのA端子とB端子をプルアップしておいて、エンコーダを回転させると各端子の電圧は、時計回り、反時計回りのとき、下の図のように変化します。
前のBAの値を1ビット左にシフトした値と現在のBAの値のXORをとり、下位2ビットだけ取り出すと時計回りのときは、0か1(2未満)であり、反時計回りのときは、2か3(2以上)です。このことを使って回転方向を判定します。
GPIO12とGPIO13を使います。回路図です。(内部でプルアップしますので、プルアップ抵抗は不要です)
テストしたスケッチです。
--------------------------------------------
/*
* ESP32 Rotary Encoder test
* 2020.1.31
* JH7UBC Keiji Hata
*/
#define ENC_A 12
#define ENC_B 13
volatile int old_value = 0x11;
volatile int value = 0;
volatile int D;
volatile int count = 0;
void setup() {
pinMode(ENC_A, INPUT_PULLUP); //内部でプルアップ
pinMode(ENC_B, INPUT_PULLUP); //内部でプルアップ
attachInterrupt(ENC_A, rotary, CHANGE); //GPIO割込みセット
attachInterrupt(ENC_B, rotary, CHANGE); //GPIO割込みセット
Serial.begin(115200); //シリアル通信初期化
}
void loop() {
}
//割込みサービスルーチン
void rotary(){
value = (digitalRead(ENC_B)<<1) | digitalRead(ENC_A);
if(old_value != value){
D = ((old_value << 1) ^ value) & 3;
if(D < 2){
count +=1;
}else{
count -=1;
}
if(count >= 4){
Serial.println("Right");
count = 0;
}else if(count <= -4){
Serial.println("Left");
count = 0;
}
old_value = value;
}
}
--------------------------------------------
時計回りのとき「Right」、反時計回りのとき「Left」とシリアルモニタに表示します。
ロータリーエンコーダを回してみます。
モニターの表示です。
回転方向と表示が逆の場合は、A,Bの配線を逆にします。
機械式ロータリーエンコーダには、チャタリングがありますので、回転と表示が若干ずれることがありますが、問題なく動作すると思います。
Arduinoのライブラリには、RotaryEncoderというものがあり、それを使う方法が簡単なのですが、使いにくい点もあるので、PICで使っている方法でテストしてみました。