使用Arduino开发板连接ec11旋转编码器

使用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的串口监视器,按下复位一次(不按应该也可以),可以看到有输出,旋转编码器,可以看到数据发生变化)在这里插入图片描述

如果为了好连接,可以购买下图(为了省事,图来自网络,如有侵权,请联系我,立删)这种,比较好连接)在这里插入图片描述
我的运行输出:
在这里插入图片描述
中间一列是转动转编码器的数据变化显示,最左边一列是未按下开关时的初始值。
至此,分享结束,我非专业人士,我也不是很精通,有问题欢迎评论讨论。
转载请注明出处

可以使用以下步骤来实现: 1. 连接EC11旋转编码器和57步进电机到Arduino板上。EC11旋转编码器一般有3个引脚,包括正极(+)、负极(-)和信号引脚(SW)。57步进电机一般有4个引脚,包括A+、A-、B+和B-。 2. 在Arduino IDE中编写代码。代码需要包括两个函数:一个函数用于读取旋转编码器旋转方向,另一个函数用于控制57步进电机的旋转方向和步数。 3. 在代码中定义旋转编码器的引脚和步进电机的引脚。这样可以让代码更加清晰易懂。 4. 在代码中初始化旋转编码器和步进电机。初始化包括将引脚模式设置为输入或输出,以及将步进电机的初始位置设置为0。 5. 在代码中编写循环函数,用于不断读取旋转编码器旋转方向,并根据旋转方向控制步进电机的旋转方向和步数。循环函数可以使用Arduino的delay函数来控制每次旋转的时间。 下面是一个简单的示例代码: ```c++ #include <Stepper.h> // 定义旋转编码器的引脚 const int ec11PinA = 2; const int ec11PinB = 3; const int ec11PinSW = 4; // 定义57步进电机的引脚 const int stepperPinA = 8; const int stepperPinB = 9; const int stepperPinC = 10; const int stepperPinD = 11; // 定义步进电机的步数和速度 const int stepsPerRevolution = 200; const int speed = 10; // 初始化步进电机 Stepper myStepper(stepsPerRevolution, stepperPinA, stepperPinB, stepperPinC, stepperPinD); // 初始化旋转编码器 int lastPosition = 0; int currentPosition = 0; void setup() { // 将旋转编码器的引脚设置为输入 pinMode(ec11PinA, INPUT); pinMode(ec11PinB, INPUT); pinMode(ec11PinSW, INPUT); // 将步进电机的引脚设置为输出 pinMode(stepperPinA, OUTPUT); pinMode(stepperPinB, OUTPUT); pinMode(stepperPinC, OUTPUT); pinMode(stepperPinD, OUTPUT); // 设置步进电机的初始位置为0 myStepper.setSpeed(speed); myStepper.step(0); } void loop() { // 读取旋转编码器旋转方向 int delta = readEncoder(); // 如果旋转方向不为0,控制步进电机旋转 if (delta != 0) { int steps = delta * 10; // 每次旋转10步 myStepper.step(steps); lastPosition = currentPosition; currentPosition += steps; } // 等待一段时间,再次读取旋转编码器 delay(50); } // 读取旋转编码器旋转方向 int readEncoder() { int delta = 0; int a = digitalRead(ec11PinA); int b = digitalRead(ec11PinB); if (a != b) { if (a == HIGH) { delta = 1; } else { delta = -1; } } return delta; } ``` 这个例子中,每次旋转编码器,步进电机就会旋转10步。你可以根据需要自行调整步数。同时,如果需要控制步进电机的左右旋转,可以根据步进电机的旋转方向来控制。例如,如果需要向左旋转,可以将步数设置为负数。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值