旋转编码器的工作原理以及如何同Arduino开发板使用

网友投稿 2019-08-18 11:26

在本篇文章中,您将了解如何使用旋转编码器。首先,您将看到有关旋转编码器的一些信息,然后您将学习如何使用旋转编码器。

什么是旋转编码器?

旋转编码器是一种机电设备,可将轴角度的位置转换为数字数据。旋转编码器具有带有一些孔的圆形板和两个通道A和B。通过旋转圆形板,当A和B通道通过孔时,在该通道和公共端之间建立连接。这些中断在输出通道中产生方波。通过计算这些脉冲,我们可以找到旋转量。另一方面,通道A和B具有90度的相位差,因此您还可以根据前面的通道脉冲找到旋转方向。

https://cdn.china-scratch.com/timg/190820/1126464616-0.jpg

编码器可以直接安装在电机轴上,也可以作为模块安装。旋转编码器模块(包括5个引脚)是最常见的旋转编码器。2个引脚提供编码器电源,SW是模块上的按钮,CLK和DT显示A和B通道。

该模块的一些功能包括:

●     无限旋转

●     20脉冲分辨率

●     5V供电电压

https://cdn.china-scratch.com/timg/190820/11264C411-1.jpg

如何使用旋转编码器?

要使用旋转编码器,我们应该对通道A和B的脉冲进行计数。为此,我们使用Arduino UNO并制作了三个项目:定位编码器、控制LED灯以及控制直流电机的速度和方向。

https://cdn.china-scratch.com/timg/190820/11264L023-2.jpg

确定旋转编码器轴的位置

将编码器的+连接至5V,GND连接至GND引脚,CLK连接至引脚编号6,DT连接至引脚编号7。

您需要知道轴的位置才能使用编码器。轴的位置根据其旋转量而变化。顺时针旋转时,它从0变为无穷大,逆时针旋转则从0变为负无穷大。

上传以下代码到Arduino开发板中,然后在串行监视器中查看轴编码器的位置。您可以将此代码用于使用编码器的所有项目。

/*Rotary Encoder - get the position*/#define encoderOutA 6 // CLK#define encoderOutB 7 // DTint counter = 0;int State;int old_State;void setup() {pinMode (encoderOutA, INPUT);pinMode (encoderOutB, INPUT);Serial.begin (9600);//Read First Position of Channel Aold_State = digitalRead(encoderOutA);}void loop() {State = digitalRead(encoderOutA);if (State != old_State){if (digitalRead(encoderOutB) != State){counter ++;}else {counter --;}Serial.print("Position: ");Serial.println(counter);}old_State = State; // the first position was changed}old_State = State; // the first position was changed
}

要确定编码器位置,我们需要将通道A和B连接到Arduino的输入。我们在开头读取并保存通道A的初始值。然后,我们读取通道A的瞬时值,如果通道B的值超前,我们减小计数器。否则,我们增加计数器。

使用轴旋转控制LED灯

电路连接

https://cdn.china-scratch.com/timg/190820/11264G532-3.jpg

代码

/*Rotary Encoder - LED Brightness Control*/#define encoderOutA 6 // CLK#define encoderOutB 7 // DT#define LED 9 // LED , must connect to pwm pinint brightness = 0;int State;int old_State;void setup() {pinMode (encoderOutA, INPUT);pinMode (encoderOutB, INPUT);pinMode (LED, INPUT);Serial.begin (9600);//Read First Position of Channel Aold_State = digitalRead(encoderOutA);}void loop() {State = digitalRead(encoderOutA);if (State != old_State){if (digitalRead(encoderOutB) != State){brightness ++;}else {brightness --;}if (brightness >= 255) brightness = 255;if (brightness <= 0) brightness = 0;Serial.print("brightness: ");Serial.println(brightness);}old_State = State; // the first position was changedanalogWrite(LED , brightness);}
首先,您需要获得轴的位置,然后您可以通过PWM减少或增加LED灯。由于PWM的值介于0到255之间,因此我们也在代码中将轴位置设置在此范围内。

用中断控制直流电机的速度和方向

电路连接

https://cdn.china-scratch.com/timg/190820/11264G563-4.jpg

代码

/*  Rotary Encoder - Controlling a DC Motor using L293D Shield*/
#include
#define CLK 2#define DT  5#define SW  3
AF_DCMotor motor(1, MOTOR12_64KHZ);
int motor_dir = 0;int State;int old_State, change;volatile int motor_speed = 0;volatile boolean buttonState = false;
void setup() {  Serial.begin(9600);  pinMode(CLK, INPUT);  pinMode(DT, INPUT);  pinMode(SW, INPUT_PULLUP);  old_State = digitalRead(CLK);  attachInterrupt (digitalPinToInterrupt(CLK), encoder_detect, CHANGE);  attachInterrupt (digitalPinToInterrupt(SW), button_detect, FALLING);}void loop() {  if (!buttonState)  {    if (motor_speed > 0)    {      motor.setSpeed(motor_speed);      motor.run(FORWARD);      Serial.print("Move Forward: ");      Serial.println(motor_speed);    }    else if (motor_speed < 0)    {      motor.setSpeed((motor_speed) * (-1));      motor.run(BACKWARD);      Serial.print("Move Backward: ");      Serial.println(motor_speed);    }  }  if (buttonState == true || motor_speed == 0)  {    motor.run(RELEASE);    Serial.println("Break");  }}
void encoder_detect ()  {  buttonState = false;  State = digitalRead(CLK);  if (State != old_State)  {    if (digitalRead(DT) != State)    {      motor_speed ++;      if (motor_speed >= 255) motor_speed = 255;    }    else {      motor_speed --;      if (motor_speed <= -255) motor_speed = -255;    }  }  old_State = State;}
void button_detect(){  buttonState = true;}

在这段代码中,我们使用了一个中断来读取轴和按键的位置。有关中断的更多信息,您可以查看Arduino网站。

通过按下编码器按键或将编码器设置在位置0,电机断开。

--end--

声明:本文章由网友投稿作为教育分享用途,如有侵权原作者可通过邮件及时和我们联系删除:freemanzk@qq.com