Arduinoで使えるロータリーエンコーダ用のライブラリーは、様々あります。
その中で私のお気に入りは、Ben Buxton氏のライブラリーで、GitHubからダウンロードできます。こちらからRotary-master.zipをダウンロードして、Arduino IDEでライブラリーに登録します。
サンプルスケッチで使い方を見てみましょう。まず、polling.inoです。
デジタルポートD2とD3にロータリーエンコーダのA,B端子を接続します。
Arduino Mini Proの場合の接続回路図です。
スケッチです。
----------------------------------------------------------------------------------------------------
#include <Rotary.h>
Rotary r = Rotary(2, 3);
void setup() {
Serial.begin(9600);
r.begin(true);
}
void loop() {
unsigned char result = r.process();
if (result) {
Serial.println(result == DIR_CW ? "Right" : "Left");
}
}
Rotary r = Rotary(2, 3);
void setup() {
Serial.begin(9600);
r.begin(true);
}
void loop() {
unsigned char result = r.process();
if (result) {
Serial.println(result == DIR_CW ? "Right" : "Left");
}
}
-----------------------------------------------------------------------------
このスケッチは、割込みを使わない方法で、プルアップは、ライブラリー内で行われます。ロータリーエンコーダを時計回りに回転させるとRight、反時計回りに回転させるとLeftとシリアルモニタに表示されます。
Arduino Mini Proを使用した場合の様子です。ロータリーエンコーダはAmazonで購入した中華製です。USBシリアル変換は、FT232RLです。
他のピンを使いたい場合は、Rotary r = Rotary(2, 3); の( )の中のピン番号を変更します。例えばD4とD5を使う場合は、Rotary r = Rotary(4, 5);とします。
次にピン変化割込みを利用するサンプルスケッチInterrupt.inoを書き込んで使ってみます。使用するピンは、前と同じです。
スケッチです。
-------------------------------------------------------------------------
#include <Rotary.h>
Rotary r = Rotary(2, 3);
void setup() {
Serial.begin(9600);
r.begin();
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
sei();
}
void loop() {
}
ISR(PCINT2_vect) {
unsigned char result = r.process();
if (result == DIR_NONE) {
// do nothing
}
else if (result == DIR_CW) {
Serial.println("ClockWise");
}
else if (result == DIR_CCW) {
Serial.println("CounterClockWise");
}
}
Rotary r = Rotary(2, 3);
void setup() {
Serial.begin(9600);
r.begin();
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
sei();
}
void loop() {
}
ISR(PCINT2_vect) {
unsigned char result = r.process();
if (result == DIR_NONE) {
// do nothing
}
else if (result == DIR_CW) {
Serial.println("ClockWise");
}
else if (result == DIR_CCW) {
Serial.println("CounterClockWise");
}
}
-------------------------------------------------------------------------
ロータリーエンコーダを時計回りに回転させると「ClockWise」、反時計回りに回転させると「CounterClockWise」とシリアルモニタに表示されます。
setup()内の
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
sei();
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
sei();
について説明します。
PCICRは、ピン変化割込み許可を設定するレジスタ(Pin Change Interrupt Control Register)です。
Arduinoのピンは、8ピンごとにPCIE0,PCIE1,PCIE2の3つのグループに分けられていて、どのグループの割込みを許可するかを設定します。
なお、各グループのピンは、ピンの名称で示すと
PCIE0 (D13,D12,D11,D10,D9,D8)
PCIE1 (RESET,A5,A4,A3,A2,A1,A0)
PCIE2 (D7,D6,D5,D4,D3,D2,D1,D0)
です。
今回D2とD3のピン変化を使いますので、グループは、PCIE2です。これをPCICRレジスタにセットするのが
PCICR |= (1 << PCIE2);
です。
次に、各グループのピンにうちどのピンの割込みを許可するかを設定するのが、PCMSKレジスタ(Pin Change Enable Mask Register)です。
このレジスタは、各グループごとにPCMSK0,PCMSK1,PCMAK2に分けられます。各レジスタで設定できるグループとPCINT名は、
PCMSK0 (PCIE0) (PCINT7,PCINT6,PCINT5,PCINT4,PCINT3,PCINT2,PCINT1,PCINT0)
PCMSK1(PCIE1) (PCINT14,PCINT13,PCINT12,PCINT11,PCINT10,PCINT9,PCINT8)
MCMSK0(PCIR0) (PCINT23,PCINT22,PCINT21,PCINT20,PCINT19,PCINT18,PCINT17,PCINT16)
それぞれ、上記のピンに対応しています。
今回のD2とD3は、PCINT18とPCINT19ですので、これらのピンの割込みを許可する設定は
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
となります。
次の行のsei(); で割込みを許可しています。
最後に、
ISR(PCINT2_vect) {
}
について説明します。
ISR(Interrupt Service Routine)は、割込み(今回はピン変化割込み)が発生した場合に呼び出される関数で、引数には、割込みの発生元を指定します。発生元とシンボルは
シンボル 発生元
INT0_vect D2ピンの外部割込み発生
INT1_vect D3ピンの外部割込み発生
PCINT0_vect PCIE0のピン変化が発生
PCINT1_vect PCIE1のピン変化が発生
PCINT2_vect PCIE2のピン変化が発生
です。
今回は、PCIE2のグループですので、シンボルはPCINT2_vectとなります。
この関数内に割込みが発生した時の処理を記入します。
他のピンを使う場合は、以上を考慮して割込みの設定をすることになります。