JH7UBCブログ

アマチュア無線 電子工作 家庭菜園など趣味のブログです

Arduino ロータリーエンコーダ その1

2020-12-21 21:50:09 | Arduino
 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");
}
}
-----------------------------------------------------------------------------
 このスケッチは、割込みを使わない方法で、プルアップは、ライブラリー内で行われます。ロータリーエンコーダを時計回りに回転させると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");
}
}
-------------------------------------------------------------------------
ロータリーエンコーダを時計回りに回転させると「ClockWise」、反時計回りに回転させると「CounterClockWise」とシリアルモニタに表示されます。


 setup()内の
PCICR |= (1 << PCIE2);
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となります。

 この関数内に割込みが発生した時の処理を記入します。

 他のピンを使う場合は、以上を考慮して割込みの設定をすることになります。


最新の画像もっと見る

コメントを投稿