Goodbye, 机械键盘

上一篇文章中,做的机械键盘用了三年多,我寻思可以换个新的了。那正好和机械键盘说再见,做个光轴键盘。同时也可以作为电子电路的 Hello world 研究作业。

电路的基础知识

作为电子电路的外行人士,还是需要学习一个。

第一是重温电路的基本定律:

  • 欧姆定律
  • 基尔霍夫电流定律,基尔霍夫电压定律
  • 戴维南定理

依靠这些基本定律,可以通过解线性方程组的方式进行电路分析。

然后引入非线性元件:

  • 电感: V=L\frac{dI}{dt}
  • 电容: I=C\frac{dV}{dt}

这时需要解的就是线性微分方程组了。通过拉普拉斯变换,依然可以变成代数方程组解决。进一步分析需要信号与系统和小波分析的相关知识。不过这些方法基本都集成在电路模拟工具中了,例如可以用这个在线工具:https://www.circuitlab.com/

然后是半导体元件:

  • N 型半导体 (negative charge):掺杂了磷、砷、锑等,电子为载流子
  • P 型半导体 (positive charge):掺杂了硼、铟等,空穴为载流子
  • 肖特基管
  • 二极管和三极管
  • 场效应管

然后是微控制器:

  • 时钟
  • 中断
  • pull-up 和 pull-down 输入
  • 开漏 (open-drain) 输出
  • 推挽 (push-pull) 输出
  • ADC
  • 常用通信协议:I2C 和 SPI

真实世界中,每个元件都不是单纯的元件——例如每个电阻,其实都是电阻、电感和电容的集合体

解耦电容需要尽量少的 L

每个元件的特性都不是简单的线性关系,会受温度、光照的影响。元件和导线之间还会感应、干扰。电路的输入信号也从来不是理想的。元件厂家的 datasheet 会提供一些额外的参数和数据方便分析。除此之外,还需要吸收大量前人的设计经验和艺术:

太厚了…就看一小半吧

还有些基础理论(选修),涉及固体物理和控制论:

  • 费米能
  • 肖特基势垒、欧姆接触
  • PID 控制
控制论劝退图

整理需求

对要做的新版本键盘,理了一下自己的需求包括 functional requirement 如下:

  • 蓝牙 USB 双模,键盘还能连接 Wi-Fi,接上后输出键盘的 Wi-Fi 地址,用电脑访问地址弹出配置网页,点保存就可以。所以用户不用安装软件、不用交网费就能全平台配置键位。
  • 使用 USB-FS (full speed,全速,帧间隔 1ms)
  • 左右分离,通过 SPI 通信。
  • 可外接设备如微型轨迹球麦克风
  • 无线电子墨水显示键盘状态,不需要 LED
  • 能贴片的全让代工厂贴了,避免手工焊接。
  • 最后且最重要的:和触点开关的机械键盘说再见,用光轴

光轴的原理是 PCB 上摆一个红外发光二极管和一个接收器(三极管),没按下去时接收器导通。轴体按下去阻隔了红外光,接收器电阻变大相当于断开。相比机械轴,光轴的信号极其平滑,抖动很少(据说也有抖动,是否需要防抖得测试一下再说),响应一般在 0.1ms 内。由于没有触点,光轴也更顺滑,使用寿命要长 50% 以上。由于不用和 PCB 连接,轴的受力可以完全加在板上,不会影响 PCB 寿命。

光轴还有一个优势是:输入电路和输出电路之间以光耦合,不存在电流乱走造成幽灵按键的问题。

其他选择:模拟光轴或者霍尔效应轴,但模拟光轴还没有方便购买的散货。霍尔效应轴就佳达隆一家有量产,写信联系它又不理我。途中有一位热心的老哥 riskable 给我发了他的 3D 打印霍尔效应轴图纸,但由于制作有点麻烦,最后还是没那么做。对霍尔效应轴感兴趣的朋友,可以看看 input.club 的 Keystone。

关于延迟的讨论

人类的反应时间在 300ms 左右。如果练成了“肌肉记忆”,对特定信号的反应会更快。例如闪烁躲锤子,反应在 200ms 都是有可能的。

机械轴触点的抖动一般在 5ms 内,如果要防止误触发(例如键盘震动造成的簧片抖动、感应无线电波造成电平变化等,比较少见但是有可能),最好进行 10ms 左右的 debounce 之后再发送信号。这就引入了 10ms 的延迟,很多低成本键盘为了方便,甚至把防抖搞到了 30ms。光轴信号是无抖的,不用做这个消抖,且感应元件微秒级的响应,就算求稳加入防抖,1ms 的前摇消抖就可以(后摇依然可以 30ms,人没法在这么短时间内按同一个键两次)。

微控制器的扫描间隔会造成延迟,执行代码也需要时间,可以提高主频和扫描频率,使之可忽略不计。

一些键盘声明为 USB 低速设备,帧间隔 8ms,那也会造成 0-8ms 的输入延迟。USB 全速帧间隔 1ms,高速帧间隔 0.125ms。一般如果键盘用的微控制器价值高于 1 块钱的话,会支持到 USB 全速,于是由 USB 帧间隔导致的延迟在 0-1ms 之间。

USB 集线器也会造成延迟。有些显示器可以外插 USB,这也是一种集线器。延迟的量级在 10 个帧左右,如果帧间隔是 8ms,你就在集线器获得了 80ms 的延迟。为了最小化延迟,建议直连而不是通过集线器。

USB 的信号一般是通过南桥芯片/ICH再进 CPU。ICH 是 IO Control Hub 的缩写,说白了也是一种集线器,它不是转到 USB 协议,工作的频率很高,造成的延迟大概可忽略不计?

显示器延迟也不可忽略,普通显示器刷新率低如 60Hz,还有响应时间延迟如 5ms,那显示延迟就是 5-22ms。换用快响应时间如 1ms 及刷新率 144Hz 的显示器,显示延迟可降低到 1-8ms

网络延迟很难估算,只能通过升级套餐、和运营商扯皮等方式解决。

综上,

普通设备的延迟(ms) 改进后的延迟(ms)
显示器 5-22 1-8
防抖 30 1
USB 速度 0-8 0-1
集线器 80 0
总计 120-145 2-10

可看到,其中改善防抖、去掉集线器的收益最大。

信息储备

看电路图和看交通标志一样复杂

为了支持这个设计,需要点实操培训。所以就先学习了一遍 Phil's Lab 的 STM32 PCB 设计+嘉立创打板教程。高频电路的设计技巧是:同类元件和同类信号尽量在同一区域;层越多越好,信号/power pour 和 ground plane 相间;当信号穿越 via 时,在旁边也来一个 ground via 配对;power 和 ground 之间电容越大越好 —— 因为高频信号无时无刻都在辐射,信号附近有地可以保证能量基本在它们之间的电介质传输,从而避免辐射到外面去。

然后就是微控制器 (MCU) 选型。现在由于芯片荒,主流 MCU 都涨价且缺货… 看了一百多本手册和价格以后,基本候选在下面几个 MCU:

  • ESP32-PICO。支持 Wi-Fi + 蓝牙,有 touch sense 功能,一个模组不仅自带天线,还打包了晶振,简直太方便了,写文章时单片 20 块左右。SDK 也是我喜欢的,可以命令行搞定。
  • 类似 STM32 的国产芯片,例如 GD32, MM32, FM32, 雅特力, Holtek 等,价格便宜且容易买到货,就是文档和工具比 STM32 / ESP32 差得远。
  • 高通 QCA4020。有 Wi-Fi + 蓝牙支持,PIN 很多但大部分都是地,可用 GPIO 的数量其实要少很多,不好贴。
  • 高通骁龙系列。类似 QCA4020,运算能力强,可以买拆机垃圾,同样不好贴。
  • nRF52840。有 Wi-Fi + 蓝牙支持,48 个 GPIO 差不多刚好支持单手键盘全键直连和中断驱动。缺点是比 ESP32 贵不少。
  • 最近量产的 ESP32-S3。Wi-Fi + 蓝牙支持,44 个 GPIO,自打包了 PSRAM、晶振和天线。核心是 Cadence 家的 Tensilica Xtensa 双核,这个架构优点是提供了一套定制工具,相比千篇一律的 ARM 处理器可以发挥定制能力强的优势。价格便宜,简直是国产之光,我直接下单了 10 片。

然后是光轴相关资料,有个叫 optical-future 的论坛上把发射器/接收器资料和光轴设计要考虑的点都讨论了个遍,节约了我很多功夫。下图 D4 为发射器,Q2 为接收器。

参考光耦电路

发光二极管采用 IR12-21C-TR8。

光敏三极管采用 PT12-21B-TR8。

光轴尺寸:

PCB 上的打洞尺寸:

By leavenember, Pad size X 为 2.85mm 更合适

然后是迷你轨迹球相关资料,基本锁定在:

  • 霍尔效应轨迹球 Trackball Breakout,I2C 低速接口
  • 光学轨迹球 Pixart PAW3204OA,SPI 接口

ESD 保护,也就是 electro-static discharge 保护,是一种防止静电放电破坏电子元件的元件。选定为给 USB 优化的专门元件 USBLC6-2。

USBLC6-2
连接方式, _CONN_ 标签为接口方向

USB 供电是 5V 的,但芯片基本都需要 3.3V,所以需要变压。考虑到电器的阻抗会变化,不能简单的用电阻串联分流,而可以用自动稳压的元件来供电。MCP16301/H 就是这么一种,利用输出电压的反馈自动控制,来稳压的元件。

MCP16301/H 的参考电路

解耦电容:传统键盘电路都是低频信号不太用考虑,但这里有 2.4G 的蓝牙信号和 40M 的 Wi-Fi 高频信号,所以也需要添加些解耦电容,吃掉高频的信号对我们 IO 端口的干扰。好在可以按照 MCU 参考电路添加。

了解 I2C 的原理,一般芯片支持 100kHz/400kHz 的通信速度。

了解 SPI 的原理,一般芯片支持主频/n 的 SPI 通信速度,所以比 I2C 要快。

了解 USB 的原理:

USB Made Simple – Part 1

如果芯片支持 USB-HS 也就是 high speed,那也能克服集线器的限制了,因为集线器增加约 10 个帧,对 USB-HS 也就 1.25ms 的延迟,是可以忽略的。遗憾的是支持 USB-HS 的芯片非常少。现在我找到的两种方案是:

  • 利用 USB PHY 元件如 USB3300 来连接,但这些元件需要 ULPI 协议,没 FPGA 似乎搞不定
  • 使用 Atmel 的 SAM9X 这种支持高速 USB 的芯片

以上两种方案成本都比较高,USB-HS 就留待下个版本的迭代吧。

无线射频:对 2.4G 频率的信号,主要利用超外差式的方式进行接收,也就是,用和信号相近的本地信号和接收到的信号混频,产生容易处理的、频率低得多的 IF (intermediate frequency) 信号。这方面的基础知识,建议参考:

一次 RubyConfChina 上,我在图灵的展位半价买的

天线在 PCB 上画,同样可以用参考设计。天线的分析原理可以用 A-\phi 方程,即磁矢量位(magnetic vector potential) 和电标量位 (electric scaler potential) 方程计算。不过买的 SoC (system on chip) 模组自带天线,不需要自己画天线了。还有个问题是,金属载板会阻挡信号,解决办法是让天线凸出去。

这次不搞灯,没必要低头看键盘的状态,显示器旁放一个无线显示就可以了。可以购买现成的 ESP32+电子墨水屏+电池的组合,以 Wi-Fi 连接到键盘。

这个电子墨水屏有点太大了,我觉得 4 寸的贴显示器旁就可以

语音识别,ESP32 有现成的 SDK 可用。

低功耗设计

我们可以循序渐进,先做好有线连接的设计,再做无线连接的设计。光轴的缺点是一直需要点亮发射器,键盘扫描耗电大,做低功耗就需要经常休眠。而休眠做得不好的产品,例如 M$ 的 Sculpt 鼠标,一段时间不动,就得两秒唤醒,给使用增加很多麻烦。

一个低功耗的键盘,应该可以在下面三种工作模式切换:

  • 正常工作模式:如果一段时间没有输入,进入浅睡眠模式
  • 浅睡眠模式:降低主频和扫描频率,有按键时进入正常工作模式
  • 深睡眠模式:停止扫描,切换到低功耗的协处理器,启用 proximity sensor,当有人接近时唤醒到浅睡眠模式

proximity sensor 有很多种,备选的几种方案有:

  • 基于 Wi-Fi CSI 的检测:需要比较多的计算,可能并不省电
  • 基于电容的检测:省电,但探测距离过近 (一般只有 mm)
  • 环境光检测:要做差分,而且如果环境黑暗就不适用了
  • 主动红外光检测:现在的主流方案,通过一个红外发光二极管发光,如果人手接近键盘,就会反射红外光,再通过环境光感应器读数。主动探测的发光二极管功耗比较高,但因为感应器响应很快,可以通过减少发光时长和频率来降低消耗。

检测到接近后,通过 I2C 发送信号到 ESP32-S3 的超低功耗协处理器 (ULP)。协处理器是一个 RISC-V 指令集的简单 CPU,可以用简单的汇编编写其逻辑。其中几个会用到的扩展指令是:

  • REG_WR: 改变 IO 引脚电平,打开红外发光二极管
  • ADC: 读数
  • WAKE: 指令唤醒主处理器

低能耗的扫描逻辑

查手册,估算每个红外发光二极管正常工作电流约为 20mA,一个键盘 80 个键,全部并联点亮那就是 1600mA,已经超过 USB 2.0 允许的最大电流了。有几个办法改善:

  • 红外二极管的正常工作电压是 1.2V 左右,我们用 3.3V VDD 供电,二极管 3 个一组串联,那刚好每个二极管分配 1.1V 的电压,就不需要在电阻里浪费功耗了。
  • 和扫描矩阵一样,分组轮流点亮,每次只点亮 3 个管。瞬间电流是 20mA

还有可以想到的一点是,点亮时间是越短越省电。我们先计算一下以下几个必要的延迟:

种类 延迟
从设置 output pin 到输出改变 20-100ns(没有资料,按场效应管响应时间得出的估计值)
红外发光的响应时间 20ns(类似产品的估算值)
红外感应的响应时间 15μs(手册给出)
从输入改变到 input pin 值改变 1.8μs(网友实验测量值)

如果规划 50μs 的点亮时间,以总计 40 个键计算,可得一个扫描周期约为 40 / 3 * 0.05 = 0.65ms,此时等效功耗为 3.3V x 20mA。如果压缩点亮时间到 30μs,单扫描周期延长到 0.8ms,等效功耗为 3.3V x 8mA。再考虑深浅睡眠停止扫描,用 2000mAH 的电池供电能工作挺久的了,实际使用再进行调整。

还有一个问题,计算得三个串联发光二极管的等效内阻约为 165Ω,ESP32 单 output pin 是否可以对其输出 20mA 左右的驱动电流?按网友的测量应该可以:

上图中驱动强度为3(source3)的曲线,第6个点负载 150Ω,刚好是20mA

还有一个问题,发光二极管是非线性元件,各管有公差,串联起来会不会一个电压特别大,另外一个电压特别小呢?查看数据手册的电压-电流曲线可以知道,电压越大,等效电阻越小,电阻变小就反过来让它分到的电压变小,因此这个串联效果是稳定趋于均分的。

工程规划

综上,大体设计和可行性分析已经无大问题,制作流程大致为:

  • 打印一个多功能的 Breakout 测试板,顺便练习手焊模块
  • 打板、编程
  • 设计外壳、切削
  • 扩展电路添加外接的轨迹球
  • 添加无线显示

工具准备

为烧录和 debug 准备了 90 块的国产 DAPLink 一个,但直接用 ESP-IDF 增加一个 USB-UART 就可以了。

画 PCB 依然是 KiCAD,元件的引脚、模型可以在 Ultra Librarian 搜出来下载。

使用 ngSPICE 做电路模拟。

板和壳建模仍旧是 OpenSCAD。

光轴若干,买回来量量尺寸,做个准备。

Filco style 板载卫星轴。

左右通信线材选用 USB 线,全接 Type-C 口。

焊接工具等。

频谱分析仪、网络分析仪、信号发生器、矢量信号分析仪——暂时不需要。

以上,暂时就酱,可以动手开工了。

来源:知乎 www.zhihu.com

作者:luikore

【知乎日报】千万用户的选择,做朋友圈里的新鲜事分享大牛。
点击下载