使用Arduino开发板连接ec11旋转编码器
因为最近要用到旋转编码器,从网上花了好长时间找了好多关于arduino使用旋转编码器的资料,总是找不到合适的,最后总结了一下(部分内容有借鉴,仅作分享,未作商用),分享给大家。
需要的元件:
杜邦线、arduino uno开发板、ec旋转编码器、面包板
首先了解一下编码器(附上几张ec11编码器的图)
旋转编码器的功能是什么呢:
首先旋转编码器是一种电子组件,能够在旋转时监视运动和位置。旋转编码器利用光学传感器,当旋转编码器旋转时,光学传感器可以产生脉冲。它能把被测的角位移直接转换成数字信号,可以分为增量型编码器和绝对型编码器。在本文中,我们将使用简单的增量式旋转编码器。
EC11编码器一共五条引线,当然两边还有两个角,那是用来固定的。五条引线分别是:
**下面三个:**A信号输出、B信号输出、GND(接地)
上面两个:一路开关信号输入,一路GND接地
具体看下图:
介绍一下编码器的工作原理:
编码器具有一个磁盘,该磁盘具有均匀分布的接触区,这些接触区连接到公共引脚C和两个其他单独的接触引脚A和B,如下所示。
当磁盘逐步开始旋转时,引脚A和B将开始与公共引脚接触,因此将产生两个方波输出信号。
如果我们仅对信号脉冲进行计数,则可以使用两个输出中的任何一个来确定旋转位置。但是,如果我们也要确定旋转方向,则需要同时考虑两个信号。
我们可以注意到,两个输出信号彼此之间相差90度。如果编码器顺时针旋转,则输出A将在输出B之前
因此,如果我们每次计算信号从高到低或从低到高变化的步数,我们就会注意到那时两个输出信号的值相反。如果编码器逆时针旋转,则输出信号具有相等的值。因此,考虑到这一点,我们可以轻松地对控制器进行编程以读取编码器位置和旋转方向。
**接下来我们进行arduino和ec11编码器的连接**
GND------GND
VCC------+5V
SW--------D4
DT(A信号输出)---------D3
CLK(B信号输出)------D2
我们的程序采用中断(可百度搜索arduino 的 attachInterrupt函数进一步了解)的方式,所以连接用了中断引脚(我们D2用来中断,D3 仅作为普通引脚):
#define encoder0PinA 2
#define encoder0PinB 3
#define encoder0Btn 4
int encoder0Pos = 0;
void setup() {
Serial.begin(9600);
pinMode(encoder0PinA, INPUT_PULLUP);
pinMode(encoder0PinB, INPUT_PULLUP);
pinMode(encoder0Btn, INPUT_PULLUP);
attachInterrupt(0, doEncoder, CHANGE);
}
int valRotary,lastValRotary;
void loop() {
int btn = digitalRead(encoder0Btn);
Serial.print(btn);
Serial.print(" ");
Serial.print(valRotary);
if(valRotary>lastValRotary)
{
Serial.print(" CW");
}
if(valRotary) {
Serial.print(" CCW");
}
lastValRotary = valRotary;
Serial.println(" ");
delay(250);
}
void doEncoder()
{
if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB))
{
encoder0Pos++;
}
else
{
encoder0Pos--;
}
valRotary = encoder0Pos/2.5;
}
**解释一下程序:**
第一部分当然是先定义要要连接的引脚
#define encoder0PinA 2
#define encoder0PinB 3
#define encoder0Btn 4
下面是启动串口通讯,并将引脚定义为输入上拉模式,当然还有中断函数attachInterrupt()用于启用D2的中断
void setup() {
Serial.begin(9600);
pinMode(encoder0PinA, INPUT_PULLUP);
pinMode(encoder0PinB, INPUT_PULLUP);
pinMode(encoder0Btn, INPUT_PULLUP);
attachInterrupt(0, doEncoder, CHANGE);
}
下面的程序是确定旋转编码器CW还是CCW的程序。当前的旋转编码器读数大于先前的旋转数据,然后表示为CW。而如果当前读数小于先前读数,则将其表示为CCW
void loop() {
int btn = digitalRead(encoder0Btn);
Serial.print(btn);
Serial.print(" ");
Serial.print(valRotary);
if(valRotary>lastValRotary)
{
Serial.print(" CW");
}
if(valRotary) {
Serial.print(" CCW");
}
lastValRotary = valRotary;
Serial.println(" ");
delay(250);
}
在下面的“ doEncoder”功能中,,如果DT和CLK(Arduino Uno的引脚)的值相同,则“ encoder0Pos”变量将增加,否则,“encoder0Pos”变量将减少。ValRotary值是已运行的步骤数的值。ValRotary值由旋转传感器编码器读数值除以2.5获得。从测试中获得2.5的值,因为旋转编码器的一个步长可能会超过1,所以根据每个步长以及读取延迟的增加将其值除以2.5。
void doEncoder()
{
if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB))
{
encoder0Pos++;
}
else
{
encoder0Pos--;
}
valRotary = encoder0Pos/2.5;
}
因为我的EC11旋转编码器没有焊片,所以在连接时不好连接,所以只连接测试了下面三个引脚,即A信号输出、B信号输出、和GND,测试运行没问题(连接好接线并烧入上面的程序后,打开arduino的串口监视器,按下复位一次(不按应该也可以),可以看到有输出,旋转编码器,可以看到数据发生变化)
如果为了好连接,可以购买下图(为了省事,图来自网络,如有侵权,请联系我,立删)这种,比较好连接)
我的运行输出:
中间一列是转动转编码器的数据变化显示,最左边一列是未按下开关时的初始值。
至此,分享结束,我非专业人士,我也不是很精通,有问题欢迎评论讨论。
转载请注明出处