摘要:本文介绍旋转编码器的使用方法
旋转编码器是一种机电设备,可将轴或轴的角位置或运动转换为模拟或数字输出信号,在工业控制中发挥着举足轻重的作用。旋转编码器目前被广泛的应用在数控机床、印刷设备、包装机械、输送带、电梯、机器人、风力发电、起重机、家用电器等领域,主要用于频率调节、速度调节、高度调节、温度调节及音量调节等的参数控制。
旋转编码器主要有两种类型:绝对编码器和增量编码器。
绝对编码器通过提供与运动相关的数据输出来反馈速度和位置信息。即使编码器断电,它们也能保持位置信息。编码器的位置在通电时立即可用。绝对编码器具有多个不同二进制权重的码环,然后通过多个不同位置和权重的码环的组合,就可以确定旋钮的当前位置。绝对编码器由机械位置决定的每个位置的唯一性,它无需记忆,无需找参考点,而且不用一直计数,什么时候需要知道位置,什么时候就去读取它的位置。这样,编码器的抗干扰特性、数据的可靠性大大提高了。需要注意的是,绝对编码器只能在一圈之内给出绝对位置。
增量编码器通过读取角位移的变化而不是读取编码轴的绝对角度来工作,在发生旋转时增量编码器将立即报告位置的变化情况。旋转增量式编码器以转动时输出脉冲,通过计数设备来知道其位置,当编码器不动或停电时,则需要依靠计数设备的内部记忆来记住位置。增量编码器不跟踪绝对位置。它们可能需要移动到固定参考点才能开始位置测量。旋转增量式编码器有两个信号A和B,当编码器轴旋转时发出方波两组脉冲信号。通过这两组脉冲不仅可以测量转速,还可以判断旋转的方向。
下图即为几种常用在家用电器中的旋转编码器。都是增量编码器。
下面就以上图中的第三种来介绍一下引脚的功能说明。其他的增量式旋转编码器和这个也是类似。
引脚 | 功能 |
CLK | 脉冲信号输出A |
DT | 脉冲信号输出B |
SW | 中间按键状态 |
+ | 电源正极。通常为+5V |
GND | 电源负极。 |
下面就来将旋转编码器连接到ESP32开发板上,然后用Mixly测试一下它的功能吧。这次要实现的功能是利用旋转编码器实现对舵机的控制。让舵机可以随着旋转编码器中间轴的旋转左右摆动,当按下中间按键的时候,舵机复位,回到90度的位置。旋转编码器电源的连接就不用说了,找到扩展板上的输出引脚,接上就行了。CLK和DT分别接到了P23和P22引脚。SW则接到了P21引脚。舵机在前面也讲过了,电源接好后,将其控制线接到P19引脚就行了。
下面就打开Mixly软件,选择“Arduino ESP32”。因为这种增量式的旋转编码器本身是无法记录码盘位置的,因此,先定义一个全局变量degree,用来记录编码器的位置,初始值为90度。如下所示:
在初始化的时候,需要完成2件事情。一件是初始化一个旋转编码器对象,指名其使用的引脚。然后是将管脚21设置为上拉输入的模式,用来获取旋转编码器中心轴的按下状态。在这里,之所以不选择普通的输入状态,是因为我的旋转编码器没有焊接上拉电阻,因此要使用上拉模式,才能正确的读取按键的状态(如果有上拉电阻,那么直接设置为输入就可以了)。旋转编码器的背部如下图所示:
初始化部分的功能实现如下图所示。
接下来就是定义旋转编码器的事件处理方法。当向右旋转时,degree增大,当向左旋转时,degree减小。当按键按下时,degree变成90度,让舵机回到中间位置。如下图所示:
最后,就是在主循环程序中,控制舵机转到degree指定的位置了。如下所示:
接下来,编译和上传程序,看看舵机是不是在旋转编码器的控制下可以左右摇摆了?
下面就来学习一下Mixly为自动生成的源代码,如下所示:
#include <ESPRotary.h> #include <OneButton.h> #include <ESP32_Servo.h>
volatile int degree; ESPRotary encoder1; OneButton button21(21,true); Servo servo_19;
void encoder1OnRightRotation(ESPRotary& encoder1) { degree = degree + 1; }
void encoder1OnLeftRotation(ESPRotary& encoder1) { degree = degree - 1; }
void attachClick21() { degree = 90; }
void setup(){ degree = 90; encoder1.begin(22, 23); encoder1.setStepsPerClick(2); pinMode(21, INPUT_PULLUP); encoder1.setRightRotationHandler(encoder1OnRightRotation); encoder1.setLeftRotationHandler(encoder1OnLeftRotation); button21.attachClick(attachClick21); servo_19.attach(19,500,2500); }
void loop(){ encoder1.loop(); button21.tick(); servo_19.write(degree); delay(10);
} |
在这里遇到了一个高级编程语言中很常见的一种事件处理机制——回调函数。回调函数是在中断的基础上演变而来的。其工作原理就是,事先定义一个事件处理函数,然后将该函数与触发的事件绑定到一起,之后,当该事件发生的时候,由系统自动的调用事件处理函数来。也就是在某个事件发生的时候,被系统自动调用的函数就是回调函数。
接下来看一下源代码的setup()函数中的如下3句代码:
encoder1.setRightRotationHandler(encoder1OnRightRotation);
encoder1.setLeftRotationHandler(encoder1OnLeftRotation);
button21.attachClick(attachClick21);
就是指定当旋转编码器向右旋转时,执行encoder1OnRightRotation()函数,当旋转编码器向左旋转时,执行encoder1OnLeftRotation()函数,当按键按下时,执行attachClick21()函数。对于其他的代码,这里就不再进行解释了,之前应该都见过了。