当前位置: 首页 > news >正文

基于PyGamer与旋转编码器打造复古游戏摇杆:硬件连接、3D打印与CircuitPython编程全攻略

1. 项目概述与核心思路

最近在捣鼓复古游戏和创意交互设备,发现旋转编码器这玩意儿真是个宝藏输入设备。它不像普通电位器那样有物理终点,可以无限旋转,通过检测相位差来判断方向和步数,精度高、手感好,非常适合用来做游戏里的连续控制,比如卷轴游戏的横向移动、老式街机摇杆的模拟,甚至是音乐播放器的快速选曲。手头正好有一块Adafruit的PyGamer,这是一块基于ATSAMD51微控制器的开源游戏掌机开发板,自带屏幕、按键、扬声器,还支持CircuitPython,简直是DIY的绝佳平台。于是,一个想法就诞生了:能不能给PyGamer外接一个旋转编码器,把它变成一个带“摇杆”的定制化手持设备?

这个项目的核心,就是打破PyGamer原有按键输入的局限,为其增加一个模拟摇杆或旋钮的输入维度。我们不是简单地把编码器焊上去,而是设计一个完整的、可3D打印的外壳,将编码器牢固地集成在设备右侧,形成符合人体工学的握持和操控体验。整个流程涵盖了硬件连接、3D建模与打印、软件编程(以CircuitPython为例)以及最终的组装调试。无论你是想重温需要旋钮操控的复古游戏(比如某些老式的射击或驾驶游戏),还是想为你的互动艺术项目做一个独特的输入控制器,这个方案都提供了一个从零到一的完整路径。下面,我就把自己从构思到实现的全过程,以及中间踩过的坑和总结的经验,毫无保留地分享出来。

2. 核心组件选型与原理剖析

工欲善其事,必先利其器。在开始动手之前,搞清楚我们用的核心部件是什么、为什么选它,至关重要。这能帮你理解后续每一个操作步骤背后的逻辑,甚至在出现问题时有能力自己排查。

2.1 主控平台:为什么是Adafruit PyGamer?

PyGamer并不是唯一的选择,市面上类似的板子还有GameBoy Advance造型的“PocketBeagle”或者一些基于ESP32的开发板。但我最终选择PyGamer,主要是基于以下几个硬核理由:

  1. 高度集成,开箱即用:PyGamer在一块板子上集成了1.8英寸彩色LCD屏幕、5个方向按键、4个动作按键、一个三轴加速度计、一个光传感器、一个迷你扬声器音频放大电路,以及一个锂电池充电管理芯片。这意味着你不需要再费心去为屏幕、按键、声音单独布线,大大降低了硬件复杂度,让我们可以专注于编码器这个新增功能。
  2. 对CircuitPython的顶级支持:Adafruit是CircuitPython的主要推动者,PyGamer拥有近乎完美的CircuitPython支持。这意味着你可以用Python这种高级语言来快速开发游戏和交互逻辑,无需面对C/C++复杂的编译环境和底层寄存器操作。对于快速原型开发和爱好者项目来说,开发效率的提升是巨大的。
  3. 丰富的扩展接口:板子边缘有两排标准的2.54mm间距的母座排针,引出了大量的GPIO(通用输入输出引脚)、I2C、SPI、模拟输入等接口。这为我们连接旋转编码器提供了极大的便利,不需要飞线到芯片引脚,连接可靠又整洁。
  4. 活跃的社区与生态:Adafruit围绕其硬件产品建立了极其丰富的教程、代码库(CircuitPython Libraries)和社区论坛。你几乎遇到的任何问题,都能在社区找到讨论或解决方案。这对于DIY项目能否顺利进行到底,往往起着决定性作用。

注意:PyGamer的GPIO引脚电压是3.3V,在选择外部传感器和编码器时,务必确认其工作电压兼容3.3V逻辑电平,否则可能需要电平转换电路。

2.2 输入核心:旋转编码器工作机制详解

旋转编码器是这个项目的灵魂。我们常用的这种是增量式编码器,它输出的是两路相位差90度的方波信号(通常标记为A相和B相)。

其工作原理可以这样通俗理解: 想象编码器轴连接着一个刻有均匀缝隙的圆盘。圆盘两侧,一边有一个红外发射管,另一边对应位置有两个紧挨着的红外接收管(对应A和B)。当轴旋转时,圆盘缝隙划过,接收管会接收到断续的光信号,从而产生脉冲。由于两个接收管安装位置有细微的错位,它们产生的脉冲信号在时间上就会有先后。这个先后顺序,就代表了旋转的方向。

  • 顺时针旋转:A相信号上升沿到来时,B相处于高电平。
  • 逆时针旋转:A相信号上升沿到来时,B相处于低电平。

通过检测A、B两相脉冲的边沿和它们的电平关系,微控制器就能精确判断出“往哪个方向转了多少格”。编码器每旋转一格(一个“步进”或“咔哒”感),A和B相都会输出一个完整的脉冲周期。有些编码器带有“定位感”(Detent),就是你在旋转时能感觉到明显的“卡位”,这通常意味着内部有机械结构,每“卡”一下对应一个固定的旋转角度,方便盲操作。

为什么不用电位器?电位器输出的是模拟电压值,代表一个“绝对位置”,且有旋转范围限制。而增量式编码器输出的是数字脉冲,代表“相对变化量”,可以无限旋转。对于游戏摇杆这种需要连续、无限制、快速响应的场景,编码器是更优解。而且,数字信号抗干扰能力比模拟信号强得多。

选型要点: 项目原文推荐的是Adafruit的高质量24脉冲编码器。这里的“24脉冲”指的是轴旋转一圈,A(或B)相会输出24个完整的脉冲周期。这意味着它的分辨率是每圈24步,对于大多数手动操控来说,精度和手感都足够了。你也可以选择更高分辨率(如每圈30或60脉冲)的编码器,但要注意,分辨率越高,手动快速旋转时产生的脉冲频率也越高,需要微控制器有足够快的中断响应能力。对于PyGamer和CircuitPython来说,24脉冲是一个性能与手感平衡得很好的选择。

2.3 其他关键物料清单与备选方案

除了PyGamer和旋转编码器,你还需要准备以下材料。这里我会列出原文提到的,并补充一些我的经验之选和备选方案:

  1. 连接线:建议使用多芯硅胶线。它非常柔软,便于在狭小的外壳内弯曲和整理,而且耐折。长度按原文建议剪裁120mm左右即可。
  2. 排针:为了将编码器的线可靠地连接到PyGamer的母座,我们需要公头排针。原文使用了现成的直角排针,这是一个非常聪明的做法,可以让连接线贴着电路板走,节省空间。如果没有,用普通的直排针自己弯成90度也行,但需要一把好用的尖嘴钳,小心操作避免折断。
  3. 锂电池:PyGamer内置充电电路,所以一块3.7V的锂电池是必须的。原文提到350mAh和400mAh两种。我的建议是,如果空间允许,优先选择400mAh或更大容量的。游戏运行时屏幕和声音是耗电大户,大容量电池能显著延长游玩时间。购买时注意选择带“JST-PH 2.0mm”接头的电池,这是PyGamer的标配。
  4. 扬声器:PyGamer支持贴片式蜂鸣器或带线的小喇叭。推荐使用带线的小型椭圆扬声器,音质比蜂鸣器好很多。注意其阻抗,常见的是8欧姆,与板载功放匹配即可。
  5. 3D打印耗材
    • 外壳主体:使用PLA或PETG。PLA打印容易,表面光滑,但略脆,不耐高温。PETG韧性更好,更耐用,但打印时对温度和冷却要求高一些。对于经常拿在手里玩的设备,PETG是更稳妥的选择。
    • 按键与十字键:这是体现手感的关键!强烈建议使用TPU或NinjaFlex这类柔性材料打印。原文用的NinjaFlex 85A,打印出来有橡胶般的弹性和触感,按压手感远超坚硬的PLA按键。这是提升设备“高级感”最立竿见影的一步。
  6. 螺丝:用于固定外壳上下盖。通常是M3规格,长度需要根据你设计的壳体厚度决定,原文用的是6mm长。
  7. 辅助工具:焊台、焊锡、助焊剂、吸锡带(处理焊错时用)、镊子、剥线钳、第三只手(焊接辅助架)。一套好的工具能让组装过程愉悦十倍。

3. 电路连接与硬件焊接实战

硬件连接是整个项目物理构建的基础,这一步的可靠性直接决定了后续软件调试和最终使用的稳定性。千万不能马虎。

3.1 电路图分析与引脚定义

首先,我们必须彻底理解旋转编码器如何与PyGamer对话。一个典型的带按压开关功能的旋转编码器有5个引脚:A相、B相、公共端(C,通常接地)、开关引脚(SW,按压时接通公共端)、以及有时还有一个额外的Vcc引脚(如果编码器内置上拉电阻则需要)。

然而,我们使用的这种简易编码器,通常只有3个功能引脚:A、B和SW(按压开关),其公共端已经在内部连接到了金属外壳(通过固定螺母接地)。因此,我们的接线任务就是:

  1. 将编码器的A、B、SW分别连接到PyGamer的三个GPIO引脚。
  2. 将编码器的金属外壳(公共地)与PyGamer的GND连接。

引脚分配策略: PyGamer上有大量空闲的GPIO,但我们需要选择那些既易于插接排针,又在CircuitPython中容易访问的引脚。参考原教程,他们选择了引脚5、6、9。我们来看看为什么:

  • 引脚5: 对应PyGamer板载的“B”按键旁边的那个GPIO。它没有被其他板载功能占用,是一个干净的数字IO。
  • 引脚6: 同样是一个空闲的数字IO。
  • 引脚9: 也是一个空闲的数字IO。
  • GND: 板子上有多个接地点,选择排母旁边的那个GND引脚最方便。

在CircuitPython中,这些引脚对应的对象名通常是board.D5,board.D6,board.D9。这个分配是任意的,你完全可以根据自己的布线方便选择其他引脚,只要在代码里相应修改即可。

3.2 焊接操作步骤与避坑指南

焊接是连接的艺术,也是事故高发区。按照以下步骤,可以最大程度保证成功:

  1. 预处理排针:如果你使用直排针自制直角排针,先用尖嘴钳在排针的塑料座下方,将需要弯曲的引脚小心地弯成90度。一定要夹紧引脚根部再弯,避免反复弯折导致金属疲劳断裂。弯好后,将这一小段排针(3-4针)剪下来备用。

  2. 导线准备:剪取四段约120mm长的硅胶线(建议用不同颜色区分功能,如红-电源、黑-地、蓝-A、绿-B、黄-SW)。用剥线钳剥去两端约2-3mm的绝缘皮。剥线长度宁短勿长,太长容易导致焊接时相邻导线短路。

  3. 焊接编码器端

    • 将编码器固定在“第三只手”或小台钳上。
    • 先给编码器的三个焊盘(A, B, SW)和外壳接地片上一点锡(上锡)。
    • 然后,将对应颜色的导线线芯拧紧,蘸一点助焊剂,分别焊接到A、B、SW焊盘上。焊接要快而准,烙铁温度建议在350°C左右,停留时间不要超过3秒,以免烫坏编码器内部的塑料结构。
    • 关键步骤:取一段短线,一端焊接到编码器金属外壳的接地片上,另一端与一根较长的地线(黑色)焊接在一起。这样,我们就通过这根短线,将编码器的地引出来了。最后,用热缩管或绝缘胶带包裹好所有焊点,防止短路。
  4. 焊接排针端

    • 将直角排针固定好。
    • 给排针的每个引脚上锡。
    • 将导线的另一端依次焊接到排针上。这里的顺序必须与你计划插入PyGamer的引脚顺序一致!假设我们计划将排针插入PyGamer的引脚5、6、9和GND,那么焊接时就要按这个顺序对应好A、B、SW和GND线。
    • 焊接完成后,同样用万用表的通断档,检查每根导线从编码器焊点到排针引脚是否连通,并且相邻引脚之间是否绝缘(不连通)。
  5. 最终检查:在接通电源前,做最后一次全面的视觉检查和万用表检查:

    • 检查是否有虚焊(焊点不光滑、有裂缝)。
    • 检查是否有锡珠或焊锡桥导致短路。
    • 用万用表确认VCC(本项目未使用)没有意外接到任何地方,GND与所有信号线之间没有短路。

实操心得:焊接编码器小焊盘时,我习惯使用尖头烙铁头,并配合镊子夹住导线辅助定位。先用电烙铁头同时接触焊盘和导线,然后送入焊锡丝,焊锡熔化流动包裹住两者后立即移开烙铁,保持导线不动直到焊锡凝固。这样焊点既小又牢固。

4. 3D模型设计与打印参数详解

外壳不仅是设备的“皮肤”,更是保证内部元件牢固、手感舒适、外观炫酷的关键。自己设计或修改3D模型,能让你的设备独一无二。

4.1 模型设计要点与适配性修改

原教程提供了设计好的STL文件和Fusion 360源文件。如果你直接打印,可以跳过此节。但如果你想根据自己的编码器型号、电池大小或审美进行修改,了解一些设计要点会很有帮助。

  1. 编码器安装位:这是外壳设计的核心。模型上会有一个圆孔,用于穿过编码器的轴,周围有几个螺丝孔位,用于固定编码器的螺母。你需要精确测量你的编码器面板安装部分的直径和螺丝孔距,并在模型中相应修改。如果孔开大了,编码器会晃动;开小了,根本装不进去。Fusion 360的参数化设计在这里优势巨大,修改几个尺寸参数就能快速适配不同型号。
  2. 内部结构限位:外壳内部需要有支撑柱(Standoff)来顶住PyGamer电路板,防止其晃动。这些支撑柱的位置必须与PyGamer板上的螺丝孔完美对应。同时,要为扬声器、电池、排线预留出空间,避免挤压。原设计通常已经考虑得很周全。
  3. 人体工学与按键开孔:外壳的握持部分要有一定的弧度,贴合手掌。按键和十字键的开孔必须略大于按键本身,防止卡键。对于柔性打印的按键,开孔可以更紧密一些,利用材料的弹性实现“自复位”。
  4. 散热与开口:虽然PyGamer功耗不高,但长时间运行微控制器还是会发热。可以在外壳背面设计一些格栅状的开口辅助散热,同时也能让扬声器的声音更好地传出来。

4.2 打印参数设置:刚性与柔性材料的博弈

3D打印的质量直接决定成品的外观和强度。这里分两部分讲:

外壳主体(PLA/PETG)打印设置

  • 层高:0.2mm是精度和打印时间的良好平衡。追求更光滑的表面可以选0.15mm,但时间会大幅增加。
  • 壁厚:至少2层(对于0.4mm喷嘴即0.8mm),建议3层(1.2mm)以保证强度。
  • 填充密度:15%-20%的网格填充足够应对手持设备的强度要求。太高密度除了浪费材料和时间,没有明显收益。
  • 打印速度:外壁打印速度建议40-50mm/s,内壁和填充可以稍快(60mm/s)。首层一定要慢(20-30mm/s),确保粘附牢固。
  • 支撑:这个模型通常设计为无需支撑。但如果你的模型有悬空部分,一定要生成支撑。支撑接口的密度和Z距离设置是关键,设置不当会导致拆除支撑后表面非常粗糙。
  • 热床温度:PLA用60°C,PETG用70-80°C。确保热床清洁(用酒精擦拭),必要时涂上固体胶或专用喷剂防止翘边。

柔性按键(TPU/NinjaFlex)打印设置: 打印柔性材料是另一个挑战,核心在于避免材料在挤出机里堆积和回抽时被拉丝。

  • 回抽必须关闭回抽(Retraction)。柔性材料像橡皮筋,回抽容易导致断料或堵塞。关闭回抽意味着打印移动时会有拉丝,但对于小体积的按键来说影响不大,后期可以用刀片轻轻修掉。
  • 打印速度:一定要慢!建议20-30mm/s。让挤出机有足够的时间稳定挤出柔软的耗材。
  • 挤出温度:参考耗材厂商建议,TPU通常在210-230°C,NinjaFlex在225-240°C。可以稍高一点以增加流动性。
  • 热床温度:50-60°C。同样需要涂胶增强附着力。
  • 冷却风扇:可以开启,但风速不要太高(30-50%),防止冷却过快导致层间粘合不牢。
  • 挤出倍数(Flow):可能需要微调增加(如105%),以确保层与层之间压实,没有缝隙。

踩坑记录:第一次用TPU打印按键时,我忘了关回抽,结果打印了不到5层就彻底堵头了,清理挤出机花了半小时。另外,打印柔性件时,确保耗材路径(从料盘到挤出机)尽可能顺畅,没有锐角弯折,否则极易导致送料不畅。

5. CircuitPython代码解析与游戏适配

硬件准备就绪后,我们就要赋予它灵魂——代码。我们将使用CircuitPython来读取编码器状态,并将其转化为游戏可识别的控制信号。

5.1 编码器驱动与状态读取

在CircuitPython中,我们通常使用rotaryio库来轻松处理旋转编码器。但为了更深入地理解原理,我们先从底层GPIO读取讲起。

基础轮询法(理解原理)

import board import digitalio import time # 初始化引脚 pin_a = digitalio.DigitalInOut(board.D6) # 假设A相接D6 pin_a.direction = digitalio.Direction.INPUT pin_a.pull = digitalio.Pull.UP # 启用内部上拉电阻 pin_b = digitalio.DigitalInOut(board.D9) # 假设B相接D9 pin_b.direction = digitalio.Direction.INPUT pin_b.pull = digitalio.Pull.UP last_state = (pin_a.value, pin_b.value) position = 0 while True: current_state = (pin_a.value, pin_b.value) # 状态变化检测逻辑(格雷码解码) if last_state != current_state: if last_state == (0, 0) and current_state == (1, 0): position += 1 # 顺时针 elif last_state == (0, 0) and current_state == (0, 1): position -= 1 # 逆时针 # ... 需要处理所有16种状态跳变,这里仅示例两种 print("Position:", position) last_state = current_state time.sleep(0.001) # 短暂延迟,降低CPU占用

这种方法需要自己处理所有的状态跳变,代码复杂且容易因抖动产生误判。不推荐在实际项目中使用

使用rotaryio库(推荐): CircuitPython的rotaryio库封装了所有复杂的解码逻辑,使用起来非常简单高效。

import board import rotaryio import digitalio # 初始化旋转编码器 encoder = rotaryio.IncrementalEncoder(board.D6, board.D9) # 参数是A相和B相的引脚 # 初始化按压开关(如果编码器带按下功能) button = digitalio.DigitalInOut(board.D5) button.direction = digitalio.Direction.INPUT button.pull = digitalio.Pull.UP last_position = encoder.position while True: current_position = encoder.position if current_position != last_position: print("Position:", current_position) # 判断方向 if current_position > last_position: print("Clockwise") else: print("Counterclockwise") last_position = current_position # 检测按钮是否被按下(按下时引脚为低电平) if not button.value: print("Button pressed!") # 添加一个简单的防抖延迟,或者等待按钮释放 while not button.value: pass # 等待按钮释放

rotaryio.IncrementalEncoder对象会自动在后台更新position属性,你只需要定期去读取它,并与上一次的值比较,就能知道旋转了多少步以及方向。代码简洁又可靠。

5.2 集成到游戏框架:以PyGamer Arcada库为例

PyGamer有一个强大的辅助库叫Adafruit_Arcada,它帮你处理了屏幕初始化、文件系统、音频播放等繁琐事务,让我们能更专注于游戏逻辑。原教程的“Cranky GIF Player”就是一个基于Arcada库的绝佳例子。

核心代码结构分析

  1. 初始化
    import board import rotaryio import adafruit_arcada arcada = adafruit_arcada.Arcada() arcada.display.brightness = 0.8 # 设置屏幕亮度 encoder = rotaryio.IncrementalEncoder(board.D6, board.D9)
  2. 主循环逻辑
    last_pos = encoder.position current_frame = 0 total_frames = 10 # 假设GIF有10帧 while True: new_pos = encoder.position if new_pos != last_pos: delta = new_pos - last_pos # 根据编码器移动的步数,切换GIF帧 current_frame = (current_frame + delta) % total_frames display_frame(current_frame) # 自定义函数,显示对应帧 last_pos = new_pos # 同时检测板载按键和其他事件 arcada.read_buttons() if arcada.just_pressed(adafruit_arcada.Arcada.BUTTON_A): # 处理A键按下事件 pass

将编码器映射为游戏控制: 对于游戏,我们通常不关心编码器的绝对位置,而更关心其“相对变化”。我们可以将编码器的position变化量(delta)映射到游戏角色的移动速度、方向或者菜单的光标移动上。

  • 模拟摇杆:将连续的delta值(经过缩放)作为每帧的移动速度。正delta向右/上移动,负delta向左/下移动。
  • 菜单选择:每次检测到position变化(无论变化多少),就让菜单光标向上或向下移动一项。这需要将连续的位置变化“离散化”为单个事件。
  • 数值调整:在游戏设置中调整音量、亮度等。可以将position直接映射到一个数值范围上。

性能与优化提示:在主循环中频繁读取编码器位置是没问题的。但如果你发现游戏帧率下降,可以考虑使用中断(CircuitPython的alarm模块可以模拟)来响应编码器变化,或者确保你的主循环足够快。对于24脉冲的编码器,手动快速旋转产生的脉冲频率,PyGamer的CircuitPython完全能轻松处理。

6. 整机组装、调试与问题排查

所有零件准备妥当,代码也测试通过了,最后一步就是将它们优雅地组合在一起,并解决最后可能出现的小毛病。

6.1 分步组装流程实录

  1. 安装编码器:将编码器从外壳外部塞入预留的圆孔,从内部用附带的螺母拧紧固定。不要拧得过死,以免压裂3D打印的外壳。固定好后,用手转动旋钮,应顺畅无阻,且没有明显的左右晃动。
  2. 主板预放置:先不要拧螺丝,将PyGamer主板轻轻放入下壳,对准所有的支撑柱和螺丝孔。同时,将编码器排针小心地对准主板上的母座(引脚5,6,9,GND)。观察排线是否会被主板或电池挤压。
  3. 整理内部线缆:这是保证美观和可靠性的关键。将扬声器线、编码器线沿着外壳内壁的走线槽(如果有)或空旷处布置好。可以用一点点双面胶或线缆固定扣将线缆粘在壳体内侧,防止其移动并干扰按键。特别注意扬声器线不要被螺丝柱压到
  4. 固定电池:使用一小块“蓝丁胶”或双面泡棉胶将锂电池粘在主板背面或外壳预留的电池仓内。确保电池接头不会受到拉扯。
  5. 连接所有接口:将扬声器插头插入主板上的扬声器插座,将电池插头插入主板的JST插座。最后,将编码器的排针稳稳地插入主板的母座。
  6. 合盖与紧固:将上盖对准下盖,先确保所有按键帽(特别是柔性打印的)都正确对准了主板上的微动开关。然后轻轻合上,用手按压四周检查是否有卡扣不严或零件干涉。确认无误后,用M3螺丝从四个角锁紧。螺丝不要一次性拧到底,应采用对角线顺序,轮流逐步拧紧,使外壳均匀受力,避免翘曲。
  7. 安装装饰件:最后,将3D打印的螺丝装饰盖按压进螺丝孔,装上你喜欢的旋钮或摇杆头。

6.2 上电测试与功能验证

组装完成后,不要急于狂欢,先进行系统测试:

  1. 首次上电:插入USB线或打开电池开关。PyGamer应该正常启动,屏幕亮起。如果没有任何反应,立即断电检查。
  2. 基础输入测试:运行一个简单的测试程序,该程序会在屏幕上显示编码器的位置变化和按钮按压状态。旋转旋钮,观察数值是否平滑变化,方向是否正确。按压旋钮,观察是否触发按钮事件。同时测试所有板载按键是否正常工作。
  3. 音频测试:运行一个播放声音的示例程序,检查扬声器是否发声,声音是否清晰无破音。
  4. 压力测试:快速、反复地旋转编码器,并频繁按压按钮,观察系统是否会出现卡顿、死机或输入丢失的情况。同时用手握持设备,感受一下是否有异常的发热点。

6.3 常见问题与解决方案速查表

即使按照教程操作,你也可能会遇到一些问题。下表列出了我遇到过的典型问题及其排查思路:

问题现象可能原因排查与解决步骤
屏幕不亮,设备无反应1. 电池没电或未连接。
2. USB线仅能充电,不支持数据传输/供电。
3. 主板短路(如螺丝碰触到线路)。
1. 使用可靠的USB数据线连接电脑,查看电脑是否识别出“CIRCUITPY”磁盘。
2. 检查电池接口是否插反、是否插牢。
3. 拆开外壳,检查是否有螺丝过长顶到主板背面线路,或排针焊点短路。
编码器旋转无反应1. 接线错误(A、B相接反或接错引脚)。
2. 代码中引脚定义错误。
3. 编码器内部损坏。
1. 用万用表通断档,确认A、B、SW、GND四根线从编码器到主板引脚一一对应。
2. 核对代码中rotaryio.IncrementalEncoder()初始化使用的引脚编号是否与实际焊接一致。
3. 将编码器拆下,单独用万用表测量旋转时A、B相与GND之间的通断变化,判断编码器好坏。
编码器方向相反A相和B相的接线顺序反了。最简单的方法:在代码里交换rotaryio.IncrementalEncoder()函数中两个引脚参数的顺序。无需重新焊接。
编码器计数不准(跳步)1. 机械抖动(旋钮松动)。
2. 电源噪声干扰。
3. 代码读取速度太慢,丢失脉冲。
1. 拧紧编码器固定螺母,检查旋钮与轴是否打滑。
2. 确保电源(电池)电量充足,在编码器VCC和GND之间并联一个0.1uF的陶瓷电容滤波。
3. 确保主循环执行速度足够快。避免在循环中进行耗时操作(如复杂的图像解码)。
按钮按下不灵敏或连发1. 按键帽与微动开关对位不准。
2. 微动开关本身不良。
3. 代码中缺少防抖(Debounce)处理。
1. 拆开检查柔性按键的“十字柱”是否准确顶在微动开关的中心。
2. 更换微动开关(PyGamer上的微动开关是可焊接更换的)。
3. 在代码中,检测到按钮按下后,添加一个短暂延迟(如0.05秒)或等待按钮释放后再执行动作,以消除机械抖动。
扬声器无声或破音1. 扬声器插头未插紧。
2. 扬声器线缆被挤压断裂。
3. 音量在代码中被设置为0或音频文件格式不支持。
1. 重新插拔扬声器接头。
2. 检查扬声器线缆是否完好。
3. 运行一个已知正常的音频示例程序(如Arcada库自带的示例)进行测试。
设备运行一段时间后死机1. 电源不稳定(电池老化或接触不良)。
2. 散热不良导致主控过热。
3. 代码存在内存泄漏或死循环。
1. 更换电池或检查电池接头。
2. 检查外壳是否有散热设计,尝试在不装外壳的情况下运行测试。
3. 简化你的代码,排查是否有递归调用或未释放的大内存对象。

完成以上所有步骤,你的专属PyGamer旋转编码器游戏摇杆就正式诞生了。从一堆散件到一个可以握在手中、随心操控的个性化设备,这个过程充满了动手的乐趣和解决问题的成就感。这个项目不仅仅是一个摇杆,它更是一个模板,你可以基于它,更换不同的旋钮造型,设计更酷的外壳涂装,甚至用这个编码器去控制其他完全不同的项目,比如一个音乐播放器、一个智能家居控制器,或者一个独特的艺术交互装置。硬件开源和CircuitPython的灵活性,给了我们无限的创造可能。

http://www.jsqmd.com/news/830838/

相关文章:

  • 手把手教你用nuPlan数据集和PyTorch框架训练你的第一个自动驾驶规划模型
  • 孩子考Scratch三级前,家长必看的5个核心考点与避坑指南(2023年5月真题解析)
  • 告别命令行报错:用VSCode内置终端和Git GUI工具绕过环境变量配置
  • Ubuntu系统部署Blender并配置桌面快捷启动指南
  • 终极免费激活指南:如何5分钟内搞定Windows和Office全版本激活
  • 081、多轴运动控制:前瞻与速度规划集成
  • 基于CircuitPython与精灵图技术打造可穿戴LED动画眼镜
  • Cool-Request:环境隔离下的智能请求头管理革命
  • 基于遗传算法的配电网故障重构研究【IEEE33节点】附Matlab代码
  • 3个关键问题:如何用Ryujinx在PC上解锁完整的Switch游戏体验?
  • 082、运动控制中的坐标系变换:齐次变换矩阵
  • Python TypeError: unhashable type: ‘dict‘ 的深度解析与三种实战解决方案
  • ARM GIC CPU接口寄存器解析与中断管理实战
  • Redis AOF文件膨胀危机:从‘No space left on device’告警到Bgrewriteaof实战化解
  • 别让好创意溜走!用Markdown和Git轻松管理你的专利技术交底书(附模板)
  • 如何快速掌握BepInEx:游戏插件框架终极指南
  • 软件工程中常见的三类文档分类及其典型代表,分别对应软件生命周期的不同阶段和不同角色的使用需求
  • 别再只让RGB闪了!用Arduino模拟输出(PWM)实现平滑色彩过渡的3个创意项目
  • Linux 下用火焰图进行性能分析
  • 国产多模态大模型图文检索:从原理到产业,一篇讲透
  • 芯片公司自建GitLab服务器:架构设计、部署与优化实战指南
  • ChromePass:3分钟找回Chrome浏览器所有已保存密码
  • 西门子200PLC步进控制进阶:巧用SM66.7状态完成位实现精准脉冲序列
  • ElevenLabs中文TTS效果翻倍:从断句生硬到情感连贯,5步完成声学模型微调(附可复现config模板)
  • 13.青岛报考CPPM与SCMP,职场进阶优选众智商学院 - 众智商学院课程中心
  • 「试讲不满意居然真的可以换老师再试讲一次」——南京鼓楼区一位小学生家长的使用南京大学家教网的体验手记 - 教育资讯板
  • 深度解析yuzu模拟器:从入门到精通的全方位指南
  • D3KeyHelper:暗黑3终极图形化按键助手完全指南
  • 免费额度用完即封号?ElevenLabs底层配额机制首度曝光,3类高危操作请立即停止!
  • DIY音乐响应LED领带:基于VU表原理的可穿戴电子制作指南