2014年07月12日

Raspberry Piでロータリーエンコーダーの動作確認

Raspberry Piで秋月電子で販売されているロータリーエンコーダー(EC12PLRGBSDVBF-D-25K-24-24C-61)の動作確認を行いました。

ロータリーエンコーダーの接続

ロータリーエンコーダーとは以下の通り接続を行いました。GPIOはプログラムでプルアップしています。

[RE]  - [RaspberryPi]
Cpin  -  14pin(GND)
Apin  -  11pin(GPIO17)
Bpin  -  12pin(GPIO18)

プログラミング

プログラムではwiringPiのwiringPiISR関数を使用しました。この関数はGPIOのレベルが変化した際に指定した関数を呼び出す事ができ、ロータリーエンコーダーの回転に合わせたイベント処理が可能となります。
また、使用したロータリーエンコーダーはクリック機能が付いています。GPIOをプルアップすることにより、何もしていない時はA端子・B端子共にLレベルとなります。回転させるとA端子とB端子がそれぞれHレベルになり、次のクリック位置になると両方ともにLレベルに戻ります。右回転と左回転を識別するには、A端子とB端子のイベントが起こる順番を識別することで可能となります。

#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>

int a;
int b;
int p_a;
int p_b;
int num;

void click_a(void){
        int _a;
        _a = digitalRead(0);//GPIOの値を取得。
        if(_a != a){ //同じ値が連続した場合にスキップする。
                if(a == 1){ //一つ前のA端子の値を格。
                        p_a = 1;
                }else{
                        p_a = 0;
                }
                a = _a;
                //a端子とb端子の直前の値が1であり、今の値が0である場合にTRUE。
                if(a == 0 && b == 0 && p_a == 1 && p_b == 1){
                        printf("right %d\n", ++num);
                }
        }
}
void click_b(void){
        int _b;
        _b = digitalRead(1);
        if(_b != b){
                if(b == 1){
                        p_b = 1;
                }else{
                        p_b = 0;
                }
                b = _b;
                if(a == 0 && b == 0 && p_a == 1 && p_b == 1){
                        printf("left  %d\n", --num);
                }
        }
}

int main(void){
        int setup = 0;
        a=1;
        b=1;
        p_a=0;
        p_b=0;
        num=0;
        setup = wiringPiSetup();
        pullUpDnControl(0, PUD_UP);
        pullUpDnControl(1, PUD_UP);
        wiringPiISR(0, INT_EDGE_BOTH, click_a);
        wiringPiISR(1, INT_EDGE_BOTH, click_b);
        while(setup != -1){
                sleep(1);
        }
}