[ESP32]ロータリエンコーダ(KY-040) with Arduino IDE
はじめに
KY-040 は、ロータリエンコーダです。
ロータリエンコーダと抵抗が基板上に接続されています。
つまみ部分を時計周りや半時計周りに回す動作や、押し込む動作を判別することができます。
音量調整などでよく使用されています。
KY-040 は、こちらのスターターキットの一部です。
開発環境
OS : Windows 11 Pro
ESP32:ESP-WROOM-32
統合開発環境 : Arduino IDE 2.3.2
Arduino core for the ESP32:2.0.17
使用ライブラリ:なし
使用パーツ
ESP32開発ボード(38Pin)
電子工作ステーション https://electronicwork.shop/items/64134541d91711003035a5a6
ロータリエンコーダ(KY-040)
ジャンパーワイヤー(メスーメス)
電子工作ステーション https://electronicwork.shop/items/637f92415988dc5175f8a9ec
作業内容
配線図
KY-040 とは GPIO 21,GPIO 22,GPIO 23 を使用して接続します。
KY-040 | ESP32開発ボード(38Pin) |
GND | GND |
+ | 3.3V or 5V |
SW | GPIO 23 |
DT | GPIO 22 |
CLK | GPIO 21 |
ライブラリインストール
なし
スケッチ作成
#define CLK_PIN 21
#define DT_PIN 22
#define SW_PIN 23
int PositionCount = 0;
int clkState;
int prev_clkState;
void setup() {
Serial.begin(115200);
pinMode(CLK_PIN, INPUT);
pinMode(DT_PIN, INPUT);
pinMode(SW_PIN, INPUT_PULLUP);
prev_clkState = digitalRead(CLK_PIN);
}
void loop() {
/* CLK_PINの状態を取得し前回値と比較 ⇒ 差異がある場合はロータリが動いたと判断 */
/* CLK_PINの状態とDT_PINの状態を比較 ⇒ 差異がある場合は時計回りに動いたと判断 */
/* 差異がない場合は半時計回りに動いたと判断 */
clkState = digitalRead(CLK_PIN);
if (clkState != prev_clkState) {
if (digitalRead(DT_PIN) != clkState) {
PositionCount++;
} else {
PositionCount--;
}
Serial.println("Encoder Position: " + String(PositionCount));
}
prev_clkState = clkState;
/* SW_PINの状態を取得しLOWである、かつポジションが0でない場合は、ポジションをクリア */
if (!digitalRead(SW_PIN) && PositionCount) {
PositionCount = 0;
Serial.println("Position Clear => 0");
}
}
コード説明
使用するGPIOピンを設定します。
#define CLK_PIN 21
#define DT_PIN 22
#define SW_PIN 23
使用するGPIOピンをそれぞれ設定します。
pinMode(CLK_PIN, INPUT);
pinMode(DT_PIN, INPUT);
pinMode(SW_PIN, INPUT_PULLUP);
CLK_PIN は、左右どちらでもロータリを動かした時に0と1を交互に変化します。
DT_PIN は、時計周りに動かした時は CLK_PIN とは違う値になり、半時計周りに動かした時は CLK_PIN と同じ値になります。
上記の動きを判断して、ポジションカウンタを増減させています。
/* CLK_PINの状態を取得し前回値と比較 ⇒ 差異がある場合はロータリが動いたと判断 */
/* CLK_PINの状態とDT_PINの状態を比較 ⇒ 差異がある場合は時計回りに動いたと判断 */
/* 差異がない場合は半時計回りに動いたと判断 */
clkState = digitalRead(CLK_PIN);
if (clkState != prev_clkState) {
if (digitalRead(DT_PIN) != clkState) {
PositionCount++;
} else {
PositionCount--;
}
Serial.println("Encoder Position: " + String(PositionCount));
}
prev_clkState = clkState;
SW_PIN は、押されたときに LOW となるため、LOW かつ ポジションカウンタが0以外の時にポジションカウンタをクリアする動作をさせています。
/* SW_PINの状態を取得しLOWである、かつポジションが0でない場合は、ポジションをクリア */
if (!digitalRead(SW_PIN) && PositionCount) {
PositionCount = 0;
Serial.println("Position Clear => 0");
動作確認
時計周りにロータリを動かすと、ポジションカウンタが増加していき、半時計周りに動かすとポジションカウンタが減少していきます。
また、ロータリを押し込むと、ポジションカウンタがクリアされます。
コメント