1. 项目缘起:为什么选择60%配列与XIAO RP2040?
如果你和我一样,桌面空间有限,或者厌倦了每次打字都要大幅度移动手臂,那么60%配列的键盘绝对是一个值得尝试的“退烧”选择。它砍掉了数字小键盘、功能键区和方向键区,只保留了最核心的字母、数字和部分修饰键,通过组合键(Layer)来实现所有功能。这种极简设计带来的不仅是桌面空间的解放,更是一种高效、专注的输入体验。我给自己这个60%键盘项目起名“Purple Owl”(紫枭),一方面是喜欢紫色带来的神秘与科技感,另一方面,猫头鹰象征着在黑夜(或复杂的代码中)也能精准定位,这很符合DIY键盘时那种不断调试、寻找问题根源的状态。
那么,核心控制器为什么是Seeed Studio的XIAO RP2040,而不是更常见的Arduino Pro Micro或者专门的开源键盘主控(如QMK支持的ATmega32U4系列)?这里有几个非常实际的考量。
首先,是成本与性能的极致平衡。XIAO RP2040板载了树莓派基金会那颗大名鼎鼎的RP2040双核ARM Cortex-M0+处理器,主频133MHz,性能远超8位AVR单片机。这意味着你可以运行更复杂的键位逻辑、宏定义,甚至在上面跑一些轻量级的自定义程序。而其价格却非常亲民,与一块Pro Micro相差无几,性价比极高。
其次,是极致的体积与接口友好度。XIAO RP2040的尺寸只有21mm x 17.5mm,比你的大拇指指甲盖大不了多少,这为紧凑的60%键盘PCB布局留下了巨大空间。它原生支持USB Type-C接口,正反插拔的便利性在2024年的今天已经是刚需。板载的RGB LED和可编程按钮虽然在这个键盘项目中不一定用得上,但也提供了额外的扩展可能性。
第三,也是最重要的一点,是开发环境的友好性。RP2040完美支持CircuitPython,这是一种基于Python 3的微控制器编程语言。对于键盘固件,我们可以直接使用基于CircuitPython的KMK固件。KMK的语法非常直观,配置键盘矩阵、定义层、设置组合键就像写Python脚本一样简单,完全避免了传统QMK固件需要搭建本地编译环境、学习C语言的陡峭学习曲线。你只需要一个文本编辑器,修改一个code.py文件,保存后键盘会自动重新加载配置,调试效率提升了不止一个量级。
最后,是社区与生态。Seeed Studio提供了完善的中文文档和社区支持,RP2040和CircuitPython在全球都有庞大的用户群,遇到问题很容易找到解决方案。这对于一个DIY项目能否顺利从“想法”走到“成品”至关重要。
所以,“Purple Owl”项目的核心就是:利用XIAO RP2040的强大性能和易用性,结合60%配列的极简美学,打造一把完全个性化、易于二次开发且成本可控的客制化键盘。接下来,我将从PCB设计开始,带你一步步实现它。
2. PCB设计实战:从原理图到布局布线的完整流程
键盘的PCB是整个项目的骨架,它决定了键盘的电气连接、结构强度和最终手感。设计PCB是一个系统工程,需要兼顾电气特性、机械结构和生产工艺。我使用国产的立创EDA(专业版)来完成设计,它对个人用户免费且功能强大,云端操作也省去了安装软件的麻烦。
2.1 原理图设计:定义键盘的“神经网络”
原理图是PCB的逻辑蓝图。对于键盘,核心是按键矩阵。60%标准配列通常有61个键,我们不可能为每个键单独拉一根线到主控,那样需要67个IO口(61个键+至少6个其他功能)。矩阵扫描的原理是将按键排列成行和列,通过扫描行线、读取列线状态来检测哪个键被按下,61个键的矩阵可以压缩到仅需17个IO口(例如8行9列)。
在立创EDA中新建原理图:
- 创建元件库:首先需要创建键盘的专属元件。主要是两种:MX轴体的热插拔轴座(如凯华或佳达隆的PCB热插拔插座)和Type-C接口。可以从立创商城找到对应的元件,生成原理图符号和PCB封装。对于轴座,注意区分正反面,原理图符号要标明引脚1的位置。
- 绘制矩阵:放置61个轴座符号,并按照你设计的键位布局(Layout)在心理上或纸上先规划好行列。例如,将同一行的所有轴座的其中一个引脚(比如上引脚)连接在一起,形成“行线”;将同一列的所有轴座的另一个引脚连接在一起,形成“列线”。
- 连接主控:放置XIAO RP2040的原理图符号。你需要仔细阅读其数据手册,找到所有GPIO引脚的定义。选择足够数量的GPIO(至少17个)作为矩阵的行线和列线。一个关键技巧:尽量选择同一Bank(组)的GPIO,并且预留一些备用IO,方便后期调试或增加功能(如RGB底灯、旋钮编码器)。将行线、列线分别连接到选定的GPIO上。
- 添加必要电路:
- Type-C接口:除了VBUS、GND、D+、D-,别忘了连接CC1和CC2引脚(通常通过5.1k电阻下拉到地),这是实现正反插拔和USB PD通信(虽然这里用不上)所必需的。
- 去耦电容:在XIAO RP2040的电源引脚(3V3)附近,放置一个0.1uF和一个10uF的陶瓷电容,用于滤除电源噪声,确保芯片稳定工作。
- ESD保护:在USB数据线(D+/D-)上可以串联小阻值电阻(如22欧姆)并添加ESD保护二极管到地,增强抗静电能力,这是一个提升可靠性的好习惯。
- 复位电路:XIAO板载了复位按钮,原理图中可以不用额外添加。
绘制完成后,务必使用立创EDA的ERC(电气规则检查)功能,检查是否有未连接的网路、短路、单端网络等错误。
2.2 PCB布局:在有限空间内排兵布阵
原理图检查无误后,进入PCB设计环节。点击“设计”->“转换原理图到PCB”,软件会根据你的原理图生成一个充满杂乱飞线的PCB初稿。
- 板框定义:首先确定键盘的物理尺寸。60%键盘的外形尺寸(长宽)和螺丝孔位(通常为M2)需要与你的外壳设计(或购买的外壳)严格匹配。在“Mechanical 1”层绘制板框,并放置螺丝孔(作为非镀铜的NPTH孔)。
- 预布局:先将所有元件大致拖到板框内。将XIAO RP2040模块、Type-C接口放在PCB的顶部或底部中间位置,方便出线。61个轴座按照键位图严格对齐。这里有个大坑:不同键帽的菊花位置(十字柱)是标准化的,但轴体本身的针脚(两个金属脚和中间的LED灯脚)位置也是固定的。你必须确保轴座的封装方向正确,否则轴体插不进去!建议先打印1:1的键位图,或者用现成的开源PCB文件作为位置参考。
- 布局优化原则:
- 信号流清晰:矩阵走线应尽量从主控向外辐射,减少交叉。
- 电源优先:先布置电源路径(VBUS到3V3 LDO),保证电源线宽足够(通常1mm以上)。
- 模块化:将功能相关的元件(如主控及其去耦电容)靠近放置。
- 考虑结构:避开螺丝孔、外壳支柱、定位板卡扣等位置。
2.3 PCB布线:艺术与技术的结合
布线是PCB设计中最耗时也最体现功力的部分。键盘PCB的布线相对简单,主要是低速数字信号,但仍有讲究。
- 规则设置:在布线前,先设置设计规则(Design Rules)。对于这种双层板,我的常用设置是:
- 线宽:信号线0.25mm,电源线0.5mm-1mm。
- 线间距:0.2mm(嘉立创的工艺能力可以做到0.15mm,但0.2mm更稳妥)。
- 过孔:外径0.6mm,内径0.3mm(这是嘉立创的免费打样标准)。
- 铺铜间距:0.3mm。
- 矩阵布线:
- 行线/列线分组:尽量将同一行或同一列的走线布在同一层(比如顶层),另一层(底层)用于交叉连接和电源。这能使走线更规整。
- 使用“差分对”思维处理长走线:虽然不是高速差分信号,但对于同一组(如相邻的两行列线)的长距离平行走线,尽量保持它们长度近似、走向一致,可以减少干扰,也更好看。
- 善用跳线:在双层板中,过孔(Via)就是你的跳线。当顶层走线无法绕过时,打一个过孔换到底层继续走,这是完全正常的。但要注意过孔不要太多太密,尤其是信号线换层后,最好在附近打回原层,形成完整的参考平面。
- 电源与地处理:
- 电源通道:从Type-C的VBUS到XIAO的VIN引脚,线宽要加粗。XIAO模块内部有LDO将5V转为3.3V。
- 地平面:这是最关键的一步。在布线基本完成后,对顶层和底层进行大面积铺铜(Pour Copper),并连接到GND网络。一个完整的地平面可以提供稳定的参考地,屏蔽噪声,是电路稳定工作的基石。在立创EDA中,使用“铺铜”工具,选择GND网络,设置好间距,框选整个板框即可。
- DRC检查与丝印调整:布线完成后,运行DRC(设计规则检查),确保没有违反你设定的线宽、间距、孔距等规则。然后调整丝印层(Silkscreen),将元件标识(如R1, C1)和方向标记摆放整齐、清晰,不要被焊盘或过孔挡住。可以在PCB空白处添加你的键盘Logo(如“Purple Owl”)和版本号。
踩坑实录:嘉立创DRC规则与过孔放置在放置过孔时,立创EDA可能会提示“过孔不在DRC规则范围内”。这通常是因为过孔太靠近板框或机械孔。嘉立创的工艺要求孔边缘到板边缘、到其他铜皮/走线需保持一定距离(通常0.2mm以上)。解决方法是:要么移动过孔位置,要么在嘉立创的订单页面,选择“扩展工艺参数”,并适当增加“板边孔距”的补偿值。最稳妥的办法是,在布局阶段就预留好足够的空间。
最后,导出Gerber文件和钻孔文件,就可以发给PCB制造商(如嘉立创)打样了。第一次打样建议选择最便宜的套餐,做两三块回来测试,确认无误后再进行后续步骤。
3. 固件烧录与KMK配置:让键盘“活”起来
PCB焊接组装完成后,它还是一块“哑巴”板子。我们需要通过固件赋予它灵魂。得益于CircuitPython和KMK,这个过程比传统方式简单太多。
3.1 环境准备与CircuitPython刷入
- 获取固件:访问CircuitPython官网,找到Seeed XIAO RP2040的专用
.uf2固件文件并下载。 - 进入Bootloader模式:用USB线连接XIAO和电脑。快速双击XIAO板载的复位按钮(RST),此时电脑上会出现一个名为
RPI-RP2的可移动磁盘。如果没出现,检查USB线是否支持数据传输,或者尝试在按住BOOT键的同时按一下RST再松开。 - 刷入固件:将下载好的
.uf2文件直接拖入RPI-RP2磁盘。磁盘会自动弹出,几秒钟后,电脑上会出现一个新的磁盘,名为CIRCUITPY。这表明CircuitPython已经成功运行在XIAO上了。
3.2 KMK固件部署与基础配置
KMK本质上是一个运行在CircuitPython上的Python键盘程序。
- 获取KMK文件:访问KMK的GitHub仓库,下载最新版本的KMK。你需要的是
kmk文件夹内的全部内容。 - 文件部署:将
kmk整个文件夹,以及KMK仓库中boot.py和main.py示例文件,复制到CIRCUITPY磁盘的根目录下。然后,将main.py重命名为code.py。CircuitPython在启动时会自动执行code.py。 - 核心配置:
kb.py这是键盘的主配置文件。我们需要在CIRCUITPY磁盘根目录创建它。以下是一个最基础的60%配列配置框架:
import board from kmk.kmk_keyboard import KMKKeyboard from kmk.scanners import DiodeOrientation from kmk.scanners.keypad import KeysScanner # 初始化键盘对象 keyboard = KMKKeyboard() # 1. 定义引脚 # 你需要根据你的PCB实际布线,填写行和列对应的GPIO引脚 # 引脚名参考 CircuitPython 的 board 模块,如 board.GP0, board.GP1 col_pins = (board.GP0, board.GP1, board.GP2, board.GP3, board.GP4, board.GP5, board.GP6, board.GP7, board.GP8) row_pins = (board.GP9, board.GP10, board.GP11, board.GP12, board.GP13, board.GP14, board.GP15, board.GP16) # 2. 配置按键矩阵扫描器 keyboard.matrix = KeysScanner( row_pins=row_pins, col_pins=col_pins, diode_orientation=DiodeOrientation.COL2ROW, # 关键!取决于你PCB上二极管的朝向 interval=0.02, # 扫描间隔,单位秒 ) # 3. 定义键位映射 # 这是一个61键ANSI布局的示例,键值参考KMK的Keycodes from kmk.keys import KC keyboard.keymap = [ # Layer 0: 默认层 [ KC.ESC, KC.N1, KC.N2, KC.N3, KC.N4, KC.N5, KC.N6, KC.N7, KC.N8, KC.N9, KC.N0, KC.MINS, KC.EQL, KC.BSPC, KC.TAB, KC.Q, KC.W, KC.E, KC.R, KC.T, KC.Y, KC.U, KC.I, KC.O, KC.P, KC.LBRC, KC.RBRC, KC.BSLS, KC.CAPS, KC.A, KC.S, KC.D, KC.F, KC.G, KC.H, KC.J, KC.K, KC.L, KC.SCLN, KC.QUOT, KC.ENT, KC.LSFT, KC.Z, KC.X, KC.C, KC.V, KC.B, KC.N, KC.M, KC.COMM, KC.DOT, KC.SLSH, KC.RSFT, KC.LCTL, KC.LGUI, KC.LALT, KC.SPC, KC.RALT, KC.RGUI, KC.MO(1), KC.RCTL # MO(1) 是切换到Layer 1的瞬时键 ], ] # 4. 调试输出(可选) if __name__ == '__main__': keyboard.go()关键参数解析:
diode_orientation:这是最容易出错的地方。如果你的PCB在每个按键上或行列线上串联了二极管(防止鬼键),必须正确设置方向。COL2ROW表示二极管正极接列线,负极接行线;ROW2COL则相反。如果没焊二极管,这里填DiodeOrientation.NONE。务必与PCB设计一致!interval:扫描速度。默认0.02秒(50Hz)足够,如果感觉响应慢,可以适当减小,但会增加CPU负担。keymap:键位映射列表。每个子列表是一个层(Layer)。KC.MO(1)是瞬时切换键,按住时激活Layer 1,松开返回Layer 0。
保存kb.py后,需要修改code.py,让它导入我们的配置:
import kb from kb import keyboard if __name__ == '__main__': keyboard.go()保存code.py,键盘会自动重启。此时,你应该能听到电脑识别新USB设备的声音,并且按键可以输入字符了!
3.3 高级功能配置:层、组合键与宏
KMK的强大之处在于其灵活的配置。
- 多层键位:你可以定义多个
keymap层。例如,Layer 1可以作为功能层,将原本的字母区映射为方向键、F1-F12等。
keyboard.keymap = [ # Layer 0 (默认层)... # Layer 1 (功能层) [ KC.GRV, KC.F1, KC.F2, ... # 将第一排数字键变为F1-F12 KC.TRNS, KC.TRNS, KC.UP, ... # TRNS表示透明,继承下层键值 KC.TRNS, KC.LEFT, KC.DOWN, KC.RIGHT, ... ], ]使用KC.MO(1)、KC.LT(1, KC.SPC)(点击是空格,长按是Layer 1)或KC.TG(1)(切换开关)来激活不同层。
修饰键与组合键:KMK原生支持所有标准修饰键(Ctrl, Alt, Shift, Win/GUI)。组合键如
Ctrl+C可以直接写成KC.LCTL(KC.C)。宏定义:你可以录制一系列按键动作。
from kmk.handlers.sequences import simple_key_sequence # 定义一个输入邮箱的宏 EMAIL = simple_key_sequence([ KC.MY_EMAIL_ADDRESS, # 假设你定义了这个字符串键 KC.ENTER, ]) # 然后在keymap中将其分配给某个键配置完成后,任何对kb.py或code.py的修改,只需保存文件,键盘会在几秒内自动重新加载并生效,实现了真正的“热重载”,调试体验无比流畅。
4. 组装、调试与进阶优化
当PCB、固件都准备好,就可以进行最终的组装和调试了。
4.1 焊接与组装
- 焊接元件:按照先矮后高的顺序焊接:贴片电阻电容 -> XIAO RP2040的排母(强烈建议使用排母,不要直接焊接) -> Type-C接口 -> 热插拔轴座。焊接轴座时务必使用定位板(或已经焊好部分轴体)来固定,确保所有轴座与PCB垂直且高度一致,否则会导致轴体安装歪斜或无法安装。
- 轴体与键帽:将机械轴体按压入热插拔轴座,确保两个金属针脚和中间LED灯脚(如果支持)完全插入。然后盖上定位板(如果有),最后安装键帽。
- 外壳安装:将PCB组件放入底壳,对准螺丝孔位,均匀拧紧螺丝。注意不要过紧,以免压裂PCB或导致变形。
4.2 上电调试与常见问题排查
组装完成后首次上电,可能会遇到一些问题:
- 问题:电脑无法识别键盘,或识别为未知设备。
- 排查:首先检查USB线是否完好,Type-C接口焊接是否有虚焊、短路。然后检查XIAO RP2040的
CIRCUITPY磁盘能否出现。如果不能,重新进入Bootloader模式刷写CircuitPython固件。如果能出现,检查code.py和kb.py是否有语法错误(CircuitPython会在磁盘根目录生成一个boot_out.txt文件,里面有错误信息)。
- 排查:首先检查USB线是否完好,Type-C接口焊接是否有虚焊、短路。然后检查XIAO RP2040的
- 问题:部分按键无反应或串键(按A出现B)。
- 排查:这是最典型的问题。首先确认
kb.py中的row_pins和col_pins定义是否与PCB布线完全一致。然后重点检查diode_orientation设置是否正确。如果设置错误,会导致整行或整列按键失效。可以用万用表蜂鸣档,逐个检查问题按键对应的行、列线与主控引脚是否导通,检查轴座焊点是否有虚焊。
- 排查:这是最典型的问题。首先确认
- 问题:按键连击(Chatter)。
- 排查:这是机械开关的物理抖动导致的。KMK内置了防抖算法。你可以在
kb.py中调整去抖参数:
如果问题依旧,可能是轴体本身质量问题,或者焊点有细微的松香残留导致接触不良,可以用洗板水清洁一下。keyboard.debounce_time = 0.05 # 增加去抖时间,单位秒,默认可能为0.001
- 排查:这是机械开关的物理抖动导致的。KMK内置了防抖算法。你可以在
4.3 进阶优化与扩展
基础功能稳定后,可以考虑一些进阶玩法:
- RGB灯光:XIAO RP2040有足够的GPIO和性能驱动RGB灯带。你可以使用KMK的
RGBMatrix扩展,在PCB背面焊接WS2812B灯带,实现炫酷的背光效果。这需要在配置中添加RGB模块并定义数据引脚。 - OLED屏幕:利用I2C或SPI接口,连接一块小尺寸OLED屏幕,可以显示键盘状态、层信息、自定义动画甚至系统信息(需要主机端配合)。
- 旋钮编码器:在60%键盘上,通过旋钮实现音量调节、页面滚动是非常实用的。KMK支持编码器,你需要为其分配两个GPIO和一个接地引脚,并在配置中定义。
- VIA/Vial兼容:虽然KMK配置已经很方便,但有些人仍喜欢图形化配置工具。可以让KMK模拟成支持VIA协议的键盘,这需要额外的配置和编译步骤,复杂度较高。
- 优化功耗:对于无线键盘项目(XIAO RP2040本身不支持蓝牙,但可以外接模块),KMK提供了休眠功能,可以大幅延长电池寿命。
整个“Purple Owl”项目从设计到落地的过程,充满了硬件与软件交织的乐趣。它不仅仅是一把键盘,更是一个完全受你控制的可编程输入终端。当你第一次用自己设计、焊接、编程的键盘敲出“Hello, World!”时,那种成就感是购买任何量产键盘都无法比拟的。最重要的是,KMK和CircuitPython降低了固件开发的门槛,让你可以更专注于键盘本身的功能和体验设计。如果在过程中遇到问题,KMK活跃的Discord社区和CircuitPython的丰富文档都是强大的后盾。