风筝
发表于: 2019-8-19 22:26:07 | 显示全部楼层

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


什么是旋转编码器?

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

Untitled-2-1.jpg


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


该模块的一些功能包括:

●     无限旋转

●     20脉冲分辨率

●     5V供电电压

rotary-encoder.jpg


如何使用旋转编码器?

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

rotary_encoder_pinout.jpg


确定旋转编码器轴的位置

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


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


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

  1. /*
  2. Rotary Encoder - get the position
  3. */
  4. #define encoderOutA 6 // CLK
  5. #define encoderOutB 7 // DT
  6. int counter = 0;
  7. int State;
  8. int old_State;
  9. void setup() {
  10. pinMode (encoderOutA, INPUT);
  11. pinMode (encoderOutB, INPUT);
  12. Serial.begin (9600);
  13. //Read First Position of Channel A
  14. old_State = digitalRead(encoderOutA);
  15. }
  16. void loop() {
  17. State = digitalRead(encoderOutA);
  18. if (State != old_State)
  19. {
  20. if (digitalRead(encoderOutB) != State)
  21. {
  22. counter ++;
  23. }
  24. else {
  25. counter --;
  26. }
  27. Serial.print("Position: ");
  28. Serial.println(counter);
  29. }
  30. old_State = State; // the first position was changed
  31. }
复制代码

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


使用轴旋转控制LED灯

电路连接

rotary_encoder_led_fritzing-1.jpg


代码

  1. /*
  2. Rotary Encoder - LED Brightness Control
  3. */
  4. #define encoderOutA 6 // CLK
  5. #define encoderOutB 7 // DT
  6. #define LED 9 // LED , must connect to pwm pin
  7. int brightness = 0;
  8. int State;
  9. int old_State;
  10. void setup() {
  11. pinMode (encoderOutA, INPUT);
  12. pinMode (encoderOutB, INPUT);
  13. pinMode (LED, INPUT);
  14. Serial.begin (9600);
  15. //Read First Position of Channel A
  16. old_State = digitalRead(encoderOutA);
  17. }
  18. void loop() {
  19. State = digitalRead(encoderOutA);
  20. if (State != old_State)
  21. {
  22. if (digitalRead(encoderOutB) != State)
  23. {
  24. brightness ++;
  25. }
  26. else {
  27. brightness --;
  28. }
  29. if (brightness >= 255) brightness = 255;
  30. if (brightness <= 0) brightness = 0;
  31. Serial.print("brightness: ");
  32. Serial.println(brightness);
  33. }
  34. old_State = State; // the first position was changed
  35. analogWrite(LED , brightness);
  36. }
复制代码

首先,您需要获得轴的位置,然后您可以通过PWM减少或增加LED灯。 由于PWM的值介于0到255之间,因此我们也在代码中将轴位置设置在此范围内。


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

电路连接

rotary_encoder_motor_fritzing.jpg


代码

  1. /*
  2.   Rotary Encoder - Controlling a DC Motor using L293D Shield
  3. */

  4. #include <AFMotor.h>

  5. #define CLK 2
  6. #define DT  5
  7. #define SW  3

  8. AF_DCMotor motor(1, MOTOR12_64KHZ);

  9. int motor_dir = 0;
  10. int State;
  11. int old_State, change;
  12. volatile int motor_speed = 0;
  13. volatile boolean buttonState = false;

  14. void setup() {
  15.   Serial.begin(9600);
  16.   pinMode(CLK, INPUT);
  17.   pinMode(DT, INPUT);
  18.   pinMode(SW, INPUT_PULLUP);
  19.   old_State = digitalRead(CLK);
  20.   attachInterrupt (digitalPinToInterrupt(CLK), encoder_detect, CHANGE);
  21.   attachInterrupt (digitalPinToInterrupt(SW), button_detect, FALLING);
  22. }
  23. void loop() {
  24.   if (!buttonState)
  25.   {
  26.     if (motor_speed > 0)
  27.     {
  28.       motor.setSpeed(motor_speed);
  29.       motor.run(FORWARD);
  30.       Serial.print("Move Forward: ");
  31.       Serial.println(motor_speed);
  32.     }
  33.     else if (motor_speed < 0)
  34.     {
  35.       motor.setSpeed((motor_speed) * (-1));
  36.       motor.run(BACKWARD);
  37.       Serial.print("Move Backward: ");
  38.       Serial.println(motor_speed);
  39.     }
  40.   }
  41.   if (buttonState == true || motor_speed == 0)
  42.   {
  43.     motor.run(RELEASE);
  44.     Serial.println("Break");
  45.   }
  46. }

  47. void encoder_detect ()  {
  48.   buttonState = false;
  49.   State = digitalRead(CLK);
  50.   if (State != old_State)
  51.   {
  52.     if (digitalRead(DT) != State)
  53.     {
  54.       motor_speed ++;
  55.       if (motor_speed >= 255) motor_speed = 255;
  56.     }
  57.     else {
  58.       motor_speed --;
  59.       if (motor_speed <= -255) motor_speed = -255;
  60.     }
  61.   }
  62.   old_State = State;
  63. }

  64. void button_detect()
  65. {
  66.   buttonState = true;
  67. }
复制代码

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


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


以上就是本篇文章的全部内容。如有问题,请随时在本帖下面进行回复。

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 714 | 回复: 1501



手机版|

GMT+8, 2024-12-22 10:49 , Processed in 0.035667 second(s), 6 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表