《ESP32 控制 Arduino 的旋转编码器实现》


前言

编码器(encoder) 是将信号(如 比特流 )或 数据 进行编制、转换为可用以通讯、传输和存储的信号形式的设备。. 编码器把角位移或直线位移转换成电信号,前者称为码盘 ,后者称为码尺。.

按照读出方式编码器可以分为接触式和非接触式两种;按照工作原理编码器可分为增量式和绝对式两类。. 增量式编码器是将位移转换成周期性的电信号,再把这个电信号转变成计数脉冲,用脉冲的个数表示位移的大小。绝对式编码器 的每一个位置对应一个确定的数字码,因此它的示值只与测量的起始和终止位置有关,而与测量的中间过程无关。

本文主要介绍旋转编码器在Arduino开发中的应用。

Arduino ESP32

  1. 旋转编码器

编码器接线图:

KY-040 模块包括两个内部上拉电阻,将引脚 CLK 和 DT 上拉到 VCC(+5V)。

引脚定义:

CLK

Rotary encoder pin A

DT

Rotary encoder pin B

SW

Push button pin. Normally openundefined shorted to GND on press

VCC

Voltage supply

GND

Ground

旋转编码器提供两种交互方式:

  • 旋转– 您可以通过单击箭头来旋转旋钮。上箭头顺时针旋转一级,下箭头逆时针旋转一级。旋转旋钮将在 DT 和 CLK 引脚上产生数字信号,如下所述。

  • 按钮– 单击旋钮以按下按钮。按下时,按钮将 SW 引脚与 GND 引脚连接起来。

  • 每次用户旋转旋钮时,它都会在 DT 和 CLK 引脚上产生一个 LOW 信号:

  • 顺时针旋转会导致 CLK 引脚首先变低,然后 DT 引脚也变低。

  • 逆时针旋转会导致 DT 引脚先变低,然后 CLK 引脚变低。

  • 两个引脚将在几毫秒内返回高电平。下图说明了这一点:

    使用wokwi仿真:

    #define ENCODER_CLK 4
    #define ENCODER_DT  2
    
    
    void setup() {
      Serial.begin(115200);
      pinMode(ENCODER_CLKundefined INPUT);
      pinMode(ENCODER_DTundefined INPUT);
    }
    
    
    int lastClk = HIGH;
    
    
    void loop() {
      int newClk = digitalRead(ENCODER_CLK);
      if (newClk != lastClk) {
        // There was a change on the CLK pin
        lastClk = newClk;
        int dtValue = digitalRead(ENCODER_DT);
        if (newClk == LOW && dtValue == HIGH) {
          Serial.println("Rotated clockwise ⏩");
        }
        if (newClk == LOW && dtValue == LOW) {
          Serial.println("Rotated counterclockwise ⏪");
        }
      }
    }
    

    但是在实际过程中,我们得到的效果并没有如仿真一样,编码器会发生抖动,读取时并不准确。

    在使用Arduino 开发ESP32设计旋转编码器程序时。

    使用到的库:BasicEncoder

    52a4562310de7839adb593c3417503b0.png

    跑一个测试程序试试:

    #include <Arduino.h>
    #include <BasicEncoder.h>
    
    
    const int8_t pinA = 2;
    const int8_t pinB = 5;
    
    
    BasicEncoder encoder(pinAundefined pinB);
    
    
    void setup() {
      Serial.begin(115200);
      Serial.println(F("Polling in loop()"));
    }
    
    
    void loop() {
      encoder.service();
      int encoder_change = encoder.get_change();
      if (encoder_change) {
        Serial.println(encoder.get_count());
      } 
      // Even a short delay here will affect performance.
      // Uncomment and change the delay to see what happens.
      //delay(10);
    }
    

     

    如果在编译过程中遇到报错,有提到SREG,那就在库函数里帮它定义一下。

    找到库所在的位置打开并进行修改,其他的坑我还没有碰到过。

    f64575df3187b73d065e6b349e5d2a7c.png

    至此,便可放心使用旋转编码器开发了。

    物联沃分享整理
    物联沃-IOTWORD物联网 » 《ESP32 控制 Arduino 的旋转编码器实现》

    发表评论