嵌入式人工智能(32-基于树莓派4B的旋转编码器-EnCoder11)

1、旋转编码器

旋转编码器是一种输入设备,通常用于测量和控制旋转运动。它由一个旋转轴和一系列编码器组成。旋转编码器可以根据旋转轴的位置和方向来测量旋转角度,并将其转化为电子信号输出。

旋转编码器通常分为两种类型:绝对值编码器和增量值编码器。

绝对值编码器可以直接输出旋转轴的绝对位置,无需进行位置复位。它通常使用一组二进制编码来表示不同的位置。绝对值编码器具有高精度和高分辨率,适用于需要准确度较高的应用。

增量值编码器则根据旋转轴的运动方向和速度来输出增量值。它通常包含两个输出信号,一个输出脉冲信号用于计数旋转轴的步数,另一个输出方向信号用于指示旋转方向。增量值编码器相对较简单,成本较低,适用于一般的旋转控制应用。

旋转编码器广泛应用于各种领域,如机械加工、机器人控制、汽车导航等。它可以实现精确的角度测量和控制,提高系统的精度和稳定性。

2、EnCode11

EC11旋转编码器广泛用于车载DVD,车载导航,汽车影音上常被人称为车载编码器。编码器主要用于频率调节,高度调节温度调节及音量调节的参数控制。

EC11旋转编码器通常具有两个正交的输出信号(A相和B相),通过检测这两个信号的变化来确定旋转的方向和步长。它还可能具有一个开关信号输出,用于表示按压旋钮的操作。

EC11旋转编码器的工作原理是通过编码盘上的凹槽和接触触点的接触来感知旋转运动。当旋转编码器旋转时,凹槽和接触触点之间的接触状态会不断变化,从而产生相应的输出信号。

总而言之,EC11旋转编码器是一种常见的用于测量和控制旋转运动的输入设备,具有防尘、防水和耐用的设计,适用于各种工业和消费电子应用。

上面2种旋转编码器实际上是一种,就是引脚编号不同,具体对应关系如下。

GND:接地连接。
VCC(+):正电源电压,额定电压5伏。
SW:按钮开关的输出(低电平有效)。当按下旋钮时,电压变低。
DT(输出 B):与CLK输出类似,但滞后于CLK 90°相移。该输出用于确定旋转方向。
CLK(输出A):用于确定旋转量的主要输出脉冲。每次仅通过一个制动装置(咔嗒声)向任一方向转动旋钮时,“CLK”输出就会经历一个先高后低的周期。

3、EC11工作原理

丝印上显示“CLK”、“DT”、“SW”、“+”、“GND”这类是Arduino的编码器,我多说一段话,做个笔记,就是介绍下Arduino,Arduino是一个开源电子平台,它起源于意大利,主要用于简化原型设计和物联网(IoT)项目的创建。Arduino板通常包括微控制器、输入/输出端口以及用于连接各种传感器和设备的插槽。用户可以通过编写简单的基于文本的程序,也就是称为“sketches”的,利用 Ardunio IDE(集成开发环境)来控制硬件。

Arduino的魅力在于其易学性,即使是缺乏专业电路知识的人也能快速上手。它广泛应用于教育、艺术、自动化、家居自动化等领域,支持各种扩展模块,如WiFi、蓝牙等,使得项目具备无线通信功能。通过Arduino,人们可以轻松地将物理世界与数字世界连接起来。

实际上我们树莓派+Python也可以,能比Arduino难不倒哪去,有机会我们也玩玩Arduino的ESP32。言归正传,“CLK”、“DT”:在该模块上显示的丝印名称为这两个,不明白为什么是这个丝印,应该实际对应于编码器常用的“A”、“B”信号吧,这两个信号的发生方式如下:

正旋:如上图当旋钮开始正向旋转时,“A”从低电平变为高电平,“B”保持不变;当旋钮旋转到预定位置时,“A”维持为高电平,“B”然后跟着从低电平跳变到高电平。也就是说,正旋时,“A”总是先与“B”开始电平变化。
反旋:与正旋相反,“B”总是先与“A”开始电平变化。

4、EC11与树莓派连接

VCC:5V

GND:GND

A:GPIO19(BOARD35)

B:GPIO26(BOARD37)

C:GPIO21(BOARD40)

旋转编码器有2个动作,一个是旋转,包括顺时针旋转和逆时针旋转。另一个是按下,车载收音机旋钮也有这个按下的动作,有的是作为退出键,这个按下的输入检测到低电平,可自行定义功能。

但是我这款EC11ABC的C引脚,用万用表测试按下无法产生低电平,令大家失望了,看来这个C引脚硬件内部没有实现按下接地的逻辑,我们用一个按键来模拟即可。

5、实验代码与现象

顺时针旋转编码器,计数值增加,OLED屏上面显示该数值。逆时针旋转编码器,计数值减少。

同时可根据这个计数值改变LED灯的亮暗,注意占空比的范围是(0-100),而编码器的值是(-无穷至+无穷),同学们可以思考下,如何做一个数学函数,将其映射过去。代码有点BUG,我就不改了。

import RPi.GPIO as GPIO
import time
from PIL import Image  
from PIL import ImageDraw
from PIL import ImageFont
import RPi.GPIO as GPIO
import luma.oled as oled  
from luma.core.interface.serial import i2c    
from luma.oled.device import ssd1306  
from luma.core.render import canvasWIDTH=128
HEIGHT=64 PWM_LED = 11
RoAPin = 35    # 旋转编码器CLK管脚
RoBPin = 37    # 旋转编码器DT管脚
BtnPin = 13    # 旋转编码器SW管脚
#global globalCounter
globalCounter = 0  # 计数器值flag = 0                # 是否发生旋转标志位
Last_RoB_Status = 0     # DT 状态
Current_RoB_Status = 0  # CLK 状态# 初始化工作
def setup():GPIO.setmode(GPIO.BOARD)       # 采用实际的物理管脚给GPIO口GPIO.setwarnings(False)        # 忽略GPIO操作注意警告GPIO.setup(PWM_LED, GPIO.OUT)GPIO.setup(RoAPin, GPIO.IN)    # 旋转编码器CLK管脚,设置为输入模式GPIO.setup(RoBPin, GPIO.IN)    # 旋转编码器DT管脚,设置为输入模式GPIO.setup(BtnPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # 设置BtnPin管脚为输入模式,上拉至高电平(3.3V)def load_device():# 创建I2C接口对象  serial = i2c(port=1, address=0x3C)  # 地址可能因显示屏型号而异,由命令行“sudo i2cdetect -y 1”得到# 创建OLED设备对象  device = ssd1306(serial, WIDTH, HEIGHT) return device# 旋转编码方向位判断函数
def rotaryDeal():global flag                   # 是否发生旋转标志位global Last_RoB_Statusglobal Current_RoB_Statusglobal globalCounter         # 计数器值pwm = GPIO.PWM(PWM_LED, 80)pwm.start(0)if GPIO.input(BtnPin)==GPIO.HIGH:Last_RoB_Status = GPIO.input(RoBPin)while(not GPIO.input(RoAPin)):       # 判断CLK管脚的电平变化来区分方向Current_RoB_Status = GPIO.input(RoBPin)flag = 1    # 发生旋转标记if flag == 1:   # 标记位为1 发生了旋转flag = 0    # 复位标记位if (Last_RoB_Status == 0) and (Current_RoB_Status == 1):globalCounter = globalCounter - 1   # 逆时针方向,负if (Last_RoB_Status == 1) and (Current_RoB_Status == 0):globalCounter = globalCounter + 1   # 顺时针方向,正print(globalCounter)with canvas(device) as draw:draw.rectangle(device.bounding_box, outline=0, fill=0)draw.text((0,0), "当前计数值为:",font=font, fill='white')draw.text((20,20), str(globalCounter), font=font, fill="white")PwmCounter=int(abs(globalCounter)/255*100)for i in range(0, PwmCounter, 1):# 更改占空比,pwm.ChangeDutyCycle(i)time.sleep(0.02)               else:globalCounter = 0with canvas(device) as draw:draw.rectangle(device.bounding_box, outline=0, fill=0)draw.text((0,0), "当前计数值为:",font=font, fill='white')draw.text((20,20), str(globalCounter), font=font, fill="white")print('计数值已经回零!')# 中断函数,当SW管脚为0,使能中断
def btnISR():global globalCounterwhile True:if GPIO.input(BtnPin)==GPIO.LOW:time.sleep(0.2)if GPIO.input(BtnPin)==GPIO.LOW:print('Button pressed.')globalCounter = 0 # 给计数器赋print(globalCounter)break# 循环函数
def loop():global globalCounter  tmp = 0	# 当前状态判断while True:rotaryDeal()      # 旋转编码方向位判断函数if tmp != globalCounter: # 判断状态值发生改变print ('globalCounter = %d' % globalCounter) # 打印出状态信息tmp = globalCounter    #  把当前状态赋值到下一个状态,避免重复打印# 释放资源
def destroy():GPIO.cleanup()             # 释放资源# 程序入口
if __name__ == '__main__':  global devicedevice = load_device()  font = ImageFont.truetype('STKAITI.TTF',17)setup()    # 调用初始化工作try:loop() # 调用循环函数except KeyboardInterrupt:  # 当按下Ctrl+C时,将执行destroy()子程序。destroy()

这个代码有点长,后面再介绍传感器的综合实验还是减少点内容,不然代码过于冗长。一般做嵌入式开发,按键LED显示屏这三个是必备的输入输出设备。

旋转编码器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/51663.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【ai】Easy-RAG 4: 修复依赖项:numpy numba omegaconf 等

numpy 2.0.1 这个版本太高了 chromadb 0.5.5 requires numpy<2.0.0,>=1.22.5,but you have numpy 2.0.1 which is incompatible.gradio 4.29.0 requires numpy~=1.0, but you have numpy 2.0.1 which is incompatible.langchain 0.2.6 requires numpy<2,>=1; pytho…

力扣面试题(一)

1、给你两个字符串 word1 和 word2 。请你从 word1 开始&#xff0c;通过交替添加字母来合并字符串。如果一个字符串比另一个字符串长&#xff0c;就将多出来的字母追加到合并后字符串的末尾。 char * mergeAlternately(char * word1, char * word2){int len1 strlen(word1);i…

嵌入式学习Day13---C语言提升

目录 一、二级指针 1.1.什么是二级指针 2.2.使用情况 2.3.二级指针与数组指针 二、指针函数 2.1.含义 2.2.格式 2.3.注意 2.4.练习 三、函数指针 3.1.含义 3.2.格式 3.3.存储 3.4.练习 ​编辑 四、void*指针 4.1.void缺省类型 4.2.void* 4.3.格式 4.4.注…

H3CNE(OSPF动态路由)

目录 7.1 静态路由的缺点与动态路由分类 7.1.1 静态路由的缺点 7.1.2 动态路由的分类 7.2 OSPF基础 7.2.1 OSPF的区域 ​编辑 7.2.2 Router-id 7.2.3 开销-Cost or Metric 7.2.4 路由转发 7.3 OSPF邻居表建立过程 7.3.1 五种包 7.3.2 建立邻居表的第一步 7.3.3 邻居建立…

模拟实现短信登录功能 (session 和 Redis 两种代码实例) 带前端演示

目录 整体流程 发送验证码 短信验证码登录、注册 校验登录状态 基于 session 实现登录 实现发送短信验证码功能 1. 前端发送请求 2. 后端处理请求 3. 演示 实现登录功能 1. 前端发送请求 2. 后端处理请求 校验登录状态 1. 登录拦截器 2. 注册拦截器 3. 登录完整…

RocketMQ事务消息机制原理

RocketMQ工作流程 在RocketMQ当中&#xff0c;当消息的生产者将消息生产完成之后&#xff0c;并不会直接将生产好的消息直接投递给消费者&#xff0c;而是先将消息投递个中间的服务&#xff0c;通过这个服务来协调RocketMQ中生产者与消费者之间的消费速度。 那么生产者是如何…

C++里memset的使用

在C中使用memset函数涉及几个关键点&#xff0c;‌包括函数的正确调用方式、‌参数的理解以及注意事项。‌memset函数是C和C语言标准库中的一个函数&#xff0c;‌用于将内存区域设置为特定的值。‌它的基本语法如下&#xff1a;‌ void *memset(void *s, int c, size_t n); …

集合论与存在性证明问题的分类

集合论是数学的一个重要分支&#xff0c;主要研究集合及其性质、关系以及操作等。关于集合论与存在性证明问题的分类&#xff0c;可以从多个角度进行阐述。 一、集合论的分类 基础集合论 研究集合的基本概念和性质&#xff0c;包括集合的定义、集合的元素关系、集合的操作、…

昇思25天学习打卡营第19天|DCGAN生成漫画头像

DCGAN生成漫画头像总结 实验概述 本实验旨在利用深度卷积生成对抗网络&#xff08;DCGAN&#xff09;生成动漫头像&#xff0c;通过设置网络、优化器以及损失函数&#xff0c;使用MindSpore进行实现。 实验目的 学习和掌握DCGAN的基本原理和应用。熟悉使用MindSpore进行图像…

网络协议一 : 搭建tomacat,intellij IDEA Ultimate 的下载,安装,配置,启动, 访问

需要搭建的环境 1.客户端--服务器开发环境 客户端&#xff1a;浏览器&#xff08;HTMLCSSJS&#xff09; 服务器&#xff1a;JAVA 1.安装JDK&#xff0c;配置JAVA_HOME 和 PATH 2.安装Tomcat 3.安装IDE--intellij IDEA Ultimate 是旗舰版的意思。 2.TOMCAT 的下载和解…

文件操作相关的精讲

目录&#xff1a; 思维导图 一. 文件定义 二. 文件的打开和关闭 三. 文件的顺序读写操作 四. 文件的随机读写操作 五. 文本文件和二进制文件 六. 文件读取结束的判断 七.文件缓冲区 思维导图&#xff1a; 一. 文件定义 1.文件定义 C语言中&#xff0c;文件是指一组相…

Flutter 生命周期介绍与使用

Flutter 生命周期简介与使用 Flutter 是一个由 Google 开发的开源 UI 软件开发工具包&#xff0c;用于跨平台应用程序的开发。了解 Flutter 的生命周期对于构建高效且响应式的应用程序至关重要。在这篇博客中&#xff0c;我们将探讨 Flutter 的生命周期管理&#xff0c;包括 S…

Java中的二叉搜索树(如果想知道Java中有关二叉搜索树的知识点,那么只看这一篇就足够了!)

前言&#xff1a;Java 提供了丰富的数据结构来处理和管理数据&#xff0c;其中 TreeSet 和 TreeMap 是基于红黑树实现的集合和映射接口。它们有序地存储数据&#xff0c;提供高效的搜索、插入和删除操作。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我的主…

PHP表单验证邮件和URL

在PHP中验证表单中的电子邮件地址和URL地址是确保用户输入数据正确性的重要步骤。下面是一个详细的教程&#xff0c;介绍如何使用PHP来验证电子邮件和URL地址。 一、验证电子邮件地址 电子邮件地址的验证通常涉及检查字符串是否符合电子邮件的标准格式。虽然完全通过正则表达…

web基础,http协议,apache概念及nginx

一、web相关概念 Web&#xff0c;全称World Wide Web&#xff0c;通常简称为WWW、Web或万维网&#xff0c;是一个基于超文本和HTTP&#xff08;超文本传输协议&#xff09;的、全球性的、动态交互的、跨平台的分布式图形信息系统。它起源于1989年&#xff0c;由英国科学家蒂姆…

Doris-接入能力

1. Doris数据入库功能特性2. Doris 数据写入流程图3. 常用组件写入功能特性对比 3.1. IDU实现方式对比3.2. 写入速度对比

文本编辑三剑客(grep)

目录 正则表达式 元字符 grep 案例 我在编写脚本的时候发现&#xff0c;三个文本编辑的命令&#xff08;grep、sed、awk&#xff0c;被称为文本编辑三剑客&#xff0c;我习惯叫它三巨头&#xff09;用的还挺多的&#xff0c;说实话我一开始学的时候也有些懵&#xff0c;主要…

云 IDE 你了解多少

IDE&#xff08;Intelligent Development Environment&#xff09; 对于软件开发者来说&#xff0c;是一个非常重要的工具。好用的 IDE 可以大幅提高开发效率&#xff0c;减少不必要的重复工作。 就目前而言&#xff0c;本地的 IDE 可能依然是主流的选择。但是&#xff0c;在本…

Rust 程序设计语言学习——智能指针

智能指针&#xff08;smart pointers&#xff09;是一类数据结构&#xff0c;它们的表现类似指针&#xff0c;但是也拥有额外的元数据和功能。智能指针的概念并不为 Rust 所独有&#xff1b;其起源于 C 并存在于其他语言中。Rust 标准库中定义了多种不同的智能指针&#xff0c;…

(史上最全的)Spring6框架学习教程

一、什么是Spring 1.javaWeb框架发展史 1、ServletJSPJavaBean(跳转页面、业务逻辑判断、数据库查询) 2、MVC三层架构(M Model pojo(User)V-view(USP)C-(controller-servlet)) (web-跳转页面service-业务逻辑判断 new UserService0;dao-数据库查询 new UserDao(); ) 3、使用…