差别
这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 | ||
rotarypositionsensor [2023/07/28 17:38] yuanjianglong |
rotarypositionsensor [2023/07/31 15:29] (当前版本) yuanjianglong |
||
---|---|---|---|
行 44: | 行 44: | ||
{{ ::旋转位置8.jpg?direct&350 |}} | {{ ::旋转位置8.jpg?direct&350 |}} | ||
- | |||
- | {{ ::204.png?200 |}} | ||
* **霍尔效应式旋转位置传感器的工作原理** | * **霍尔效应式旋转位置传感器的工作原理** | ||
行 100: | 行 98: | ||
在重载设备和其他车辆中,霍尔效应旋转位置传感器能够取代脚踏板与发动机之间的机械电缆连接。机械电缆会抻拉或腐蚀,需要定期维护和重新校准。取代机械电缆,能改善发动机控制系统的响应和车辆排放,提高可靠性并减少超重。这种电子油门系统比电缆连接系统更安全,更经济。 | 在重载设备和其他车辆中,霍尔效应旋转位置传感器能够取代脚踏板与发动机之间的机械电缆连接。机械电缆会抻拉或腐蚀,需要定期维护和重新校准。取代机械电缆,能改善发动机控制系统的响应和车辆排放,提高可靠性并减少超重。这种电子油门系统比电缆连接系统更安全,更经济。 | ||
- | {{ :旋转位置2.jpg?direct&280 |}} | + | {{ :旋转位置2.jpg?direct&200 |}} |
* 公交车和卡车悬架/自动门踏板感应 | * 公交车和卡车悬架/自动门踏板感应 | ||
行 106: | 行 104: | ||
霍尔效应旋转位置传感器也可用在公交车和重卡离地高度系统中,感应悬架系统的行程。公交车利用自动踏板可降低其离地高度,方便乘客上下车。在此应用的两端都可使用霍尔效应旋转位置传感器:一个传感器监控控制杆的位置,第二个传感器部署在悬架臂或连杆上来监控离地高度。 | 霍尔效应旋转位置传感器也可用在公交车和重卡离地高度系统中,感应悬架系统的行程。公交车利用自动踏板可降低其离地高度,方便乘客上下车。在此应用的两端都可使用霍尔效应旋转位置传感器:一个传感器监控控制杆的位置,第二个传感器部署在悬架臂或连杆上来监控离地高度。 | ||
- | {{ :旋转位置3.jpg?direct&280 |}} | + | {{ :旋转位置3.jpg?direct&200 |}} |
精确的位置感应可确认车辆是否处于适合应用系统要求的正确高度,从而改进车辆上下通行的便利性。大型拖车也可利用霍尔效应旋转位置传感器来监测拖车高度,提高仓库停靠对接的效率。 | 精确的位置感应可确认车辆是否处于适合应用系统要求的正确高度,从而改进车辆上下通行的便利性。大型拖车也可利用霍尔效应旋转位置传感器来监测拖车高度,提高仓库停靠对接的效率。 | ||
行 125: | 行 123: | ||
本次设计需要通过RP2040模块驱动一个旋转位置传感器,这里采用的是一个方向脉冲型信号的512线编码器,RP2040通过脉冲捕获,检测编码器输出的信号,将编码器输出的信号显示于0.96的显示屏,同时12路LED灯用于记数编码器的旋转圈数,此外通过串口通信的方式将编码器数据发送至上位机,方便后续的数据处理与系统开发,其本次设计的系统架构框图如图所示。 | 本次设计需要通过RP2040模块驱动一个旋转位置传感器,这里采用的是一个方向脉冲型信号的512线编码器,RP2040通过脉冲捕获,检测编码器输出的信号,将编码器输出的信号显示于0.96的显示屏,同时12路LED灯用于记数编码器的旋转圈数,此外通过串口通信的方式将编码器数据发送至上位机,方便后续的数据处理与系统开发,其本次设计的系统架构框图如图所示。 | ||
+ | |||
+ | {{ ::案例20.png?500 |}} | ||
+ | |||
行 133: | 行 134: | ||
此外其中通过查阅各类资料与相关数据手册后得出编码器在旋转过程中,POUT将产生特定的脉冲信号,DIR端口将输出0或1的高低电瓶以表示旋转的方向,PR2040通过IO口中断形式捕获脉冲信号,其中编码器工作原理及信号如下图所示。 | 此外其中通过查阅各类资料与相关数据手册后得出编码器在旋转过程中,POUT将产生特定的脉冲信号,DIR端口将输出0或1的高低电瓶以表示旋转的方向,PR2040通过IO口中断形式捕获脉冲信号,其中编码器工作原理及信号如下图所示。 | ||
- | + | {{::案例7.png?direct&350|}} {{:案例4.png?350|}} | |
- | {{:案例7.png?350 |}} {{:案例4.png?450|}} | + | |
实际编码器上电后,通过示波器测试模块的DIR引脚输出和OUT输出信号,观测到的现象与数据手册一致,实际测试表明该编码器在上电后能正常工作,其中示波器测试编码器输出信号波形如下图所示。 | 实际编码器上电后,通过示波器测试模块的DIR引脚输出和OUT输出信号,观测到的现象与数据手册一致,实际测试表明该编码器在上电后能正常工作,其中示波器测试编码器输出信号波形如下图所示。 | ||
行 144: | 行 144: | ||
首先在上电后对OLED显示屏、WS2812以及串口进行初始化化配置,使其具有基础的数据显示与发送功能,其次开启IO口中断模式,使其通过中断的方式快速检测编码器产生的脉冲信号并进行捕获,通过中断的次数计算编码器的当前位置与转过的圈数以及旋转方向,检测完成后用过SPI图像协议以及RP2040特带的PIO口将数据显示于OLED显示屏与LED灯板,此外将数据通过串口的新式发送到上位机便于数据查看,其中系统软件工作流程图如图所示。 | 首先在上电后对OLED显示屏、WS2812以及串口进行初始化化配置,使其具有基础的数据显示与发送功能,其次开启IO口中断模式,使其通过中断的方式快速检测编码器产生的脉冲信号并进行捕获,通过中断的次数计算编码器的当前位置与转过的圈数以及旋转方向,检测完成后用过SPI图像协议以及RP2040特带的PIO口将数据显示于OLED显示屏与LED灯板,此外将数据通过串口的新式发送到上位机便于数据查看,其中系统软件工作流程图如图所示。 | ||
+ | |||
+ | {{ ::案例21.png?400 |}} | ||
+ | |||
行 154: | 行 157: | ||
通过对编码器的研究与数据采集,初步了解了编码器的工作原理与实际应用,在日常生活中,可将编码器应用与智能小车等一系列智能运动的控制中,通过车轮的转动带动编码器的来捕获小车的运动方向以及更加精确的控制小车的速度,以下为编码器在大学生智能汽车竞赛中的实际图片,当然编码器的应用远不止如此,更是涉及到身边的工业机械、工程机械建筑设备、石化设备、医疗设备、航空航天仪器仪表、国防工业等旋转速度和角度的测量。 | 通过对编码器的研究与数据采集,初步了解了编码器的工作原理与实际应用,在日常生活中,可将编码器应用与智能小车等一系列智能运动的控制中,通过车轮的转动带动编码器的来捕获小车的运动方向以及更加精确的控制小车的速度,以下为编码器在大学生智能汽车竞赛中的实际图片,当然编码器的应用远不止如此,更是涉及到身边的工业机械、工程机械建筑设备、石化设备、医疗设备、航空航天仪器仪表、国防工业等旋转速度和角度的测量。 | ||
- | {{ ::案例5.png?direct&300 |}} | + | {{:案例5.png?300|}} {{:案例6.png?300|}} {{::案例22.png?350|}} |
- | + | ||
#### 5.5 附件程序 | #### 5.5 附件程序 | ||
+ | <code python> | ||
+ | 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 | ||
- | from machine import Pin, SPI, ADC, UART | + | #引脚定义并初始化 |
+ | 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) | ||
- | from ssd1306 import SSD1306_SPI | + | uart = UART(0, baudrate=115200, tx=Pin(0), rx=Pin(1), bits=8, parity=None, stop=1) |
- | from astronaut import frames | + | led1.off() |
+ | led2.off() | ||
+ | led3.off() | ||
+ | led4.off() | ||
- | from board import pin_cfg | ||
- | import framebuf | + | #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 | ||
- | import _thread | + | #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)) | ||
+ | </code> | ||
- | import time | ||
- | import array | ||
- | import rp2 | ||
- | '' | ||