量角器是一种专门的设备,用于高精度测量旋转角度,并通过USB将这些测量结果传输到主机。它集成了一个精确的编码器,能够以1度的精度测量角度。树莓派Pico通过可编程I/O (Programmable I/O)高速读取编码器信号,而TinyUSB库则用于与主机共享数据。该量角器的开发主要是为了解决在汽车驾驶模拟中需要精确测量物理方向盘的旋转角度的问题。
软件栈
为了提供所需的功能,该平台需要支持快速I/O和简单的USB处理。使用直接GPIO读取编码器信号的初步实验表明,在快速旋转过程中,信号可能部分丢失,因为直接GPIO只能处理高达~10kHz的变化。一个更好更快的选择是使用Raspberry Pi Pico上可用的可编程输入/输出(Programmable Input/Output, PIO)功能。
最初,我计划使用最简单的软件选项——MicroPython,但它缺乏对USB功能的直接支持。CircuitPython是第二个候选,但它没有完全的PIO支持。最后,我选择了c++,因为它为Raspberry Pi Pico (TinyUSB库)提供了良好的USB支持以及PIO功能。
我基于TinyUSB库中的hid_composite示例实现,并从实现中删除了除通用输入/输出设备外的所有子设备。我用一个处理基于tm1637的显示的简单类和一个带有处理编码器信号的自定义PIO代码的Encoder c++类完成了代码。
为了开发,我使用了Microsoft Visual Studio Code和官方的Raspberry Pi Pico扩展(在macOS和Windows上)。
编码器信号处理
编码器产生两相正交脉冲信号,每个相位每旋转400个脉冲。该信号的解码由PIO程序(在文件encoder.pio中)执行,该程序等待通道a上的上升沿,然后检查通道B上的值:对于0,生成IRQ 0;对于1,生成irq1。这些中断由Encoder c++类处理:irq0减少旋转计数器,而irq1增加旋转计数器。这种配置每次旋转产生400个脉冲,计数器值需要乘以360/400 = 0.9来表示以度为单位的值。
通过增加三个PIO程序,可以将测量精度提高到每旋转1600个脉冲:一个等待通道A的下降沿,另一个等待通道B的上升沿,第三个等待通道B的下降沿。
USB通信
USB处理实现基于TinyUSB库中的hid_composite示例。除通用输入/输出设备外,所有设备类型都从原始代码中删除。可以使用tests目录中的两个示例在主机设备上测试该实现:
•Test_hid.py,它使用了hid库
•Test_pyusb.py,它使用pyusb库
•构建指令
连接:
•编码器<-> RPi Pico
•VCC[红色]<-> VBus[引脚40](5V)
•GND[黑色]<-> GND[例如引脚38]
•通道A[白色]<-> GP2[引脚4]+ 10 kOhm上拉电阻至3V3[引脚36]
•通道B[绿色]<-> GP3[引脚5]+ 10 kOhm上拉电阻到3V3[引脚36]
•TM1637显示<-> RPi Pico
•CLK <-> 5[引脚7]
•DIO <-> 4[引脚6]
•VCC <-> 3V3[引脚36]
•GND <-> GND[例如引脚38]
•复位开关<-> RPi Pico
•3V3[针36]
•GP14[引脚19]
案例:
使用OpenSCAD设计的简单设备案例和插件案例可以在GitHub的案例目录中找到。