如何从零开始:用 CH592F制作CS2生命值胸章并实现和游戏联动效果

背景
在CS2中(CS:GO里面也有)中有一个叫做生命值胸章的饰品
第一次看到时候就觉得这个很适合使用LED做出来.
而且还可以通过CSGO GSI同步游戏中生命值状态.
补充说明
有不少人指出胸章出自半条命:Alyx,以前只在朋友家玩过开头, 对这个装置在半条命中的印象不是很深了.
观看了一些Alyx的实况视频后了解到这个装置的更为具体的一些信息, 或许将来可以制作三个完整的爱心版本,然后像Alyx中的一样, 每颗心都有大小的变化, 极大的提高了丰富表现力.
元件选型
MCU选型
由于胸章的尺寸较小(60mmx20mm), 而且我也不希望成品太厚无法佩戴,还不想拖着一根线,所以主控得是一个支持无线(乐鑫:有人叫我?)的芯片.
虽然我很喜欢乐鑫家的芯片(我之前写过很多关于 ESP32 串流 和 ESP32 显示公网图片 的教程)),但是抱歉, 这次真的对不起,你的功耗实在是太高了.
之前在制作Friday Ink时候,用的芯片是CH582F, 使我对WCH王翠花家的芯片略有好感,不仅便宜够用,功耗还低.
结合成本和开发量评估后, 最终选择WCH王翠花家的CH592F作为主控, 和之前的CH582F对比, 只是RAM略有些减少, 但是对于当前的HealthPin是绝对足够的.

LDO选型
之前爱用的LDO是AP2112K-3.3TRG, 源自多年前抄Arduino Pro micro时候形成的习惯.
为了进一步压缩成本, LDO换成了更容易购买到而且仅需0.18元的ME6211.
锂电池充电芯片选型
在之前的罗盘设计中, 锂电池充电管理芯片用的是MCP73831, 这款IC我首次购买时候4元,后来居然涨价到了8元(不过最近有所回落,但还是让我有所忌惮).
因此充电管理芯片换成了仅需0.45元的TP4057, 二者外围器件差异不大,仅需注意引脚定义.
灯珠和MOS选择
你知道的, RGB可以提升300%性能,所以灯珠毫不犹豫的选择了内置WS2812B的1mm x 1mm RGB灯珠.
考虑到WS2812B的静态功耗有点大, 对于我们本来就不大的电池来说雪上加霜, 所以三颗心分为三组, 除了最小的那颗心无法主动关闭供电外, 其余两颗心都会使用MOS管控制电源开关,达到不用时候彻底关闭省电的目的.对于灯泡、电机这类无源负载,通常使用驱动简单的NMOS作为下管来控制其地线回路。而对于WS2812B这类需要与MCU进行精确数字通信的有源器件,为了确保通信信号的完整性以及两者之间的稳定共地,优选使用PMOS作为上管来控制其电源,而不是控制其地线。
为了节省空间, 选择一个SOT23-6封装的BRCS4953提供双PMOS.
PCB设计
尝试过把灯珠和主控分别放在两张板子上, 再焊接方式粘在一起, 但是这样会增加一个板子的厚度,成本也会因此上升.
遂放弃这个方案, 继而使用传统的双面元件方式实现.
PCBA最终渲染如下:
其中电池外围则印有BOMB HAS BEEN PLANTED HANDLE WITH CARE字样彩蛋.
实物焊接效果展示
由于没有外壳, 而且阻焊是白色,所以看上去和游戏原设计有所出入.
程序
StatTrak项目回顾
在CS:GO还没升级成为CS2的时候,我就在现实中制作过一个可以和游戏联动的StatTrak.
当时方案是直接编写一个python脚本和CS:GO GSI通信, 再借助pyserial向装置发送击杀数据.
Auraro
我记得罗技的GHUB是能够控制自家设备和游戏的联动, 于是就在想是否有类似的开源方案来做到类似的统一管理.
一方搜索后得知了Project Aurora这个开源项目.
最最令人激动的是, Aurora不仅仅适配了很多知名厂商的设备, 他甚至还有一套Device Script来供第三方设备实现对接.
Device Script编写
在Aurora的仓库下有一个example_script.cs提供了简单的示例.
HealthPin的通信方式是使用蓝牙HID, 而蓝牙HID装置在连接电脑后会被视作一个普通的HID装置, 只需要使用标准HID通信API向装置发送数据即可.
协议拟定和实现
我们的装置有LED和蜂鸣器, 所以协议中在将装置这些能力暴露出来.
初步定义如下类型的协议结构和Command, 并且着重介绍SetHeartColor命令
1 | // 命令 ID 枚举 |
Device Script完善
Aurora下发颜色配置时候, 会触发Script Device的UpdateDevice(object keyColors, bool forced)函数, 这个函数里面我们可以查询到所有键位颜色信息.
而HealthPin三颗心分别被映射到了键盘的7,8,9三个键,所以只关注这三个键的数据即可. 当然如果你想关注F1,F2,F3的配置也没问题, 只是需要注意在调整Profiles时候要设置对应的按键.
1 | Color targetHeart1 = Color.Black; |
获取到颜色数据,只需要使用HidD_SetFeature函数发送数据即可.
1 | private static extern bool HidD_SetFeature( |
下位机程序
当初选择CH592F有大原因就是有很多人用它做键盘, 而且官方的例子中就有一个基于蓝牙的HID_Keyboard example.
在构思本项目时候, 就像好了要伪装成为一个HID设备, 再和电脑走HID进行通信. 这个方案不用考虑串口驱动或者其他USB驱动的麻烦事情了.
驱动WS2812B
具体可以参考WCH官方实现, 巧妙地使用了SPI来模拟WS2812时序,这里不做赘述.
HID命令解析
这部分和上位机反着处理即可, 在hidEmuRptCB函数中, 处理HID_DEV_OPER_WRITE的情况,然后区分是否是我们需要关注的事件.
1 | // 解析自定义的HID灯光协议 |
然后享受Aurora对大量游戏的支持,以及丰富的灯光配置.

视频
如何从零开始:用 CH592F制作CS2生命值胸章并实现和游戏联动效果