[ESP32]ロータリエンコーダ(KY-040)with Arduino IDE

ESP32

[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)

ESP32 Development Board ESP-32S NodeMCU-32S MICRO/TYPE-C Wireless Module WiFi+Bluetooth ESP-WROOM-32 IOT Expansion Board - AliExpress 502
Smarter Shopping, Better Living! Aliexpress.com

電子工作ステーション https://electronicwork.shop/items/64134541d91711003035a5a6

ロータリエンコーダ(KY-040)

ジャンパーワイヤー(メスーメス)

電子工作ステーション https://electronicwork.shop/items/637f92415988dc5175f8a9ec

作業内容

配線図

KY-040 とは GPIO 21,GPIO 22,GPIO 23 を使用して接続します。

KY-040ESP32開発ボード(38Pin)
GNDGND
+3.3V or 5V
SWGPIO 23
DTGPIO 22
CLKGPIO 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");
動作確認

時計周りにロータリを動かすと、ポジションカウンタが増加していき、半時計周りに動かすとポジションカウンタが減少していきます。
また、ロータリを押し込むと、ポジションカウンタがクリアされます。

おわりに

コメント

タイトルとURLをコピーしました