以前用CRT显示器的时候,调整显示器的时候用一个圆盘转动和点击的方法就可以实现选择菜单和修改设置项的值,比多个按钮的方式方便很多。

鼠标滚轮也是这种操作方法,旋转+点击,只是方向不同。最近在网上买了旋转编码器模块,想把它用到实际制作中。在网上找了很多资料,测试发现其中的代码或多或少都有问题。于是决定自己研究一下旋转编码器的原理,只涉及高低电平应该会比较简单。

我买的旋转编码器模块有5个引脚,分别是VCC, GND, SW, CLK, DT。其中VCC和GND用来接电源和地,按缩写SW应该是Switch(开关)、CLK是Clock(时钟)、DT是Data(数据)。

网上的资料虽然代码不是很理想,但介绍的原理基本是没问题的。旋转编码器的操作是旋转和按压转轴,在按下转轴的时候SW引脚的电平会变化,旋转的时候每转动一步CLK和DT的电平是有规律的变化。在只接电源的情况下先测一下各种操作时引脚电平的变化,没有示波器只好用万用表测电压。

点击:SW(红)+GND(黑)时按下和松开按钮没有任何变化,VCC(红)+SW(黑)松开时表针指向0,按下时高电平。据此可以推测SW平时为高阻态,按下时接地。用Arduino检测的方法是设置连接SW的引脚为INPUT并上拉输出高电平,检测到引脚为低电平则表示按钮按下,以下代码可以正确检测出按钮的变化。

//定义引脚连接

int SW= 4; //SW->D4

bool lastButtonStatus = false;voidsetup()

{

pinMode(SW, INPUT);

digitalWrite(SW, HIGH);//连接按钮的引脚设为上拉

Serial.begin(9600);

}voidloop()

{bool buttonStatus = !digitalRead(SW);//高电平时未按下,状态为false

if (buttonStatus !=lastButtonStatus)

{

Serial.println(buttonStatus? "pressed" : "released");

lastButtonStatus= buttonStatus;//保存当前状态

}

delay(100);

}

旋转:CLK(红)+GND(黑),每旋转一次(和方向无关),电平转换一次,DT(红)+GND(黑),变化情况和上一种情况一致,并且CLK和DT的电平保持一致。VCC(红)+CLK(黑),VCC(红)+DT(黑)也是同样的情况。CLK(红)+DT(黑)或者CLK(黑)+DT(红)时,每次旋转(和方向无关)指针都会轻微摆动然后归零,并且相邻两步指针的摆动方向相反。结论:每次旋转CLK和DAT引脚的电平都会变化,电平变化有时间差,但无法区分往哪个方向旋转。

编写测试代码,在按下按钮的时候读取CLK和DT的值:

1 //定义引脚连接

2 int CLK = 2;//CLK->D2

3 int DT = 3;//DT->D3

4 int SW = 4;//SW->D4

5

6 voidsetup()7 {8 pinMode(SW, INPUT);9 digitalWrite(SW, HIGH);//连接按钮的引脚设为上拉

10 pinMode(CLK, INPUT);11 pinMode(DT, INPUT);12 Serial.begin(9600);13 }14

15 voidloop()16 {17 if (!digitalRead(SW)) //读取到按钮按下时读取CLK和DT的值

18 {19 int clkValue = digitalRead(CLK);//读取CLK引脚的电平

20 int dtValue = digitalRead(DT);//读取DT引脚的电平

21 Serial.print("CLK:");22 Serial.print(clkValue);23 Serial.print("; DT:");24 Serial.println(dtValue);25 delay(1000);26 }27 }

测试发现不管顺时针还是逆时针旋转,每次按下按钮之后读取的CLK和DT的值都是一样的,并且相邻两步之间的值是不一样的,符合用万用表测量的结果。

万用表测量时发现CLK和DT的变化有一定的时间差,可以用Arduino在CLK电平变化的瞬间读取DT的值,可能会找到其中的规律。改成通过中断0监控CLK上的电平变化,读取CLK和DT的电平值:

1 //定义引脚连接

2 int CLK = 2;//CLK->D2

3 int DT = 3;//DT->D3

4 const int interrupt0 = 0;//Interrupt 0 在 pin 2 上

5

6 voidsetup()7 {8 pinMode(CLK, INPUT);9 pinMode(DT, INPUT);10 attachInterrupt(interrupt0, ClockChanged, CHANGE);//设置中断0的处理函数,电平变化触发

11 Serial.begin(9600);12 }13

14 voidloop()15 {16 }17

18 //中断处理函数

19 voidClockChanged()20 {21 int clkValue = digitalRead(CLK);//读取CLK引脚的电平

22 int dtValue = digitalRead(DT);//读取DT引脚的电平

23 Serial.print("CLK:");24 Serial.print(clkValue);25 Serial.print("; DT:");26 Serial.println(dtValue);27 }

顺时针旋转一步:

顺时针旋转3步(用横线分隔):

逆时针旋转3步(用横线分隔):

根据以上测试结果,每旋转一次触发的中断次数不一致,可能是硬件本身引起的,类似按钮抖动。多次测试之后,查看每次变化的最后一组值,顺时针旋转时CLK和DT的值不一致,逆时针旋转时CLK和DT的值一致。修改代码,顺时针时对计数值加1,逆时针时对计数值减1,按下按钮时计数值清零。

1 //定义引脚连接

2 int CLK = 2;//CLK->D2

3 int DT = 3;//DT->D3

4 int SW = 4;//SW->D4

5 const int interrupt0 = 0;//Interrupt 0 在 pin 2 上

6 int count = 0;//计数值

7 int lastCLK = 0;//CLK历史值

8

9 voidsetup()10 {11 pinMode(SW, INPUT);12 digitalWrite(SW, HIGH);13 pinMode(CLK, INPUT);14 pinMode(DT, INPUT);15 attachInterrupt(interrupt0, ClockChanged, CHANGE);//设置中断0的处理函数,电平变化触发

16 Serial.begin(9600);17 }18

19 voidloop()20 {21 if (!digitalRead(SW) && count != 0) //读取到按钮按下并且计数值不为0时把计数器清零

22 {23 count = 0;24 Serial.print("count:");25 Serial.println(count);26 }27 }28

29 //中断处理函数

30 voidClockChanged()31 {32 int clkValue = digitalRead(CLK);//读取CLK引脚的电平

33 int dtValue = digitalRead(DT);//读取DT引脚的电平

34 if (lastCLK !=clkValue)35 {36 lastCLK =clkValue;37 count += (clkValue != dtValue ? 1 : -1);//CLK和DT不一致时+1,否则-1

38 Serial.print("count:");39 Serial.println(count);40 }41 }

测试发现大多数时候可以正确输出:

偶尔旋转不是很顺畅会出现跳动的情况,这时候能感觉到旋钮在两步之间跳动了一下。看到有人说在引脚和地之间接上滤波电容会好一些,实际测试发现并没有改善。推测由于旋钮是D字型的,用手旋转的时候确实会出现跳动的情况,装上旋钮帽之后应该会避免这种情况。

旋转编码器可以用于需要精确调整值(电位器不准确),操作菜单等场合。后续会使用旋转编码器制作一些小东西,也欢迎大家分享旋转编码器相关代码。

arduino编码器计数_【Arduino】旋转编码器的Arduino使用方法相关推荐

  1. arduino编码器计数_关于电机中断计数问题 - Arduino - 极客工坊 - Powered by Discuz!...

    如果您不介意的话,可以看下我个程序,delay只用在EEPROM读写这里 #include #include union data                                   ...

  2. arduino编码器计数_旋转编码器的工作原理以及如何在Arduino中使用

    在本篇文章中,我们将学习旋转编码器的工作原理以及如何将其与Arduino开发板一起使用.旋转编码器是一种位置传感器,用于确定旋转轴的角度位置.它根据旋转运动产生模拟或数字电信号. Rotary-Enc ...

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

    使用Arduino开发板连接ec11旋转编码器 因为最近要用到旋转编码器,从网上花了好长时间找了好多关于arduino使用旋转编码器的资料,总是找不到合适的,最后总结了一下(部分内容有借鉴,仅作分享, ...

  4. ec11编码器c语言程序,旋转编码器 关于EC11计数的程序 - 下载 - 搜珍网

    压缩包 : e09f3b72b0b3edc883d8ce7c7fbba.rar 列表 旋转编码器check/Doc/readme.txt 旋转编码器check/keilkill.bat 旋转编码器ch ...

  5. arduino编码器计数_基于Arduino开发环境的光电编码器检测仪设计方案 - 全文

    0 引言 Arduino是一款基于单片机系统的电子产品开发平台,它的软硬件系统都具有高度的模块化,而且软件系统是完全开源的.其硬件系统也是高度模块化的,在核心控制板的外围有开关量输入/输出模块.各种模 ...

  6. 旋钮编码器c代码_求旋转编码器c程序

    编码器涵盖很多种类,不知你具体要求的哪种?我也曾折腾过一段时间EC11型的,给你个从网上找来的,参考吧(在我板上能运行) //通过编码开关(旋转编码器)控制数码管的加减一 #include #defi ...

  7. linux 旋转编码器,基于ARM_Linux的旋转编码器接口与驱动程序的设计

    旋转编码器作为速度和位移反馈的传感器,广泛应用于 角位移或角速率的测量,通常有A,B,Z 三相输出.目前,在 实际的应用中,旋转编码器多与PLC.单片机.PC 联合组成控 制采集系统,如文献[1 - ...

  8. arduino 休眠 节能_魔法书3:让 Arduino 慢下来 20倍省电

    我是潘,曾经是个工程师.这是 "Arduino 魔法书" 系列的专栏.上节课介绍了怎么让Arduino 全速运行,但大部分时候我们更希望 Arduino 能慢下来,节省更多的电能, ...

  9. arduino编码器计数_几根线做的Arduino液晶屏旋转编码器带你进入数字化编程之旅...

    #define ENCODER_A_PIN 2 #define ENCODER_B_PIN 3 #define SWITCH_PIN    4 long position;// int latchPi ...

  10. arduino 呼吸灯_如何改善您的Arduino呼吸机:用于临时COVID-19呼吸机设计的RTS和SCS简介...

    arduino 呼吸灯 The world as we know it was recently taken by storm. That storm was the outbreak of the ...

最新文章

  1. Promise对象的创建与使用
  2. python12个基本语法_12-25python基本语法
  3. 36 CO配置-控制-产品成本控制-成本对象控制-期末结算-定义目标成本版本
  4. Codeforces 678E. Another Sith Tournament(概率DP,状压)
  5. C - 师--链表的结点插入
  6. 如何添加二级标题_怎样给Word文档添加目录?
  7. 5.13 广东移动 笔试题
  8. 第35章 GoogleAuthenticator插件项的定义实现
  9. word之无法插入公式,公式图标灰色
  10. Spark数据倾斜解决方案(收藏级)
  11. correl函数相关系数大小意义_相关系数越大,说明两个变量之间的关系就越强吗...
  12. 锁定计算机屏幕的快捷键是什么,计算机屏幕锁定的快捷键是什么? -计算机
  13. 行业分析报告|线上教育技术市场现状及未来发展趋势
  14. pixel手机救砖教程
  15. HCIP笔记(13)
  16. Matlab仿真-信源仿真
  17. 人形机器人视觉处理——垃圾分类
  18. 了解ClassLoader
  19. 联想G480安装固态硬盘过程
  20. Gazebo仿真激光SLAM

热门文章

  1. 约瑟夫环(C语言实现)
  2. ssh连接服务器协议错误,Xmanager发生SSH协议错误怎么办
  3. sql 服务器时间修改时间,教您如何修改sql server时间
  4. 121道分布式面试题和答案,25K妥妥的
  5. meethigher-腾讯课堂自动签到
  6. Make Menuconfig详解 (配置内核选择)
  7. 如何快速批量新建文本文档(txt)?
  8. vue.js2.0视频教程
  9. RS232串口转USB驱动无法正确识别
  10. 1、NoSQL数据库简介