尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

树莓派机械键盘扩展板设计:从矩阵扫描到热插拔轴体实战

树莓派机械键盘扩展板设计:从矩阵扫描到热插拔轴体实战 1. 项目缘起为什么要在树莓派上做机械按键扩展板玩树莓派的朋友尤其是那些喜欢捣鼓复古游戏机、自制街机、智能家居中控或者各种DIY控制台的朋友肯定都遇到过一个问题树莓派自带的GPIO引脚虽然强大但直接用来接按钮、开关总觉得有点“大材小用”且不方便。特别是当你需要连接十几个甚至几十个机械按键时杜邦线会乱成一团可靠性也堪忧。这时候一块专门为树莓派3B当然也兼容其他40针GPIO的型号设计的机械按键扩展板Shield就显得非常有必要了。我最初想做这个项目是因为在搭建一个复古风格的桌面控制台。我需要一排手感清脆、反馈明确的机械按键来控制音乐播放、灯光开关甚至是一些自定义的宏命令。用薄膜按键或者触摸屏总感觉少了点“仪式感”和“操控感”。市面上的成品扩展板要么功能太单一比如只有几个按钮要么集成度太高带了屏幕、摇杆价格不菲要么就是针对特定游戏手柄布局的灵活性不够。所以我决定自己设计一块专注于“机械按键阵列”的扩展板核心目标就三个连接稳定、布局灵活、手感出色。这块“Raspberry Pi 3B Mechanic Switches Shield”本质上就是一个GPIO接口的转接和扩展板。它直接插在树莓派的40针GPIO排针上将树莓派的GPIO信号引出来并通过板载的电路将多个机械按键的开关信号规整地映射到特定的GPIO引脚上。这样一来你就不再需要为每一个按键单独焊接杜邦线也避免了接线错误和接触不良的问题。板子设计好了你只需要把喜欢的机械轴比如青轴、红轴、茶轴焊上去再盖上键帽一个专属于你的、手感一流的物理控制面板就诞生了。2. 核心设计思路与方案选型设计这样一块扩展板听起来简单但里面有几个关键点需要仔细考量。不同的选择直接决定了最终板子的成本、复杂度和用户体验。2.1 按键扫描方案矩阵扫描 vs. 直接GPIO这是最核心的电路设计决策。每个按键本质上是一个开关我们需要检测它是否被按下。直接GPIO连接每个按键独占一个GPIO引脚另一端统一接地或接VCC。树莓派程序直接读取每个引脚的电平。这种方法最简单编程直观没有任何延迟和“鬼键”多个按键同时按下导致的误识别问题。但是树莓派3B的GPIO引脚虽然多但实际可用的、适合做输入的也就20个左右。如果你需要32个甚至64个按键这种方法就完全不够用了。矩阵扫描将按键排列成行和列的矩阵。例如8行 x 8列可以管理64个按键但只需要8816个GPIO引脚。工作原理是程序循环将每一行设置为低电平输出然后读取所有列输入的状态。如果某个按键被按下对应的行列就会导通从而在读取的列数据中检测到低电平。通过行列坐标就能唯一确定是哪个按键。注意矩阵扫描是键盘领域的标准做法可以极大节省GPIO资源。但它引入了两个问题1.扫描延迟因为要逐行扫描按键检测有微小延迟但对于人手操作毫秒级来说完全无感。2.鬼键在特定情况下如同时按下三个特定位置的键可能会产生一个虚拟的按键信号。这需要通过硬件二极管或软件算法来避免。我的选择为了支持更多按键我计划至少做4x416个起步并可扩展矩阵扫描是唯一可行的方案。为了追求最好的兼容性和避免鬼键我决定为每个按键都串联一个二极管这是最稳妥的硬件防鬼键方案。虽然增加了焊接工作量和小部分成本但换来的是100%可靠的按键识别对于追求稳定的控制台项目来说是值得的。2.2 机械轴选型与键座设计既然是“机械”开关轴体的选择就是灵魂。市面上主流的是MX轴和类MX轴。Cherry MX原厂轴手感标杆质量稳定但价格较高。常见的颜色有青轴段落感最强click声最清脆适合打字和需要确认感的操作。茶轴有轻微的段落感声音比青轴小兼顾打字和游戏。红轴线性轴直上直下无段落感触发压力小适合游戏和快速连击。黑轴线性轴但触发压力比红轴大手感更重。国产轴如佳达隆Gateron、凯华Kailh Box近年来品质提升巨大手感多样价格实惠有很多创新轴体如提前段落轴、静音轴。对于DIY项目来说性价比极高。我的选择考虑到项目的成本控制和手感尝鲜我推荐使用国产热插拔轴座配合国产轴。热插拔轴座的好处是你不需要焊接轴体轴可以直接插在轴座上后期想换手感比如把青轴全换成静音红轴只需要拔下来再插上去无比方便。这大大提升了项目的可玩性和维护性。PCB设计时就要选用兼容热插拔轴座的封装通常是两个金属弹片孔。键帽方面可以选择便宜的OEM高度ABS键帽或者更有质感的PBT键帽。对于功能控制台甚至可以选择无刻键帽或者自己定制印字的键帽颜值更高。2.3 与树莓派的接口与供电树莓派3B的GPIO提供3.3V和5V电源。机械键盘轴体和LED如果你要加背光的工作电压通常是5V。但需要注意的是树莓派的GPIO引脚输入电平绝对不能超过3.3V否则可能损坏CPU。这就引出了一个关键设计电平转换。我们的矩阵扫描电路如果直接用5V供电那么按键按下时传递给树莓派GPIO的将是5V高电平这是危险的。因此必须在扩展板上设计电平转换电路。简单电阻分压对于每个输入到树莓派的信号线可以用两个电阻组成分压电路将5V降到3.3V左右。这种方法成本低但会增加元件数量和布局复杂度且对电阻精度有一定要求。专用电平转换芯片如TXS0108E等双向电平转换芯片。方案更专业、稳定但成本高且需要更多的PCB空间。利用二极管和上拉电阻这是更巧妙也是更常见的做法。将矩阵的“行”设置为输出“列”设置为输入。在树莓派端将作为输入的“列”引脚通过一个上拉电阻连接到3.3V。在扩展板上当某一行输出低电平时如果该行某列的按键被按下电流会从树莓派的3.3V上拉电阻经过按键、二极管流向行的低电平。此时树莓派读取到的该列引脚电平会被拉低接近0V。由于电流方向是从树莓派流向扩展板且回路中串联了二极管防止倒灌因此扩展板一侧的电压不会影响到树莓派的3.3V引脚。这种方法安全地实现了电平隔离无需额外转换芯片是我最终采用的方案。供电则直接从树莓派的5V引脚Pin 2或4和GND引脚取电为整个扩展板的扫描电路和可能的LED供电。3. 电路设计与PCB绘制实战确定了矩阵扫描带二极管、热插拔轴座、3.3V上拉电平隔离的方案后就可以开始具体设计了。3.1 原理图设计我使用KiCad这款免费开源软件进行设计。首先创建原理图。创建元件库需要自制两个元件符号。一个是“机械轴开关”它有两个引脚常开触点。另一个是“热插拔轴座”它对应PCB上的两个焊盘。绘制矩阵假设设计一个4行4列的矩阵。放置16个开关符号。每个开关串联一个二极管的符号注意二极管方向阴极朝向“行”线方向。连接网络将第1行的所有开关的一端通过二极管后连接在一起命名为“Row1”。同样处理Row2, Row3, Row4。将第1列的所有开关的另一端连接在一起命名为“Col1”。同样处理Col2, Col3, Col4。添加上拉电阻和接口放置4个电阻阻值通常在1kΩ到10kΩ之间我选用4.7kΩ一端分别连接到Col1-Col4网络另一端连接到名为“3V3”的网络。这个“3V3”网络最终会连接到树莓派的3.3V引脚。设计连接器放置一个2x20排针的符号代表树莓派的40针GPIO接口。将Row1-Row4网络连接到排针上你计划用作输出的GPIO引脚例如GPIO17, GPIO27, GPIO22, GPIO23。将Col1-Col4网络连接到排针上你计划用作输入并启用内部上拉或通过我们板载电阻上拉的GPIO引脚例如GPIO5, GPIO6, GPIO13, GPIO19。最后将“5V”和“GND”网络连接到排针对应的电源引脚。3.2 PCB布局与布线原理图检查无误后导入PCB编辑器。板框与定位首先定义PCB的尺寸和形状。树莓派的GPIO排针位置是固定的所以扩展板的金手指接口位置必须精确对应。测量树莓派3B上排针的间距标准的2.54mm和整体位置在PCB上放置一个对应的2x20的排母注意是母座用来插在树莓派的公针上。这是最关键的一步位置错了整个板子就废了。我通常会在KiCad中导入一张树莓派的实物图作为背景来辅助定位。元件布局将排母固定在板子底部。在板子正面Top Layer规划按键的位置。16个键可以排成4x4的网格间距遵循标准键帽的19.05mm0.75英寸间距。在每个按键位置放置热插拔轴座的封装两个独立的焊盘。将16个二极管放置在对应按键的附近最好在背面Bottom Layer以节省空间。将4个上拉电阻也放置在背面空闲区域。电源滤波电容在5V和GND入口附近放置一个100nF的陶瓷电容用于滤除高频噪声。布线电源先行先布5V和GND线。GND最好铺铜铺地可以增加稳定性和抗干扰能力。在KiCad中我通常会在背面进行大面积GND铺铜。信号线然后连接行线Row和列线Col。由于矩阵线路简单可以在背面用细线如0.3mm宽度连接。确保每条行线连接到该行所有按键的二极管阳极每条列线连接到该列所有按键的另一端。连接到排母最后将Row1-4, Col1-4以及电源线引到排母对应的焊盘。设计规则检查布线完成后一定要运行DRC检查线宽、间距、有无未连接网络等错误。3.3 打样与焊接将设计好的PCB文件Gerber格式发给PCB打样厂商。为了美观和耐用我选择了黑色阻焊油沉金工艺。沉金能让金手指更耐磨接触更好。收到PCB空板后开始焊接先焊小元件按照“先低后高”的原则先焊接电阻、二极管这些贴片元件。使用烙铁和焊锡丝或者用锡膏进行热风枪回流焊如果有条件。焊接轴座和排母然后焊接热插拔轴座和2x20的排母。排母焊接要确保所有引脚都吃锡饱满且没有连锡。最后安装轴体和键帽焊接完成后用万用表通断档检查关键线路确保没有短路或断路。确认无误后就可以将机械轴体按压进热插拔轴座然后盖上键帽。4. 软件驱动与按键功能编程硬件准备就绪后剩下的就是让树莓派识别按键了。这里提供两种主流思路。4.1 方案一使用Python GPIO库直接扫描这是最直接、最可控的方法。我们以4x4矩阵为例假设引脚连接如下行输出 Row1 - GPIO17, Row2 - GPIO27, Row3 - GPIO22, Row4 - GPIO23列输入 Col1 - GPIO5, Col2 - GPIO6, Col3 - GPIO13, Col4 - GPIO19import RPi.GPIO as GPIO import time # 定义行列引脚 rows [17, 27, 22, 23] cols [5, 6, 13, 19] # 按键映射表4x4矩阵 keys [ [1, 2, 3, A], [4, 5, 6, B], [7, 8, 9, C], [*, 0, #, D] ] def setup(): GPIO.setmode(GPIO.BCM) # 设置行引脚为输出并初始化为高电平因为我们板子上拉是3.3V行拉低才有效 for pin in rows: GPIO.setup(pin, GPIO.OUT, initialGPIO.HIGH) # 设置列引脚为输入并启用树莓派内部上拉作为双重保险即使板载电阻失效 for pin in cols: GPIO.setup(pin, GPIO.IN, pull_up_downGPIO.PUD_UP) def scan_keys(): pressed_key None for i, row_pin in enumerate(rows): # 将当前行拉低 GPIO.output(row_pin, GPIO.LOW) # 稍微延迟等待信号稳定 time.sleep(0.001) for j, col_pin in enumerate(cols): # 读取列引脚状态内部已上拉按下时为低电平 if GPIO.input(col_pin) GPIO.LOW: pressed_key keys[i][j] # 等待按键释放防抖 while GPIO.input(col_pin) GPIO.LOW: time.sleep(0.01) # 扫描完一行后将该行恢复高电平 GPIO.output(row_pin, GPIO.HIGH) # 如果检测到按键跳出循环简单处理一次只处理一个键 if pressed_key is not None: break return pressed_key def main(): setup() try: print(按键扫描开始按下CtrlC退出) while True: key scan_keys() if key: print(f按键 [{key}] 被按下) # 这里可以添加按键处理逻辑如触发命令、播放声音等 time.sleep(0.05) # 主循环延迟降低CPU占用 except KeyboardInterrupt: pass finally: GPIO.cleanup() if __name__ __main__: main()这个程序会不断扫描矩阵当检测到按键时打印键值。你可以根据key的值来执行不同的功能比如调用os.system执行命令或者控制其他GPIO设备。4.2 方案二模拟为USB键盘进阶如果你希望这块扩展板被系统识别为一个标准的USB键盘这样你可以在任何界面下使用甚至进入BIOS就需要用到USB HID功能。树莓派本身可以作为USB设备gadget模式。启用USB Gadget模式需要修改树莓派的/boot/config.txt和/boot/cmdline.txt并加载相关内核模块。这个过程相对复杂且不同系统版本Bullseye, Bookworm步骤不同。使用hid-gadget工具社区有hid-gadget这样的工具可以模拟键盘按键。你需要编写一个程序将GPIO扫描到的按键转换成对应的USB HID键值如KEY_A, KEY_ENTER等然后通过hid-gadget发送给主机树莓派自身。使用专用MCU更专业和稳定的做法是在扩展板上集成一块额外的微控制器如ATmega32U4、RP2040由这块MCU负责扫描矩阵并通过其USB接口直接将自己枚举为一个USB键盘设备。树莓派通过USB线连接到这个“键盘”上。这样完全独立不占用树莓派GPIO也更稳定。但这属于更复杂的“子项目”了。对于大多数控制台应用方案一Python直接控制更简单灵活因为你可以直接让按键触发特定的Python脚本完成任何你想做的事打开应用、发送网络请求、控制GPIO等。5. 项目扩展与进阶玩法基础功能实现后这个项目还有很多可以打磨和扩展的地方。增加背光每个轴体上可以加装LED。如果是单色LED可以串联电阻后由树莓派的GPIO直接驱动需注意电流或者用晶体管扩流。如果是RGB LED则需要使用WS2812B这类可寻址LED并连接到树莓派的一个GPIO用neopixel库控制实现炫彩灯光效果。增加编码器旋钮除了按键旋钮旋转编码器在音量调节、菜单选择上非常方便。可以预留一两个编码器的焊盘编码器同样可以通过GPIO读取。多层PCB与结构设计为了更稳固可以设计两块PCB。顶层PCB安装轴体和键帽底层PCB放置主控芯片、电阻电容等。中间用铜柱固定形成“夹心”结构更接近客制化键盘的工艺。外壳设计用亚克力板激光切割或者3D打印一个外壳将树莓派和扩展板封装进去形成一个完整的、美观的桌面设备。软件优化消抖处理上面的示例代码用了简单的延时消抖。更可靠的做法是使用状态机或中断计时器的方式来消抖。多键无冲完善扫描算法实现真正的N键无冲NKRO即使同时按下所有键也能正确识别。配置化将按键映射关系哪个物理按键对应什么功能写进配置文件甚至做一个简单的Web配置界面这样不用改代码就能重新定义按键功能。这个“Raspberry Pi 3B Mechanic Switches Shield”项目从电路设计到PCB制作再到软件编程完整地走了一遍硬件DIY的流程。它不仅仅是一块扩展板更是一个载体让你能够把对机械手感的喜爱和树莓派的无限可能结合起来创造出独一无二的交互设备。无论是作为一个学习电子设计的练手项目还是作为一个实用工具的核心部件它都能带来满满的成就感。
返回列表