用ATTiny44与V-USB自制USB键盘:从HID协议到水果触控的嵌入式实践
1. 项目概述:当香蕉也能敲代码
几年前,我在一个创客展上看到一个项目:用几根香蕉弹奏钢琴。当时觉得这想法既酷又有点“不务正业”。后来自己动手做类似的东西,才发现这背后藏着嵌入式开发里一个非常有趣且实用的技术点:如何让一个成本不到十块钱的微控制器,摇身一变成为电脑能识别的标准USB键盘。今天要聊的Crocopoi,就是这样一个把“不务正业”玩到极致,同时又极具教学和实用价值的项目。它的核心很简单:一块搭载了ATTiny44微控制器的小板子,配合V-USB软件库,能把任何导电的物体——没错,香蕉、黄瓜、铝箔,甚至一块湿海绵——都变成可以触发键盘按键(上下左右、空格、回车)的交互界面。
这听起来像是魔术,但原理却很扎实。它解决了一个原型开发中常见的痛点:快速、低成本地测试物理交互逻辑。比如,你想做一个体感游戏控制器,或者一个创意音乐界面,在验证核心交互想法时,完全没必要先去定制机械按键或复杂的传感器阵列。用Crocopoi,接上几片铝箔或几个水果,马上就能在电脑上跑通你的交互逻辑,极大地降低了创意落地的门槛。这个项目非常适合嵌入式爱好者、交互设计师、艺术科技从业者,以及任何想给物理世界和数字世界搭一座简单桥梁的朋友。它麻雀虽小,却涵盖了从USB协议、微控制器编程到PCB设计的完整流程,是个绝佳的练手项目。
2. 核心原理:微控制器如何“伪装”成USB键盘
要让电脑把一个自制的小板子认作键盘,而不是一个无法识别的“未知设备”,我们需要遵循一套严格的“对话规则”,这就是USB HID(Human Interface Device,人机接口设备)协议。理解这个协议,是玩转Crocopoi乃至任何自制USB设备的关键。
2.1 USB HID协议的精简解读
你可以把USB通信想象成一场面试。电脑(主机)是面试官,你的设备(Crocopoi)是求职者。HID协议就是这份“键盘岗位”的职位说明书和面试流程。
首先,设备一插上电脑,面试官就会问:“你是谁?会干什么?”这时,设备必须递上一份标准的“简历”,即设备描述符。这份简历里必须明确写明:我是一个键盘(设备类Class=0x03,子类SubClass=0x01,协议Protocol=0x01)。电脑核对职位要求(HID规范)后,发现匹配,才会进入下一轮。
接着,电脑会要求看更详细的“项目经验”,即报告描述符。这份描述符定义了设备的具体能力:我有6个按键,分别对应哪些键值(比如Keycode 0x52是上箭头),数据包应该以什么格式发送。这份描述符是用一种叫HID报告描述符的语言写的,虽然看起来像天书,但其结构是固定的,主要就是定义一些“用法页”(Usage Page,如通用桌面控制)和“用法”(Usage,如键盘)。Crocopoi的固件核心之一,就是正确构造这份描述符。
最后,当面试通过,设备正式“上岗”(枚举成功)后,每次用户触摸导电物体,设备就需要向电脑发送一个简短的“工作报告”,即输入报告。对于键盘来说,这个报告通常是一个8字节的数据包,其中某些位就代表了哪个按键被按下了。电脑收到这个报告,就会将其翻译成相应的按键事件。
2.2 V-USB:在ATTiny上实现USB的软件魔法
这里就遇到了一个硬件上的矛盾:标准的USB通信需要专门的硬件控制器来处理复杂的时序和信号编码(NRZI编码与位填充)。而像ATTiny44这样的廉价8位微控制器,根本没有这个硬件模块。那怎么办呢?这就是V-USB的魔力所在。
V-USB是一个纯软件实现的USB 1.1低速设备协议栈。它的工作原理可以粗略理解为“用软件模拟硬件时序”。ATTiny44有两个通用IO口被用来模拟USB的D+和D-数据线。V-USB库通过精密计算指令周期,在这些IO口上以精确的1.5MHz频率(低速USB的位速率)翻转电平,从而“无中生有”地拼凑出符合USB规范的电气信号。
注意:软件模拟对时序要求极为苛刻。因此,V-USB必须运行在一个稳定且精确的时钟源上。这就是为什么Crocopoi电路板上那颗12MHz的晶体振荡器(CRYSTAL)和两个18pF的负载电容(C1, C2)如此关键。它们为ATTiny44提供了稳定、精准的时钟心跳,是V-USB稳定工作的基石。如果使用内部RC振荡器,时钟漂移会导致USB通信失败,电脑根本无法识别设备。
2.3 触摸检测:用高阻值电阻“感知”人体
Crocopoi如何知道你去摸了那根香蕉?它用的不是复杂的电容触摸芯片,而是一个极其巧妙的模拟电路:高阻值电阻分压与施密特触发器。
电路板上,每个按键通道(对应R8-R13, 10MΩ电阻)都连接着一个IO口。这个IO口平时被微控制器内部的上拉电阻拉到高电平(比如5V)。另一端通过一个10MΩ的巨无霸电阻接地。当你用手同时触摸“地线”鳄鱼夹和连接香蕉的“信号线”鳄鱼夹时,你的身体(大约几百kΩ到几MΩ的电阻)就并联在了那个10MΩ电阻上。
人体电阻相对于10MΩ来说小得多,这相当于显著降低了该通道对地的电阻。根据欧姆定律,IO口检测点的电压就会被你的身体“拉低”。微控制器通过ADC(模数转换)或简单的数字输入检测(当人体电阻足够小,电压被拉低至逻辑低电平阈值以下时),就能感知到这个电压变化,从而判定“按键”被触发。
实操心得:10MΩ这个值选得很有讲究。值太小,需要更用力或更潮湿的接触才能触发,不灵敏;值太大,容易受环境电磁干扰,产生误触发。10MΩ是一个在灵敏度和抗干扰性之间取得良好平衡的经验值。如果发现触摸不灵,可以尝试让手湿润一点(降低人体电阻),或者检查导电物体与鳄鱼夹的连接是否牢固。
3. 硬件设计:从原理图到PCB的工程实现
有了原理,下一步就是把它变成实实在在的电路板。Crocopoi的硬件设计充分体现了“极简”和“实用”的思路。
3.1 核心电路模块解析
让我们拆解一下物料清单(BOM)里的关键角色:
- 主控与时钟(IC1, CR, C1, C2):ATTiny44是大脑,12MHz晶振是心脏。两个18pF的电容帮助晶振起振并稳定在其谐振频率。这是整个系统运行的节拍器,不容有失。
- USB数据线保护(D2, D3, R1, R2):这是V-USB项目的经典设计。两个3.3V的齐纳二极管(Zener)将模拟出的USB数据线(D+和D-)电压钳位在3.3V左右,防止意外高压损坏微控制器脆弱的IO口。两个49Ω的电阻(R1, R2)则作为串联电阻,起到一定的限流和阻抗匹配作用。
- 电源滤波(C3, C4, C5):C3和C4(比如10uF和0.1uF)通常并联在电源入口,用于滤除低频和高频噪声,为芯片提供“干净”的电力。C5(1nF)接在ATTiny44的ADC参考电压引脚(AREF)上,可以稳定模拟参考电压,如果用到ADC的话会更准确。
- 触摸感应网络(R8-R13, R7):如前所述,6个10MΩ电阻(R8-R13)对应6个按键通道。R7(10kΩ)是连接到ATTiny44复位引脚的上拉电阻,确保芯片能正常启动。
- LED指示(D1, R3):LED(D1)和499Ω的限流电阻(R3)构成状态指示灯。在固件中,可以编程让它在上电、枚举成功或按键时闪烁,是重要的调试手段。
3.2 PCB布局与单面板设计考量
原作者特意将PCB设计为单面板,这是一个对DIY爱好者非常友好的决定。双面板虽然布线更方便,但需要过孔,对家庭热转印或手工焊接不那么友好。单面板意味着所有元件和走线都在同一面,另一面是完整的铜箔(通常作为接地层或仅少量跳线)。
在Eagle这类PCB设计软件中,单面板设计需要更多的布线技巧:
- 跳线(Jumper Wire):当无法在同一面连通两条线路时,可能需要使用0Ω电阻或一根导线作为“跳线”在元件面进行连接。在Crocopoi的紧凑布局中,需要仔细规划走线路径以避免使用过多跳线。
- 电源与地线优先:需要先布置好电源(VCC)和地(GND)的主干道,确保供电稳定。特别是USB的5V电源,走线应尽量短而粗。
- 晶体振荡器就近布局:12MHz晶振及其负载电容必须尽可能靠近ATTiny44的XTAL引脚,走线短且直,以减少寄生电容和电感,保证时钟信号纯净。
将设计好的PCB文件(Gerber文件)发给像SeeedStudio这样的制造商,选择最便宜的工艺(如FR-4, 1.6mm厚度, 有铅喷锡),几天后你就能收到一打专业制作的空白PCB了,这比自己腐蚀要精确和美观得多。
4. 固件开发:编写让ATTiny“说话”的程序
硬件是躯体,固件则是灵魂。Crocopoi的固件开发是围绕V-USB库展开的。
4.1 开发环境搭建与项目配置
首先,你需要搭建一个AVR开发环境。我推荐使用 PlatformIO(基于VSCode) 或 AVR-GCC + Makefile 的传统组合。PlatformIO对新手更友好,库管理方便。
核心步骤是:
- 获取V-USB库:从Objective Development官网下载V-USB库。它是压缩包形式,里面包含了核心的
.c和.h文件,以及大量示例。 - 创建项目结构:在你的项目文件夹中,创建一个
lib或usbdrv子目录,将V-USB库文件复制进去。关键文件通常包括usbdrv.c,usbdrvasm.S(或.asm, 汇编文件,用于精确时序),usbdrv.h和usbconfig.h。 - 配置
usbconfig.h:这是最关键的一步。你需要根据Crocopoi的硬件连接,修改这个配置文件。主要设定包括:USB_CFG_IOPORT: 设定USB D+数据线连接的端口(如PORTB)。USB_CFG_DMINUS_BIT: 设定D-连接的引脚位(如PIN4)。USB_CFG_DPLUS_BIT: 设定D+连接的引脚位(如PIN3)。USB_CFG_CLOCK_KHZ: 设置为12000(对应12MHz晶振)。USB_CFG_DEVICE_CLASS,_SUBCLASS,_PROTOCOL: 分别设置为0x03, 0x01, 0x01, 声明为键盘设备。USB_CFG_VENDOR_ID和USB_CFG_DEVICE_ID: 可以自定义一个,或者用示例中的默认值。避免与已知设备冲突即可。USB_CFG_HID_REPORT_DESCRIPTOR: 这里要填入你的键盘报告描述符数组。可以从V-USB的hid-class示例中复制一个标准的键盘报告描述符,它通常定义了8字节的输入报告(modifier keys + reserved + keycodes)。
4.2 主程序逻辑与触摸检测实现
主程序的结构通常是这样一个循环:
4.3 编译与烧录
编写好代码后,使用AVR-GCC进行编译。在PlatformIO中,这通常是点击“Build”按钮。编译会生成一个.hex文件。
烧录需要一台AVR编程器,如USBasp、AVRISP mkII或使用Arduino作为ISP编程器。连接编程器到Crocopoi板上的ISP接口(MOSI, MISO, SCK, RESET, VCC, GND)。然后使用avrdude命令行工具或PlatformIO的上传功能进行烧录:
烧录完成后,拔掉编程器,将Crocopoi通过Micro USB线连接到电脑。如果一切顺利,电脑会发出“叮咚”的硬件识别音,并在设备管理器的“键盘”类别下看到一个新设备。
5. 制作、调试与创意应用
5.1 焊接与组装要点
收到PCB和元器件后,焊接是下一个挑战。对于贴片元件(如ATTiny44, 0805或1206封装的电阻电容),如果你没有热风枪或回流焊炉,可以尝试以下方法:
- 拖焊法(适用于SOIC封装的ATTiny44):给一排引脚都上一点锡,然后用烙铁头带着充足的焊锡从左到右快速拖过,多余的锡会被烙铁带走,借助焊锡的表面张力,引脚会自动分离。这是最实用的手工焊接小贴片芯片的方法。
- 先焊芯片,再焊外围:先焊接最核心、最精密的ATTiny44和晶振。确保它们位置正确、没有桥接。然后再焊接电阻、电容等。
- 检查齐纳二极管方向:D2和D3(3.3V齐纳)有方向性,通常色环或标记端对应阴极,要对照原理图正确焊接。
- LED方向:LED(D1)是二极管,长脚为正(阳极),应接在电阻R3那一侧,短脚为负(阴极)接地。
焊接完成后,务必用放大镜和万用表仔细检查:
- 电源短路:测量VCC和GND之间的电阻,不应接近0欧姆(在未上电时)。
- 连通性:检查关键网络是否连通,特别是USB D+/D-到芯片引脚的线路。
- 虚焊/桥接:仔细查看每个焊点,特别是芯片引脚之间。
5.2 上电调试与故障排查
第一次上电总是令人紧张。遵循以下步骤:
- 先测电压:不接USB,用万用表测量板子VCC和GND之间的电压。正常应为5V左右。如果为0或极低,立刻断电,检查USB插座焊接、电源线路有无短路。
- 观察电流:串联万用表在电流档(或使用带电流显示的USB测试仪)接入USB。正常工作的ATTiny44+V-USB,电流通常在20-50mA范围。如果电流异常大(>100mA),可能存在短路;如果电流为0,可能电源未接通或芯片未工作。
- 听声音,看设备管理器:接上电脑。成功时,电脑会提示安装驱动(V-USB使用系统自带的HID驱动,通常自动完成)并识别为键盘。如果没有任何反应:
- 检查晶振:用示波器探头(需注意负载电容影响)或逻辑分析仪测量晶振引脚,看是否有12MHz正弦波。没有示波器的话,可以尝试更换晶振和负载电容。
- 检查USB数据线:用万用表二极管档或通断档,检查D+和D-线路是否连接到正确的芯片引脚,且与齐纳二极管连接正确。
- 重新烧录固件:确认熔丝位(Fuse Bits)设置正确。对于ATTiny44使用12MHz外部晶振,通常需要设置熔丝位为:
CKDIV8=1(禁用8分频),SUT_CKSEL=外部全幅振荡器, 启动时间16K CK + 65ms。错误的熔丝位(如设成了内部RC振荡器)会导致USB无法工作。
5.3 常见问题速查表
| 问题现象 | 可能原因 | 排查步骤 |
|---|---|---|
| 电脑无任何反应(无提示音) | 1. USB电源未接通 2. 晶振未起振 3. 固件未运行(熔丝位错误) 4. V-USB配置错误(引脚定义) |
1. 测VCC电压 2. 检查晶振焊接, 更换晶振电容 3. 检查/重设熔丝位, 烧录一个简单的LED闪烁程序测试芯片 4. 核对 usbconfig.h中的I/O口设置 |
| 电脑识别为“未知设备” | 1. USB枚举失败(描述符错误) 2. 时钟不准(晶振频率偏差大) 3. USB信号质量差 |
1. 检查报告描述符是否正确 2. 确保使用高质量12MHz晶振 3. 检查D+/D-上的齐纳二极管和串联电阻, 线路尽量短 |
| 触摸不灵敏或无效 | 1. 触摸通道上拉电阻未启用 2. 人体电阻太大(手太干) 3. 检测阈值设置不当 4. 鳄鱼夹接触不良 |
1. 程序中确认将对应引脚设置为输入并上拉 2. 湿润手指或使用更大面积的导电物接触 3. 可以改用ADC读取电压值, 设置软件阈值 4. 确保导电物体与导线连接牢固 |
| 按键粘滞(按下后不释放) | 1. 程序防抖逻辑问题 2. 导电物体表面有残留水分或污渍导致持续导通 |
1. 增加触摸检测的释放去抖延时 2. 清洁导电物体表面, 或使用更稳定的导电材料(如铜箔) |
5.4 创意应用扩展
Crocopoi的基础框架打开了无数创意应用的大门:
- 水果钢琴/鼓机:将多个Crocopoi并联(需修改固件支持更多按键),将不同水果分配给不同音符或鼓点,制作一个可触摸演奏的乐器。
- 体能训练计数器:将铝箔片贴在俯卧撑支架或跳绳手柄上,每次接触即计数一次,通过空格键触发计时软件或计数应用。
- 简易安全系统:将两条导线布置成隐蔽的回路,一旦被闯入者碰断(或接通),即触发“回车”键,配合电脑上的脚本执行报警、拍照等操作。
- 互动艺术装置:在画作、雕塑的特定导电区域隐藏触点,观众触摸时触发电脑播放对应的音效或改变灯光。
- 教育工具:用于教授电路导通、电阻的概念,让学生直观感受“人体也是导体”。
要实现更复杂的应用,你可以升级主控芯片(如使用ATTiny84以获得更多IO口和Flash空间),修改报告描述符以支持更多按键或自定义HID设备类型(如游戏手柄),甚至将触摸检测升级为更精确的电容感应测量。Crocopoi作为一个起点,其价值在于清晰地展示了从物理世界到数字指令的最短路径。