Arduino 编码器

article/2025/8/20 11:45:04

旋转编码器模块
这次我们将使用的旋转编码器为360度KY-040模块,工作电压: 5V,一圈脉冲数: 20,旋转编码器可通过旋转可以计数正方向和反方向转动过程中输出脉冲的次数,旋转计数和电位计不一样,这种转动计数是没有限制的。配合旋转编码器上的Switch按键,可以复位到初始状态,即从0开始计数。
增量编码器是一种将旋转位移转换为一连串数字脉冲信号的旋转式传感器。这些脉冲用来控制角位移。在Eltra编码器中角位移的转换采用了光电扫描原理。读数系统以由交替的透光窗口和不透光窗口构成的径向分度盘(码盘)的旋转为依据,同时被一个红外光源垂直照射,光把码盘的图像投射到接收器表面上。接收器覆盖着一层衍射光栅,它具有和码盘相同的窗口宽度。接收器的工作是感受光盘转动所产生的变化,然后将光变化转换成相应的电变化。再使低电平信号上升到较高电平,并产生没有任何干扰的方形脉冲,这就必须用电子电路来处理。读数系统通常采用差分方式,即将两个波形一样但相位差为180°的不同信号进行比较,以便提高输出信号的质量和稳定性。读数是再两个信号的差别基础上形成的,从而消除了干扰。增量编码器给出两相方波,它们的相位差90°,通常称为A通道和B通道,见下图。
在这里插入图片描述
其中一个通道给出与转速相关的信息,与此同时,通过两个通道信号进行顺序对比,得到旋转方向的信息。还有一个特殊信号称为Z或零通道,该通道给出编码器的绝对零位,此信号是一个方波与A通道方波的中心线重合。
在这里插入图片描述
读者可以根据上图左图和右图进行对比起高低电平的变化。接
下来我们开始编程,我们的编程效果要达到怎样呢? 在顺时针和逆时针转动编码器的旋钮时,在串口监视器中显示每个脉冲的计数值,并同时显示是在顺时针转,还是逆时针。通过按下Switch旋钮,所有的计数值将归0,并且LED灯闪烁一下。串口监视器显示见左图。读者买到编码器时,可以在转动编码器旋钮时,通过手感去感觉编码器在360度内有20格。每转动一格,要求LED等闪烁一下。
在这里插入图片描述
现在我们开始连接Arduino和编码器,如下图

在这里插入图片描述
编码器原理、编程要求和接线图都讲好了,我们现在开始编程。
int CLK = 2; // 定义针脚2名为CLK,A 通道
int DT = 3; // 定义针脚3 名为DT,B 通道
int SW = 4; // 定义针脚4名为SW,旋钮的按钮开关
int LedPin = 13; // 定义LED针脚13名为LedPin
int InterRupt = 0; // 给中断变量名InterRupt 赋值为0
int Count = 0; // 给变量Count 赋值为0,作为计脉冲数用
int LastCLK = 0; // 给变量LastCLK赋值为0,作为上一脉冲信号

void setup()
{
pinMode(SW, INPUT); // 设置SW 针脚为输入状态
digitalWrite(SW, HIGH); // 给SW 针脚置高
pinMode(LedPin,OUTPUT); // 设置LedPin 针脚为输出状态
pinMode(CLK, INPUT); // 设置CLK针脚为输入状态
pinMode(DT, INPUT); // 设置DT 针脚为输入状态
attachInterrupt(InterRupt , ClkChange, CHANGE); // 中断语句,后面会详细讲解
Serial.begin(9600); //设置波特率为9600
}

void loop()
{
if ((!digitalRead(SW)) && (Count != 0)) // 如果SW读到的信号为0,因SW 针脚已置高
{ // 脉冲计算为非0,即按下旋钮和计数非0同时发生时
Count = 0; // 脉冲计数置0
Serial.print(“Count:”); // 串口监视器打印字符串Count
Serial.println(Count); // 串口监视器打印变量Count值
digitalWrite(LedPin, HIGH); // 点亮LED灯
delay(200); // 延时200毫秒
digitalWrite(LedPin, LOW); // 熄灭LED灯
delay(200); // 延时200毫秒
}
}

void ClkChange() // 中断函数
{
int clkValue = digitalRead(CLK); // 把读取CLK针脚的信号保存到变量clkValue中
int dtValue = digitalRead(DT); // 把读取DT针脚的信号保存到变量clkValue中
digitalWrite(LedPin, HIGH); // 点亮LED灯
delay(100); // 延时100毫秒
digitalWrite(LedPin, LOW); // 熄灭LED灯
delay(100); // 延时100毫秒
if (LastCLK != clkValue) // 结合图5-09和表5-03,中断语句中使用了
{ // CHANGE,即任何的信号变化,即上升沿或下降沿。
// 后面会详细说明
int Count1 = Count; //把Count值保存到Count1
LastCLK = clkValue; // 把clkValue的值保存到LastCLK
Count += (clkValue != dtValue ? 1 : -1); // Count自加,该语句后面详细说明
Serial.print(“Count:”); // 在串口监视器打印字符串Count
Serial.print(Count); // 在串口监视器打印变量Count值
if((Count-1) == Count1) // 如果Count -1 的值是否等于Count1
{
Serial.println(“顺时针”); // 在串口监视器中打印字符串顺时针
}

if((Count+1) == Count1)          //  如果Count +1 的值是否等于Count1
{Serial.println("逆时针");          // 在串口监视器中打印字符串逆时针
} 

}
}

读者可以结合下表细细体会一下if (LastCLK != clkValue) 语句中的内容。
在这里插入图片描述
第一句:if (LastCLK != clkValue),请结合下面图表理解,这句话是在中断函数内的。想来初学者对中断函数还是会比较陌生,中断函数格式:attachInterrupt ( Interrupt, ISR, MODE) .
中断类型:外部中断,引脚改变中断和时钟中断三种,本例使用外部中断。
当Arduino检测Interrupt外部中断号中断时,即数字接口2中断,程序会转去执行一个特定的函数ISR,在这个程序中就是ClkChange()函数。
在setup()函数中语句:attachInterrupt(InterRupt , ClkChange, CHANGE);
MODE则有4种模式:
 RISING: 信号由低变高,即上升沿
 FALLING:信号由高变低,即下降沿
 CHANGE:任何信号变化,上升或下降
 LOW: 低电平触发

初略了解了上面中断的概念和函数定义后,我们回过来再看程序中if语句:if (LastCLK != clkValue)。看顺时针CW蓝色箭头方向,在A通道的第1次上升沿时(蓝色箭头),信号的跳变是从0变为1,即LastCLK为0,clkValue为1,当A通道信号跳变为1时(CHANGE),B通道中的dtValue值仍然是0,即黄色框,见图5-14。而Count等于多少呢?看这句Count += (clkValue != dtValue ? 1 : -1),这句我们可以拆解两部分:第1部分clkValue != dtValue ? 1 : -1,意思是如果clkValue不等于dtValue,则结果为1;相等为-1。通过之前结果可知:clkValue为1,dtValue也为0,所以两者不相等则为1。接着使用语句int Count1 = Count和LastCLK = clkValue。前一句是把第一次的Count值1保存到Count1,后一句是把clkValue值保存到LastCLK中,所以在表5-03的顺时针表中第二次跳变时,LastCLK为1,clkValue为0,dtValue也为1,两者不相等,Count还是等于1。但表中实际结果是2,为什么呢?这是因为第2部分Count +=语句。我们再复盘一下,最初Count=0,第一次跳变后Count +=1,即Count=Count+1=0+1=1,此时Count的值为1。第二次跳变Count +=1,即Count=Count+1=1+1=2。到这里相信读者已经可以理解这个程序的逻辑了吧。

在这里插入图片描述

最后在串口监视器中打印“顺时针”的判断语句是if((Count-1) == Count1),即如果2-1是否等于1,等于1则打印“顺时针”。为什么会想到这句语句呢?请看表5-03中顺时针的Count值变化,1->2->3,都是后一个数值比前一个数值大1。那么还有一种情况,如果我正在逆时针转动旋钮,当时数值停在-3,此时我顺时针转,数值会变成什么呢?我们可以看图5-12的倒数第4和第3行,这个数值会变成-2,即-3+1=-2。原理和之前讲的Count=Count+1一样。如果读者把上面的文字理解了,那么你就已经领悟了该程序的精髓了。
大家可以根据作者上面的程序分析,举一反三的列出表5-03中的逆时针的变量值的变化表。此程序中涉及到中断的类型的使用,我们会在本书的后面章节中单独的讲解。上面的编码器是手动的,若是能理解了这个程序逻辑,将来使用电机马达自带编码器的应用就可以更快上手。如自平衡小车的底盘,基本都是带有编码器的,这个可以精确的计算出转速和角度。

http://www.hkcw.cn/article/aAcecxxggJ.shtml

相关文章

ppt一键制作:ai自动生成PPT,便捷高效超级精美!

深夜的台灯下,你对着杂乱的 PPT 内容反复刷新灵感,鼠标在字体、配色选项间来回穿梭,好不容易拼凑出的页面,却总透着浓浓的 “廉价感”;汇报在即,逻辑混乱的大纲改了又改,每一页感觉合适又不搭&a…

俞敏洪骑车摔倒深夜发博:感谢关心,皮外伤

5月29日,俞敏洪在青海骑行时不慎摔倒,膝盖等处磕破出血。30日凌晨1点多,他发博报平安:29日骑车有点睡着了摔了一下,感谢广大朋友关心,皮外伤,不用担心。责任编辑:zx0002

R语言在生物群落数据统计分析与绘图中的实践应用

随着生物信息学的快速发展,R语言因其开源、自由、免费的特点,在生物群落数据分析领域得到了广泛应用。生物群落数据多样且复杂,涉及众多统计分析方法。本文旨在介绍R语言在生物群落数据统计分析与绘图中的实践应用,结合具体技术要…

100个 Coze 智能体实战案例

👋 家人们,今天我们正式开始 「100个 Coze 智能体实战案例」 系列! 为了让关注的小伙伴,去学习到字节的大杀器,coze空间里面的工作流,做agent智能体也好,工作流也好,很多人都会疑惑…

跨越太赫兹鸿沟:高通量实时成像的曙光?

告别蜗牛扫描,实时透视不再是梦 你是否想象过,未来的安检仪能瞬间透视行李箱内的物品,医生能无创“看穿”皮肤下的癌细胞,文物修复师能精准分析千年古画下的每一层颜料?这些科幻场景的实现,正依赖于一种名…

高效开发,升级软件,硬件也要专业

作为开发者的你,在看代码时是否有频繁切换鼠标滚轮的困扰?是否经常会感觉到看代码眼睛干涩? 是时候拥有一台专为程序员打造的专用显示器啦,作为一名程序员,需要写很多项目,都是大工程,我们在修改代码时总希望能显示多…

上班带饭素材

=================================================================== 素菜: 清炒西蓝花 + 欧芹大蒜盐 清炒生菜 &#

从时钟精度看晶振频率稳定度的重要性

在当今数字化的时代,电子设备无处不在,从我们日常使用的智能手机、电脑,到工业生产中的自动化控制系统,再到航空航天领域的精密仪器,这些设备的正常运行都离不开一个关键的组件——晶振。晶振,全称为晶体振…

RAG技术:私有大模型知识更新的最佳实践

“ 大模型的知识主要是在预训练阶段学习的,更新大模型的固化知识是非常困难的,需要通过特定数据集的微调再训练实现。通过RAG实现私有知识库与私有化部署大模型相融合,就变得容易得多,但需要根据私有知识库的数据结构特点进行选型…

Cesium 报错:自定义材质报‘texture2D‘ : no matching overloaded function found错误

文章目录 问题分析解决 问题 Ceisum 加载自定义材质时报错如下: 自定义材质报‘texture2D‘ : no matching overloaded function found错误 分析 cesium1.102 及以上的版本会报错:原因是从1.102版本开始默认使用的是WebGL2上下文渲染。WebGL2 在所有平…

vue3项目 前端文件下载的两种工具函数

1、Blob 流下载 Blob 表示不可变的原始数据的类文件对象,通常用于处理文件或大块二进制数据。 注意:js中还有一个二进制数据类型ArrayBuffer,它们的区别如下 Blob 可以位于磁盘、高速缓存内存和其他不可用的位置;ArrayBuffer 是存…

信号量的应用:利用信号量实现进程同步

进程同步与信号量 进程同步是指在多进程环境下,为了保证程序的正确性,协调多个进程按一定顺序执行。信号量是实现进程同步的重要工具,它本质上是一个特殊变量,通过对其进行 wait(P 操作)和 signal&#xf…

常规个人信息安全设置(windwos一)

windows操作系统 1、修改个人电脑密码,修改为安全密码,打开安全策略。2、确定关闭远程访问功能3、打开病毒防护 最近无意识的一些操作导致了电脑被病毒攻击,表现就是所有文件夹下都会自动生成一个READMIN.TXT文件,内容如下&#x…

C#回调函数深度解析

文章目录 前言什么是回调函数C#中实现回调的方式委托(Delegate)事件(Event)Action和FuncPredicateAsyncCallback匿名方法和Lambda表达式 回调函数实际应用场景异步编程事件处理策略模式LINQ查询 回调函数的优缺点优点缺点 最佳实践与注意事项总结相关资源 前言 在现代软件开发…

一男子发多条视频怀念亡妻:相恋12年,会照顾好两个老人

5月29日(报道),山东一男子发布多条视频怀念亡妻,二人相恋十二年,28岁妻子死于心脏停搏,去世前一天还晒了老公送的花。当事人:“我会带着思念好好活下去,照顾好两个老人。”责任编辑:zx0002

在supermap idesktop中两块影像设置背景透明后,拼接处会有一条明显的黑线,但是放大后又没有,这个怎么处理

1.将数据集的影像数据先添加到一个新的地图; 2.去数据集将影像数据的金字塔删除; 3.重新创建影像金字塔;选择【创建影像数据金字塔】 4.将栅格数据添加到图层里 点击属性进行设置,勾选【无值透明】、背景值设置为0 0 0&#xff…

女子误扔40多万黄金到第二天才发觉 民警经过近1小时排查成功找到

近日在天津,民警接到市民求助,称不慎将价值40万元的黄金当作垃圾丢弃。报警人是天津一家经营金店的夫妇,店主称,当晚闭店后,他的妻子照例去扔垃圾,却不慎将装有500多克价值40万元的黄金首饰及金料的塑料袋当作垃圾丢弃。等他们发现时已是第二天,此时垃圾早已被环卫部门收…

工业智能网关在柔性制造系统中的动态产线切换实践

一、项目背景 在电子制造行业,某企业拥有数百台生产设备,包括西门子品牌的PLC设备、欧姆龙品牌的传感器以及基恩士品牌的条码读取器等。这些设备分布在多个车间,传统的监控方式需要工作人员到现场逐一查看设备运行状态,不仅效率低…

Facebook 的隐私保护为何备受争议?

Facebook,这个全球最大的社交网络平台,拥有数十亿用户,其隐私保护问题一直是公众关注的焦点。从数据收集到隐私政策的复杂性,再到第三方数据共享和隐私设置的不直观性,Facebook 在隐私保护方面面临着重重挑战。本文将深…

lesson04-简单回归案例实战(理论+代码)

理解线性回归及梯度下降优化 引言 在机器学习的基础课程中,我们经常遇到的一个重要概念就是线性回归。今天,我们将深入探讨这一主题,并通过具体的例子来了解如何利用梯度下降方法对模型进行优化。 线性回归简介 线性回归是一种统计方法&a…