やること
Arduinoでロータリーエンコーダを使います。
2,3ピンはI2Cで使用したいので、今回は9,10ピンを使った割り込み処理を試します。
ロータリーエンコーダの信号読み取りはライブラリの Encoder Library を利用します。
ロータリーエンコーダーとは?
回転量を信号に置き換える電子部品です。時計回り、反時計回りも検出できます。
ボリュームと違って360度以上、何回転でもグルグルと回せるのが良いところです。
絶対値を出力するアブソリュート型と相対的な回転量をパルスで出力するインクリメンタル型があります。
今回使うEC10Eはインクリメンタル型です。
準備物・実施環境
- Arduino系のもの(今回はMICRO。UNO R4の場合の注意は最後の方に)
- ロータリーエンコーダ 秋月で1個50円のEC10E
- ライブラリ Encoder,TimerOne, MsTimer2


接続

この接続方法は簡易的なものです。
よりよい結果を出すためのフィルタ回路例も公式にあります↓
https://tech.alpsalpine.com/prod/j/html/encoder/incremental/ec10e/ec10e_common.html
プログラム
Arduino系のスケッチその1:MsTimer2 を使う場合
#include <MsTimer2.h> //タイマーライブラリの読み込み
#include <Encoder.h> //ロータリーエンコーダライブラリの読み込み
Encoder myEnc(9, 10); //ロータリーエンコーダ信号に使うピンを9,10に設定
volatile long oldPosition = -999; //割り込み処理で使う変数はvolatileにすると安心
volatile long newPosition = 0;
void RotEnc() { //割り込み処理の関数
//ライブラリで得たロータリーエンコーダの数値をキープするだけ
newPosition = myEnc.read();
}
void setup() {
Serial.begin(115200);
//割り込み処理の設定
MsTimer2::set(1, RotEnc); //1ms(ミリ秒)で設定
MsTimer2::start();
}
void loop() {
//ロータリーエンコーダの数値が変化した時だけシリアルに出力
if (newPosition != oldPosition) {
oldPosition = newPosition;
Serial.println(newPosition);
}
}
割り込み速度が1msなので手で回す分には十分使える分解能です。
でも他の処理に影響が出るかも?
Arduino系のスケッチその2:TimerOne を使う場合
#include <TimerOne.h> //高性能なタイマーライブラリの読み込み
#include <Encoder.h>
Encoder myEnc(9, 10);
volatile long oldPosition = -999;
volatile long newPosition = 0;
void RotEnc() {
newPosition = myEnc.read();
}
void setup() {
Serial.begin(115200);
Timer1.initialize(25); //25μs(マイクロ秒)で設定
Timer1.attachInterrupt(RotEnc);
}
void loop() {
if (newPosition != oldPosition) {
oldPosition = newPosition;
Serial.println(newPosition);
}
}
25μs(40kHz)で値を取得します。これぐらいあるとロータリーエンコーダ的には安心ですが、割り込み回数が多くなるのでやっぱり他の処理に影響が出るかも??
実行
スケッチをArduinoに書き込んだらそのままシリアルモニタを開きます。
うまくいけばロータリーエンコーダをクリクリと回した分だけ、シリアルモニタに数値が表示されます。回転方向により、数値が増えたり減ったりします。
ところで何がしたかったのか
廉価な倒立振子を試作しようとしていて、ロータリーエンコーダーが必要になりました。
ミニ四駆用のギアは歯の大きさがタミヤの工作シリーズのギアボックスのものと噛み合うので、3Dプリンタなどと組み合わせれば下記のようにホイールの回転量を調べることができます。
EC10Eはクリックが重いので、金属の板を一旦外し、クリック用の突起を万力で挟んでたいらにしてから使っています。
これちゃんと動くのか
Encoder Libraryの解説文にある「Low Performance Polling Mode」としての使用になります。
プログラムのところにも書きましたが、割り込み回数を増やすことで精度をアップしようとしているので、他の処理との関係がうまく行くかちょっと心配です。
手元ではI2Cやシリアル書き込みと同居できているようですが、処理を書き足していくうちに不具合が生じるようになるかもしれません。
Arduino UNO R4の場合
Arduino UNO R4では内部処理が変わってしまったようで、2023年10月時点では前述のライブラリが動かないようです。下記のライブラリであれば動くようですのでお試しください。
https://reference.arduino.cc/reference/en/libraries/rotaryencoder/
参考URL
下記のサイト/記事を参考にさせていただきました。