基于CircuitPython的巨型机械键盘:从嵌入式开发到定制输入设备实践
1. 项目概述:当机械键盘遇上“巨无霸”
如果你和我一样,对机械键盘那清脆的段落感和扎实的敲击感着迷,同时又是个喜欢动手折腾的硬件爱好者,那么这个项目绝对能让你眼前一亮。我们这次要做的,不是常规的60%或87键键盘,而是一个只有三个按键的“巨无霸”——一个基于CircuitPython的巨型机械键盘。这三个按键,分别对应着经典的“Ctrl”、“Alt”和“Delete”。想象一下,当你需要强制关闭一个卡死的程序时,不是用指尖轻轻一点,而是抡起拳头,“砰”地一声砸在那个硕大的红色Delete键上,那种解压感和仪式感,是任何普通键盘都无法给予的。
这个项目的核心,远不止是做一个大号的玩具。它本质上是一个绝佳的嵌入式开发与硬件交互的入门实践。我们通过Kailh的巨型轴体作为输入设备,利用Adafruit的Circuit Playground Express(后文简称CPX)这款功能丰富的微控制器作为大脑,再借助CircuitPython这一对初学者极其友好的编程语言,将物理世界的按压动作,转化为计算机能够理解的USB HID(人机接口设备)键盘指令。整个过程涵盖了从结构设计、电路焊接到嵌入式编程的完整链条,非常适合想要从纯软件跨入硬件领域,或者希望给某个特定场景(比如演讲控制、游戏宏、艺术装置)制作一个夸张而有趣的定制化输入设备的创客朋友。
我选择CPX和CircuitPython组合,原因很简单:高效且友好。CPX板载了加速度计、光线传感器、温度传感器、蜂鸣器以及10个可编程RGB NeoPixel灯珠,几乎是一个“瑞士军刀”式的开发板,为我们后续的功能扩展留足了空间。而CircuitPython作为MicroPython的一个分支,其语法与标准Python高度一致,无需复杂的编译环境,通过USB线连接电脑,直接像操作U盘一样拖拽代码文件就能运行,极大地降低了硬件编程的门槛。接下来,我会带你一步步从零开始,复现这个充满乐趣的“大家伙”。
2. 核心硬件选型与设计思路拆解
2.1 为什么是“巨型轴体”与CPX?
项目的起点是三个Kailh的“Big Switch”系列轴体。这类轴体尺寸通常是标准MX轴的数倍,内部结构与微动开关类似,但保留了机械轴的触发手感(有青轴的咔哒声、红轴的线性无段落、黄轴的轻微段落感)。选择它们,首先是为了那个无可替代的视觉冲击力和操作体验。其次,从硬件连接角度看,大轴体意味着更大的焊盘和引脚间距,对于新手焊接来说容错率更高,不容易因为手抖而造成焊盘损坏或短路。
主控选择Circuit Playground Express,则是经过深思熟虑的。市面上能运行CircuitPython的板子很多,比如ItsyBitsy、Feather系列等。CPX的核心优势在于其极高的集成度和开箱即用的体验。它原生支持USB HID,意味着我们无需额外编写复杂的驱动代码,就能让它被电脑识别为键盘或鼠标。板载的10个NeoPixel LED,我们可以直接编程用来做按键状态反馈(比如按Ctrl亮蓝色,按Alt亮黄色,按Delete亮红色),这省去了额外焊接LED和编写底层通信协议的麻烦。其多个模拟/数字输入输出引脚,也足以应对三个轴体及其独立LED的控制需求。
注意:如果你手头没有CPX,理论上任何支持CircuitPython和USB HID的开发板都可以替代,例如Adafruit的KB2040、RP2040驱动的板子等。但需要根据板子的引脚定义重新调整代码中的引脚映射,并确认其CircuitPython固件是否包含
adafruit_hid库。
2.2 框架结构:简单可靠的木制方案
原项目采用了3/4英寸(约19mm)见方的木榫条来搭建框架,这是一个非常聪明且成本低廉的方案。木材质地易于加工(手锯即可),结构强度足够支撑轴体和我们的操作力度,并且外观有一种质朴的创客风格。框架设计成一个简单的长方形底座,中间开出三个方孔放置轴体。这里的关键尺寸是方孔之间的间距,需要确保轴体放入后稳固,且手指(或拳头)在操作一个键时不会误触相邻的键。
我实际制作时,在原方案基础上做了一点加固:在框架底部的四个角各加了一段30mm的短木条作为“脚垫”,这不仅能防止框架在桌面上滑动,也抬高了底板,让从底部引出的线材有更多空间,避免被压到。整个结构仅靠木工胶粘接,对于这种受力主要是垂直压力的结构来说完全足够,比使用螺丝或钉子更简洁美观。
2.3 电路设计:理解共地与独立控制
电路连接是整个项目的“经脉”,理解其原理至关重要。每个巨型轴体都有四个引脚:两个是开关引脚(通常是一银一铜),两个是LED引脚(长正短负)。我们的目标是实现:按下开关,触发键盘信号;同时,点亮该开关对应的独立LED作为视觉反馈。
电路设计采用了“共地”方案。这意味着所有元件(三个开关、三个LED)的负极(GND)都连接到了同一个公共接地端,即CPX板上的GND焊盘。这样做的好处是极大地简化了布线,我们只需要一根较粗的黑线作为“地线总线”,串联起所有需要接地的点。
正极(电源)则需要进行独立控制。每个开关的正极(信号端)需要连接到一个独立的数字输入引脚(配置为上拉输入模式),这样CPX才能区分是哪个开关被按下了。每个LED的正极则需要连接到一个独立的数字输出引脚,以便程序可以单独控制其亮灭。为此,我们需要CPX提供6个独立的IO口(3个输入给开关,3个输出给LED)。CPX的A2-A7这六个模拟引脚,同时也可以作为数字IO使用,正好满足需求。
为了保护LED,每个LED的正极回路中都串联了一个10Ω的限流电阻。这是必须的,否则直接连接3.3V电源可能会因电流过大而烧毁LED。电阻值的选择基于欧姆定律和LED的特性。假设白色LED正向电压约3V,CPX工作电压3.3V,那么电阻需要分担约0.3V的压降。如果期望LED电流在20mA左右,根据 R = V / I,电阻约为15Ω。原方案选用10Ω是一个比较保守且能保证亮度的值,电流大约在30mA,在CPX单个引脚驱动能力(通常~20mA)的临界点但通常可以工作,为了更稳妥,你也可以使用15Ω或20Ω的电阻。
3. 从零开始:硬件搭建全流程实录
3.1 木制框架的切割与组装
首先处理木榫条。你需要一根截面为3/4英寸(约19mm)见方,长度至少36英寸(约914mm)的木榫条。使用钢尺和铅笔精确标记需要切割的长度:
- 长边:2根,每根240mm。这是框架的主体长度。
- 短横撑:4根,每根55.5mm。它们将作为支撑,决定两个长边之间的间距,同时也是承载轴体的“梁”。
- 脚垫:4根,每根30mm。用于制作底座抬高的脚。
实操心得:切割时务必保证截面平直且与木条垂直。你可以使用一个简单的直角尺或利用桌角作为参考。如果切口有毛刺,用砂纸稍微打磨一下,这样在粘合时接触面更紧密,强度更高。
组装从主体框架开始。在干净的工作台上,将两根240mm的长条平行放置,间距正好是55.5mm。在每根55.5mm短横撑的两端涂上足量的木工白乳胶,然后将其卡在两根长条之间。关键点来了:你需要确保四根短横撑之间的间距也是55.5mm。因为Kailh巨型轴体的底座宽度大约是50mm,留出55.5mm的间距,既能严丝合缝地卡住轴体,又能为轴体两侧的卡扣留出活动空间。你可以先不用胶水,用直角尺辅助摆放,确认所有间距准确无误后再统一上胶。
使用F夹或简单的夹具将框架夹紧。检查整体是否方正,长边是否平行。然后静置至少一小时,让胶水初步固化。接下来,在四个角的内侧底部,粘上30mm的脚垫。同样用夹具固定,等待胶水完全干透(建议放置24小时以达到最大强度)。
3.2 焊接基础:LED与电阻的预处理
在将电路安装到框架上之前,最好先完成所有元件的“预加工”。这会让后续步骤清晰很多。
- LED引线处理:取出三个10mm白色雾状LED。注意LED有极性:较长的引脚是正极(阳极),较短的引脚是负极(阴极)。用尖嘴钳将每个LED的两个引脚分别弯成90度的小钩状,便于后续焊接导线。然后,剪取大约15cm长的导线。强烈建议遵循电工惯例:用黑色导线连接所有负极(阴极),用红、黄、蓝或其他颜色的导线分别连接三个LED的正极。这样在复杂的接线中才不会搞混。
- 焊接与绝缘:将黑色导线焊接到LED的短脚(负极),彩色导线焊接到长脚(正极)。在焊接彩色导线(正极)的这一端,先串联焊接上一个10Ω的直插电阻。你可以将电阻的一个引脚与LED长脚焊接在一起,再将导线焊接到电阻的另一个引脚上。完成焊接后,必须使用热缩管进行绝缘。剪一小段热缩管套在焊接点上,用热风枪或打火机(小心操作)轻轻加热,使其收缩并紧密包裹焊点,防止任何可能的短路。因为加了电阻,正极这一侧的焊点会稍大,可能需要直径3mm的热缩管,而负极侧用2mm的即可。
- 开关引脚上锡:用烙铁给每个轴体的四个金属引脚(两个开关引脚,两个LED引脚)预先上一层薄薄的焊锡。这个步骤叫做“搪锡”或“预上锡”,能让你后续焊接导线时更快、更牢固。操作要领是:烙铁头接触引脚并加热约1秒后,送入焊丝,焊丝熔化后迅速移开。切忌长时间加热,否则可能烫坏轴体内部的塑料结构或弹片。
3.3 框架内部的布线艺术
现在,将三个轴体放入框架的三个格子中。按照你喜欢的顺序排列,我遵循了原项目的顺序:左(蓝轴/Ctrl)、中(黄轴/Alt)、右(红轴/Delete)。
接下来是体现“共地”布线智慧的时候了:
- 建立“地线总线”:取一根较长的黑色导线(约20cm),将其一端剥开,缠绕并焊接在**第一个轴体(Switch 1)的银色开关引脚(Pin 1)**上。这个引脚在电路中我们将它定义为接地端。
- 串联所有接地端:再剪两段较短的黑色导线,用它们将Switch 1的银色引脚,与Switch 2、Switch 3的银色引脚依次串联起来。这样,三个开关的接地端就通过黑色导线连成了一体。
- 连接LED负极:将三个LED的黑色负极导线,分别焊接在对应轴体的LED负极引脚上。注意,LED的负极引脚通常也是银色的,但它是独立的,不要和开关的银色引脚混淆。虽然它们最终都通向GND,但在此处我们遵循“星型接地”的变体,先汇集到开关接地端,再统一引出。
- 连接开关信号线:剪三段彩色导线(建议用不同于LED正极的颜色,比如绿、白、紫),分别焊接在三个轴体的**铜色开关引脚(Pin 2)**上。这三根线就是信号线,之后会连接到CPX的A7, A5, A3。
- 连接LED正极线:将之前预处理好的、带电阻的LED正极彩色导线,焊接在对应轴体的LED正极引脚上。这三根线之后会连接到CPX的A6, A4, A2。
完成以上步骤后,你的每个轴体上应该都有:一根从银色开关引脚引出的“地线总线”、一根连接LED负极的黑线、一根连接开关信号端的彩色线、一根连接LED正极(带电阻)的彩色线。检查所有焊点是否饱满、圆润,没有虚焊或毛刺。
3.4 与大脑(CPX)的最终连接
现在,将CPX用尼龙搭扣或强力双面胶固定在框架的前侧或侧面,选择一个方便插USB线且不影响按键操作的位置。
参照下面的连接表,将来自框架的所有导线,连接到CPX对应的焊盘上。CPX的焊盘很大,非常适合手工焊接。
| 导线来源 | 连接到CPX引脚 | 功能说明 |
|---|---|---|
| 来自Switch 1银色引脚的长黑线 | GND | 整个系统的公共接地 |
| Switch 1 铜色引脚信号线 | A7 | 检测Switch 1(Ctrl)是否按下 |
| Switch 1 LED正极线(带电阻) | A6 | 控制Switch 1的LED |
| Switch 2 铜色引脚信号线 | A5 | 检测Switch 2(Alt)是否按下 |
| Switch 2 LED正极线(带电阻) | A4 | 控制Switch 2的LED |
| Switch 3 铜色引脚信号线 | A3 | 检测Switch 3(Delete)是否按下 |
| Switch 3 LED正极线(带电阻) | A2 | 控制Switch 3的LED |
重要提示:在通电前,务必、务必、务必用万用表的通断档或肉眼仔细检查所有连接!重点检查:1)是否有导线短路(特别是正极和地线之间);2)LED的正负极是否接反;3)信号线是否连接到了正确的引脚。确认无误后,再进行焊接。焊接到CPX时,动作要快而准,避免烙铁长时间接触焊盘导致过热损坏。
4. CircuitPython编程深度解析
4.1 环境搭建与代码结构剖析
硬件连接妥当后,我们进入编程环节。首先确保你的CPX已经安装了最新版本的CircuitPython。访问Adafruit官网的CircuitPython板块,下载对应CPX的.uf2文件。按住CPX上的复位按钮,同时通过USB连接到电脑,直到出现一个名为CPLAYBOOT的U盘,将下载的.uf2文件拖入即可完成固件烧录。之后,电脑会识别出一个名为CIRCUITPY的U盘,这就是我们的代码存储和运行空间。
将提供的代码保存为code.py,放在CIRCUITPY盘的根目录。一旦保存,代码会自动开始运行。现在,我们来深入理解这段代码的每一部分。
代码开头导入了一系列必要的库:
time:用于控制循环速度。board:定义了CPX上所有引脚的名称(如board.A7),是硬件抽象的关键。neopixel:用于控制板载的10个RGB LED。usb_hid,adafruit_hid.keyboard等:这是实现USB键盘功能的核心库。它让CPX可以模拟键盘发送按键信号。
初始化部分定义了硬件映射关系:
buttonpins = [board.A7, board.A5, board.A3] # 三个开关连接的引脚 ledpins = [board.A6, board.A4, board.A2] # 三个独立LED连接的引脚 buttonkeys = [Keycode.CONTROL, Keycode.ALT, Keycode.DELETE] # 每个开关对应的键值这三个列表的顺序必须严格对应,即索引0代表第一个开关(蓝轴),索引1代表第二个(黄轴),索引2代表第三个(红轴)。
4.2 核心逻辑:状态检测与事件处理
程序的核心是一个while True无限循环,以大约每秒100次(time.sleep(0.01))的速度扫描三个开关的状态。
这里运用了一个经典的“边缘检测”算法来准确捕捉按键的“按下”和“释放”事件,而不是单纯的状态。它使用了两个状态列表:
buttonspressed:存储当前循环周期中,每个开关的状态(True为按下,False为释放)。buttonspressedlast:存储上一个循环周期中,每个开关的状态。
逻辑判断如下:
- 读取引脚电平:由于我们设置了内部上拉(
Pull.UP),当开关未按下时,引脚通过内部电阻连接到高电平(3.3V),读取值为True。当开关按下,引脚被短接到GND(0V),读取值为False。所以代码中判断if button.value is False意味着开关被按下。 - 检测“按下事件”:如果当前状态是按下(
False),且上一次状态是未按下(buttonspressedlast[i] is False),则判定为一次新的“按下事件”,触发pressbutton(i)函数。 - 检测“释放事件”:如果当前状态是未按下(
True),且上一次状态是按下(buttonspressedlast[i] is True),则判定为一次“释放事件”,触发releasebutton(i)函数。
pressbutton和releasebutton函数分别做了三件事:点亮/熄灭对应的独立LED、通过kbd.press(k)或kbd.release(k)发送对应的键盘按键按下/释放信号、在串口打印日志(方便调试)。
4.3 视觉反馈的进阶玩法:NeoPixel混色
除了独立LED,CPX自带的10个NeoPixel LED提供了更炫酷的视觉反馈,代码中lightneopixels()函数实现了混色逻辑:
- 单按:按下Ctrl(蓝轴),所有NeoPixel显示蓝色
(0,0,255);按下Alt(黄轴),显示黄色(127, 64, 0)(RGB值模拟黄色);按下Delete(红轴),显示红色(255,0,0)。 - 组合按:这是最有趣的部分。代码检测了特定的组合状态。例如,当Ctrl和Alt同时按下(但Delete没按)时,显示绿色
(0,255,0)。当三个键全部按下时,显示白色(255,255,255)。这种通过颜色混合来直观反映组合键状态的设计,极大地增强了交互的直观性和趣味性。
你可以轻松修改这个函数,定义属于自己的颜色逻辑。比如,改成呼吸灯效果,或者根据按下的顺序播放一段灯光动画。
5. 功能自定义与扩展思路
5.1 修改按键映射
这是最直接的自定义需求。你想把这巨型键盘变成什么?游戏快捷键?多媒体控制键?还是演示文稿翻页器?只需修改buttonkeys列表即可。
例如,想做成一个Mac版的“强制退出”快捷键(Command+Option+Esc):
buttonkeys = [Keycode.GUI, Keycode.ALT, Keycode.ESCAPE]想做成一个简单的音乐播放控制器(播放/暂停、上一首、下一首):
buttonkeys = [Keycode.F7, Keycode.F8, Keycode.F9] # 假设你的播放器用这些功能键你需要参考adafruit_hid.keycode模块中定义的所有键值。在CircuitPython中,你可以通过查看库文件或在线文档找到支持的所有Keycode,如Keycode.SPACE,Keycode.ENTER,Keycode.LEFT_ARROW等。
5.2 利用CPX的传感器扩展功能
CPX的板载传感器为这个巨型键盘赋予了无限可能。你可以编写代码,让按键功能根据环境变化:
- 光感控制:通过
light_sensor读取环境光强度。在黑暗环境下,按下某个键触发“夜间模式”,降低屏幕亮度;在明亮环境下,触发“日间模式”。 - 动作触发:利用
accelerometer加速度计。敲击键盘框架本身(而不仅仅是按键)来触发某个动作,比如摇晃框架模拟“撤销”操作(Ctrl+Z)。 - 声音反馈:使用
speaker蜂鸣器。为不同的按键配上不同的音效,让每次按压都声临其境。 - 温度显示:按下某个组合键,让NeoPixel用颜色表示当前环境温度(通过
temperature传感器读取)。
5.3 项目变体与进阶挑战
掌握了核心原理后,你可以尝试更多变体:
- 无线化:将CPX换成支持蓝牙HID的板子,如Adafruit的Circuit Playground Bluefruit,制作一个无线的巨型演示器或游戏控制器。
- 增加更多输入:CPX还有多余的引脚(如A0, A1, TX, RX)和两个物理按钮(A、B)。你可以接入更多的开关、旋钮(电位器)或滑块,制作一个功能丰富的宏键盘或模拟控制器。
- 改变外观与交互:抛弃木框架,用亚克力激光切割、3D打印设计更酷的外壳。甚至可以把轴体换成其他巨大的触发装置,比如脚踏开关,做成一个“脚部Ctrl+Alt+Delete”。
- 集成到智能家居:通过CPX的网络功能(需额外模块),让按下Delete键的同时,不仅强制关闭电脑程序,还通过MQTT协议关闭家里的智能灯,打造一个极具戏剧性的“下班/崩溃”仪式感开关。
这个项目的魅力在于,它用一个极其简单和有趣的形式,包裹了嵌入式开发中从数字输入输出、USB HID通信到传感器应用等多个核心概念。当你亲手焊完最后一根线,敲下代码,并看到自己制作的“庞然大物”真的能控制电脑时,那种成就感是购买任何成品都无法比拟的。它不仅仅是一个键盘,更是一个属于你自己的、可编程的物理交互接口。
