旋转式位置传感器是一种用于测量物体旋转角度的传感器,是许多机电设备中不可缺少的元器件。它的工作原理是利用磁性和电学性质来测量旋转角度,具有高精度、高可靠性等优点。其中,最常用的技术是使用旋转磁编码盘和集线器,将旋转角度转换为数字信号输出到控制器进行处理。
就是每转过单位的角度就发出一个脉冲信号(也有发正余弦信号,然后对其进行细分,斩波出频率更高的脉冲),通常为A相、B相、Z相输出,A相、B相为相互延迟1/4周期的脉冲输出,根据延迟关系可以区别正反转,而且通过取A相、B相的上升和下降沿可以进行2或4倍频;Z相为单圈脉冲,即每圈发出一个脉冲。
我们通常用的是增量型编码器,可将旋转编码器的输出脉冲信号直接输入给PLC,利用PLC的高速计数器对其脉冲信号进行计数,以获得测量结果。不同型号的旋转编码器,其输出脉冲的相数也不同,有的旋转编码器输出A、B、Z三相脉冲,有的只有A、B相两相,最简单的只有A相。
编码器有5条引线,其中3条是脉冲输出线,1条是COM端线,1条是电源线(OC门输出型)。编码器的电源可以是外接电源,也可直接使用PLC的DC24V电源。电源“-”端要与编码器的COM端连接,“+ ”与编码器的电源端连接。编码器的COM端与PLC输入COM端连接,A、B、Z两相脉冲输出线直接与PLC的输入端连接,A、B为相差90度的脉冲,Z相信号在编码器旋转一圈只有一个脉冲,通常用来做零点的依据,连接时要注意PLC输入的响应时间。旋转编码器还有一条屏蔽线,使用时要将屏蔽线接地,提高抗干扰性。
就是对应一圈,每个基准的角度发出一个唯一与该角度对应二进制的数值,通过外部记圈器件可以进行多个位置的记录和测量。
由于A、B两相相差90度,可通过比较A相在前还是B相在前,以判别编码器的正转与反转,通过零位脉冲,可获得编码器的零位参考位。编码器码盘的材料有玻璃、金属、塑料,玻璃码盘是在玻璃上沉积很薄的刻线,其热稳定性好,精度高,金属码盘直接以通和不通刻线,不易碎,但由于金属有一定的厚度,精度就有限制,其热稳定性就要比玻璃的差一个数量级,塑料码盘是经济型的,其成本低,但精度、热稳定性、寿命均要差一些。
分辨率—编码器以每旋转360度提供多少的通或暗刻线称为分辨率,也称解析分度、或直接称多少线,一般在每转分度5~10000线
磁性旋转传感器是利用磁性元件实现测量的传感器。其工作原理是将磁性元件固定在被测物体上,当被测物体旋转时,磁性元件也跟随旋转,产生磁场变化。传感器内部的磁敏电阻感应到这一磁场变化,并产生电压信号输出。通过测量电压信号的大小和方向,就可以计算出被测物体的旋转角度。
霍尔效应式转速传感器和曲轴位置传感器是一种利用霍尔效应的信号发生器。霍尔信号发生器安装在分电器内,与分火头同轴,由封装的霍尔芯片和永久磁铁作成整体固定在分电器盘上。触发叶轮上的缺口数和发动机气缸数相同。当触发叶轮上的叶片进入永久磁铁与霍尔元件之间,霍尔触发器的磁场被叶片旁路,这时不产生霍尔电压,传感器无输出信号;当触发叶轮上的缺口部分进入永久磁铁和霍尔元件之间时,磁力线进入霍尔元件,霍尔电压升高,传感器输出电压信号。
光电旋转传感器是通过光电元件实现测量的传感器。其工作原理是将旋转物体上的刻度盘固定在光电元件上方,当旋转物体旋转时,刻度盘上的条纹或孔洞会使光束发生变化,光电元件感应到这一变化并产生电信号输出。通过测量电信号的大小和方向,就可以计算出被测物体的旋转角度。
旋转式位置传感器广泛应用于工业自动化、航空航天、汽车、医疗设备等领域。 例如,在机床中,旋转式位置传感器可以用于测量工件的旋转角度,实现工件的定位和控制;在汽车中,旋转式位置传感器可以用于测量转向角度和车速,实现车辆的稳定性和安全性控制。 旋转式位置传感器是一种重要的传感器元器件,可以实现物体旋转位置角度的高精度测量。
1、工业机械、工程机械建筑设备、石化设备、医疗设备、航空航天仪器仪表、国防工业等旋转速度和角度的测量;
2、汽车电子脚踩油门角位移、方向盘位置、座椅位置、前大灯位置;
3、自动化机器人、运动控制、旋转电机转动和控制。
所有“位置传感器”中最常用的是电位器,因为它是一种便宜且易于使用的位置传感器。它有一个与机械轴相连的触点,该机械轴的运动可以是有角度的(旋转的)或线性的(滑块型),这会导致滑块和两个端部连接之间的电阻值发生变化,从而产生电信号输出在电阻轨道上的实际抽头位置与其电阻值之间具有比例关系。换句话说,阻力与位置成正比。
电位器有多种设计和尺寸,例如常用的圆形旋转类型或较长且扁平的线性滑块类型。当用作位置传感器时,可移动物体直接连接到电位计的旋转轴或滑块。
直流参考电压施加在形成电阻元件的两个外部固定连接上。输出电压信号取自滑动触点的抽头端子,如下图所示。
电位器结构图
这种配置产生与轴位置成比例的电位或分压器类型的电路输出。然后,例如,如果在电位器的电阻元件上施加 10v 的电压,则最大输出电压将等于 10 伏的电源电压,最小输出电压等于 0 伏。
然后电位器抽头将输出信号在 0 到 10 伏之间变化,其中 5 伏表示抽头或滑块处于其中间位置或中心位置。电位器的输出信号 (Vout) 在沿电阻轨道移动时取自中心游标连接,并且与轴的角位置成正比。
简单的位置检测电路示例
虽然电阻式电位器位置传感器具有许多优点:成本低、技术含量低、易于使用等,但作为位置传感器,它们也有许多缺点:运动部件磨损、精度低、可重复性低和频率响应有限。
在重载设备和其他车辆中,霍尔效应旋转位置传感器能够取代脚踏板与发动机之间的机械电缆连接。机械电缆会抻拉或腐蚀,需要定期维护和重新校准。取代机械电缆,能改善发动机控制系统的响应和车辆排放,提高可靠性并减少超重。这种电子油门系统比电缆连接系统更安全,更经济。
霍尔效应旋转位置传感器也可用在公交车和重卡离地高度系统中,感应悬架系统的行程。公交车利用自动踏板可降低其离地高度,方便乘客上下车。在此应用的两端都可使用霍尔效应旋转位置传感器:一个传感器监控控制杆的位置,第二个传感器部署在悬架臂或连杆上来监控离地高度。
精确的位置感应可确认车辆是否处于适合应用系统要求的正确高度,从而改进车辆上下通行的便利性。大型拖车也可利用霍尔效应旋转位置传感器来监测拖车高度,提高仓库停靠对接的效率。
厂商 | 主营业务 |
泰科电子 TE Connectivity | 解决方案代理商,产品、服务 |
霍尼韦尔 Honeywell | 航空产品和服务、楼宇和工业控制技术、以及特性材料 |
百能云芯 Bourns | 电子元器件、芯片 |
森萨塔科技 Sensata | 传感器的解决方案,关键型产品 |
力特Littelfuse | 模块化产品、解决方案 |
本次设计需要通过RP2040模块驱动一个旋转位置传感器,这里采用的是一个方向脉冲型信号的512线编码器,RP2040通过脉冲捕获,检测编码器输出的信号,将编码器输出的信号显示于0.96的显示屏,同时12路LED灯用于记数编码器的旋转圈数,此外通过串口通信的方式将编码器数据发送至上位机,方便后续的数据处理与系统开发,其本次设计的系统架构框图如图所示。
本次研究设计的传感器模块为512线旋转位置传感器-编码器模块,通过编码器采集到的数据发送给RP2040模块,RP2040通过外接OLED显示屏与WS1812LED灯板。此外RP2040通过SPI硬件协议驱动OLED显示屏用于实时显示编码器旋转的位置、方向等数据,LED灯板则用于统计编码器旋转的圈数,同时将数据实时发送到上位机,便后后续的数据处理与系统开发,其中系统硬件框图如图所示。
此外其中通过查阅各类资料与相关数据手册后得出编码器在旋转过程中,POUT将产生特定的脉冲信号,DIR端口将输出0或1的高低电瓶以表示旋转的方向,PR2040通过IO口中断形式捕获脉冲信号,其中编码器工作原理及信号如下图所示。
实际编码器上电后,通过示波器测试模块的DIR引脚输出和OUT输出信号,观测到的现象与数据手册一致,实际测试表明该编码器在上电后能正常工作,其中示波器测试编码器输出信号波形如下图所示。
首先在上电后对OLED显示屏、WS2812以及串口进行初始化化配置,使其具有基础的数据显示与发送功能,其次开启IO口中断模式,使其通过中断的方式快速检测编码器产生的脉冲信号并进行捕获,通过中断的次数计算编码器的当前位置与转过的圈数以及旋转方向,检测完成后用过SPI图像协议以及RP2040特带的PIO口将数据显示于OLED显示屏与LED灯板,此外将数据通过串口的新式发送到上位机便于数据查看,其中系统软件工作流程图如图所示。
通过对系统硬件模块的组成、软件代码的编写,以及系统的调试,初步完成对编码器数据的采集,实时的将编码器的旋转位置,方向以及旋转的圈数显示与OLED显示屏,同时将数据发送至上位机串口调试助手,其中串口调制助手界面以及实物OLED显示屏显示数据如下图所示。
通过对编码器的研究与数据采集,初步了解了编码器的工作原理与实际应用,在日常生活中,可将编码器应用与智能小车等一系列智能运动的控制中,通过车轮的转动带动编码器的来捕获小车的运动方向以及更加精确的控制小车的速度,以下为编码器在大学生智能汽车竞赛中的实际图片,当然编码器的应用远不止如此,更是涉及到身边的工业机械、工程机械建筑设备、石化设备、医疗设备、航空航天仪器仪表、国防工业等旋转速度和角度的测量。
from machine import Pin, SPI, ADC, UART from ssd1306 import SSD1306_SPI from astronaut import frames from board import pin_cfg import framebuf import _thread import time import array import rp2 #常量定义 NUM_LEDS = 12 #LED number wsLedDegree = 30 #LED light Degree #pasoberry image buffer = bytearray(b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|?\x00\x01\x86@\x80\x01\x01\x80\x80\x01\x11\x88\x80\x01\x05\xa0\x80\x00\x83\xc1\x00\x00C\xe3\x00\x00~\xfc\x00\x00L'\x00\x00\x9c\x11\x00\x00\xbf\xfd\x00\x00\xe1\x87\x00\x01\xc1\x83\x80\x02A\x82@\x02A\x82@\x02\xc1\xc2@\x02\xf6>\xc0\x01\xfc=\x80\x01\x18\x18\x80\x01\x88\x10\x80\x00\x8c!\x00\x00\x87\xf1\x00\x00\x7f\xf6\x00\x008\x1c\x00\x00\x0c \x00\x00\x03\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") #记数变量定义 pcnt = 0 #脉冲计数器,用于计算脉冲数量 ledCnt = 0 circle = 0 message='' cirLed = 0 global direction global dircnt dircnt = 1 #引脚定义并初始化 dire = Pin(2, Pin.IN, Pin.PULL_UP) pout = Pin(3, Pin.IN, Pin.PULL_UP) led1 = Pin(20, Pin.OUT) led2 = Pin(26, Pin.OUT) led3 = Pin(22, Pin.OUT) led4 = Pin(21, Pin.OUT) uart = UART(0, baudrate=115200, tx=Pin(0), rx=Pin(1), bits=8, parity=None, stop=1) led1.off() led2.off() led3.off() led4.off() #WS1812初始化 @rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW, out_shiftdir=rp2.PIO.SHIFT_LEFT, autopull=True, pull_thresh=24) def ws2812(): T1 = 2 T2 = 5 T3 = 3 wrap_target() label("bitloop") out(x, 1) .side(0) [T3 - 1] jmp(not_x, "do_zero") .side(1) [T1 - 1] jmp("bitloop") .side(1) [T2 - 1] label("do_zero") nop() .side(0) [T2 - 1] wrap() # Create the StateMachine with the ws2812 program, outputting on Pin(18). sm = rp2.StateMachine(0, ws2812, freq=8_000_000, sideset_base=Pin(18)) # Start the StateMachine, it will wait for data on its FIFO. sm.active(1) # Display a pattern on the LEDs via an array of LED RGB values. ar = array.array("I", [0 for _ in range(NUM_LEDS)]) # 8 blue 16 red 24 green #oled初始化 spi1 = SPI(1, 100000, mosi=Pin(pin_cfg.spi1_mosi), sck=Pin(pin_cfg.spi1_sck)) oled = SSD1306_SPI(128, 64, spi1, Pin(pin_cfg.spi1_dc),Pin(pin_cfg.spi1_rstn), Pin(pin_cfg.spi1_cs)) oled.rotate(1) oled.fill(0) oled.show() fb = framebuf.FrameBuffer(buffer, 32, 32, framebuf.MONO_HLSB) global flag flag = 0 for j in range(NUM_LEDS): ar[j] = 0 sm.put(ar, 16) def dirIRQHandler(pin): global dircnt dircnt += 1 #脉冲捕获中断函数 def poutIQHandler(pin): global pcnt global ledCnt global circle pcnt += 1 if pcnt > 512: pcnt = 0 circle += 1 ledCnt += 1 if ledCnt == 0: pass elif ledCnt == 13: ledCnt =1 for j in range(NUM_LEDS): ar[j] = 0 sm.put(ar, 16) else: ar[ledCnt-1] = wsLedDegree sm.put(ar, 16) def oled_thread(): global direction while True: oled.fill(0) #oled.blit(fb, 96, 0) oled.text("Raspberry Pi",5,5) oled.text("Pcnt: ",5,20) oled.text("Cnum: ",5,35) oled.text("Dire: ",5,50) oled.text(str(pcnt),50,20) oled.text(str(circle),50,35) oled.text(str(direction),50,50) oled.show() time.sleep_ms(100) #设置脉冲捕获 _thread.start_new_thread(oled_thread, ()) pout.irq(trigger=Pin.IRQ_RISING,handler=poutIQHandler) dire.irq(trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING,handler=dirIRQHandler) i=0 while True: #pass direction = dire.value() time.sleep_ms(50) uart.write('pcnt: '+str(pcnt)) uart.write(' circle: '+str(circle)) uart.write(' direction: '+str(direction))