做一个CS2中的生命值胸章

背景

在CS2中(CS:GO里面也有)中有一个叫做生命值胸章的饰品
healthpin_in_cs2
第一次看到时候就觉得这个很适合使用LED做出来.
而且还可以通过CSGO GSI同步游戏中生命值状态.

元件选型

由于胸章的尺寸较小, 所以不能配备的较大容量的电池.
而且我不想拖着一根线,所以得是一个支持无线的芯片.
虽然我很喜欢乐鑫家的芯片,但是抱歉, 这次真的对不起,你的功耗实在是太高了.
之前在制作Friday Ink时候,用到了CH582F,使我对王翠花家的芯片略有接触.
所以这一次选择王翠花家的CH592F作为主控, 对比CH582F, 只是ram略有些减少,但是也足够制作HealthPin了.
ch592

之前一直在用AP2112K这款LDO,是继承自多年前抄Arduino Pro micro设计的原因.
为了进一步压缩成本, LDO换成了ME6211.充电管理芯片换成了TP4057,而不是之前的MCP73831.
同时为了丰富色彩, 灯珠选择了1mm x 1mm 的WS2821 RGB灯珠.

考虑到WS2812的静态功耗有点大, 所以三颗心分为三组, 除了最小的那颗无法主动关闭供电外,其余两颗心都会使用MOS管控制电源开关,达到不用时候彻底关闭省电的目的.

电路

打磨了好几个版本,最后决定做成双面元件.渲染如下:
healthpin3dmodel
healthpin3dmodeltop

实物

由于没有外壳, 而且阻焊是白色,所以看上去和游戏原设计有所出入.
real_health_pin

程序

上位机考虑到通用性质, 我没有像之前制作StatTrak那样单独写一个脚本和设备通信.
而是选择了Aurora这个开源项目作为上位机,在Auraro基础上进行二次开发.
好在Aurora对于新设备的适配提供了Device Script这个东西, 所以只要开发一个.cs脚本, 即可被Aurora识别到.
然后享受Aurora对大量游戏的支持,以及丰富的灯光配置.
aurora_add_script_device

CH592F假装自己是一个支持灯光配置的键盘, 使用HID和电脑进行通信.
HealthPin只会对7,8,9按键的配置响应, 所以Aurora 自定义配置时候,只需要设置这三个按键的灯光即可.
aurora_cs2_profile

视频

写在最后

视频发出后,有不少人指出胸章出自半条命:Alyx,以前只在老王家玩过开头, 对这个装置在半条命中的印象不是很深了.
观看了一些实况视频后了解到这个装置的更为具体的一些信息, 激发了我继续开发的一些兴趣.
或许可以制作三个完整的爱心,然后像Alyx中的一样, 每颗心都有大小的变化.

踩坑与收获:2025独立开发者Google Play上架实战复盘

背景与初衷

入行安卓开发有些年头了。学生时代我曾注册过Play开发者账户,当时审核比较宽松,上架比现在容易,但后来因违反政策,老账号被封,开发的APP也被谷歌下架。
play_store_old_account_screenshot

失业期间,出于对Compose的兴趣,我边学边做,开发了一款安卓平台的ESP32烧录工具,命名为ESPFlash

开端:注册开发者账号

上架Play Store的第一步,是使用谷歌账号支付25美元注册成为Play开发者。
注册链接是https://play.google.com/console/signup

作为个人开发者,我选择注册个人类型的账号。
register_play_developer_account

填写完基本信息后,输入信用卡信息完成扣款。我使用的是学生时代办理的交通银行Youth Power卡,支持银联和VISA。
play_develop_payment_record

创建应用和完善信息

在开发者控制台创建应用后,需要填写基本信息,并准备应用截图和隐私政策页面。

  • 尺寸符合要求即可。若追求美观,可使用 theapplaunchpadapp-mockup-mockup 等在线工具生成。
  • 隐私政策:这是关键。即使你的APP是工具类,未主动收集用户数据,但只要接入了Firebase、AdMob等第三方SDK,就必须在隐私政策中明确告知。我使用 free privacy policy 这类工具生成内容,并托管在自己的域名下。

封闭测试:最大的挑战与对策

这是最麻烦的地方, 由于谷歌政策调整,
现在注册的新的开发者账户上架APP需要12 名测试人员在过去至少 14 天内选择持续参与测试

起初觉得难以实现,但后来在 Reddit 的 AndroidClosedTesting 板块找到了解决方案。这里是安卓开发者互相帮助完成测试要求的地方

我在该板块发帖,召集其他开发者互相下载APP、完成打卡。仅第一天就招募到约20人。为了确保成功率,只要有新帖子出现,我也会主动下载对方的APP并参与测试。在这14天内,我大约测试了60款不同的APP。

正式版

14天测试期满后,即可在控制台提交正式版发布申请。
release_espflash
约3天后,我收到了审核未通过的邮件,要求整改。排查后发现,问题很可能出在隐私政策上——初始版本未充分说明Firebase和AdMob的数据处理情况。

更新隐私政策并重新提交后,仅用了几个小时就审核通过,成功上架Google Play。

总结

  • 政策研究要先行:尤其关注测试和隐私政策要求。
  • 封闭测试有捷径:善用Reddit等社区互助。
  • 隐私政策无小事:必须覆盖所有第三方SDK的行为。
  • 耐心与细致:审核被拒是常态,仔细阅读反馈,针对性修改。

后续

差不多过了一个月,迎接了第一份付费用户.
first_paid_user

UNO R4 Wi-Fi 接入 Home Assistant

项目介绍

本项目是Funpack第五期板卡三的任务1实现.
任务目标是让UNO R4 Wi-Fi通过网络连接到智能云端, 并模拟成一个可以控制的灯, 通过远程控制调整自带的LED矩阵点亮范围.

实现思路

将UNO R4作为灯装置接入IOT平台, 随后在IOT平台上下发命令来操作UNO R4, 调整这个”灯”的亮度.
这里我选择的是可以部署在内网环境下的Home Assistant.

UNO R4通过MQTT服务器与Home Assistant进行通信. MQTT服务器选择EMQX开源版.

结构图

服务器部署

本项目需要有一台服务器,并且在服务器上部署Home Assistant和EMQX两个服务.
本节简单介绍下两个服务的部署方式.

Home Assistant

Home Assistant官网上有较为详细的多种安装方式介绍.这里我选择的是使用Docker进行安装,可以忽略很多具体环境差异,只需要输入命令便可将Home Assistant跑起来.
具体介绍位于
Install Home Assistant Container

1
2
3
4
5
6
7
8
9
docker run -d \
--name homeassistant \
--privileged \
--restart=unless-stopped \
-e TZ=MY_TIME_ZONE \
-v /PATH_TO_YOUR_CONFIG:/config \
-v /run/dbus:/run/dbus:ro \
--network=host \
ghcr.io/home-assistant/home-assistant:stable

命令执行完毕,打开使用服务器IP配合默认端口号8123->http://:8123即可进入主面板.

EMQX

EMQX同样可以使用Docker进行安装部署, 页面通过 Docker 运行 EMQX详细介绍了所需的命令.

运行以下命令获取 Docker 镜像:

1
docker pull emqx/emqx:5.8.1

运行以下命令启动 Docker 容器。

1
docker run -d --name emqx -p 1883:1883 -p 8083:8083 -p 8084:8084 -p 8883:8883 -p 18083:18083 emqx/emqx:5.8.1

HomeAssistant对接到EMQX

进入HomeAssistant主页后点击右下角设置,选择设备与服务, 搜索MQTT

安装MQTT插件

安装好MQTT插件后,进入插件面板点击添加条目填写上一步配置的EMQX信息即可.

代码编写

注册到Home Assistant

publish 指定格式的payload到topic
其中topic格式为homeassistant/设备类型/自定义名称/config,根据格式要求.
得到主题应当为homeassistant/light/fun_matrix/config.
payload内容是一个描述设备的json字符串, 如下代码所示.

  • 其中name是设备名称;
  • device_class要和注册topic中设备类型对应;
  • command_topic代表设备的开关状态;
  • brightness_command_topic灯的亮度控制;
  • unique_id装置唯一ID;
  • device设备描述;
  • schema代表当前为json格式;
  • brightness代表本装置支持亮度控制;
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    void registerToHomeAssistantServer() {
    const char* topic = "homeassistant/light/fun_matrix/config";
    std::string message = R"({
    "name": "led",
    "device_class": "light",
    "command_topic": "fun_matrix/light/state",
    "brightness_command_topic": "fun_matrix/light/brightness/set",
    "unique_id": "fun_matrix",
    "device": {
    "identifiers": "fun_matrix",
    "name": "UnoR4WiFi"
    },
    "schema": "json",
    "brightness": true
    }
    )";
    bool retained = false;
    int qos = 1;
    bool dup = false;
    mqttClient.beginMessage(topic, message.length(), retained, qos, dup);
    mqttClient.print(message.c_str());
    mqttClient.endMessage();
    }

响应HomeAssistant命令

根据注册时候payload中brightness_command_topic和command_topic, 来响应具体的动作即可.
其中command_topic固定传递ON和OFF字符串, brightness_command_topic传递亮度值0-255.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
void onMqttMessage(int messageSize) {
String topic = mqttClient.messageTopic();
Serial.println(topic);
String payload;
while (mqttClient.available()) {
payload = mqttClient.readString();
Serial.println(payload);
}

if (topic.endsWith("state")) {
Serial.print("brightness_state_topic");
bool enable = payload.equals("ON");
if (lightIsOn != enable) {
lightIsOn = enable;
if (lightIsOn) {
showFrame(level);
} else {
showFrame(0);
return;
}
}
}
if (topic.endsWith("set")) {
Serial.print("brightness_command_topic");
level = payload.toInt() / 25;
Serial.println(level);
showFrame(level);
return;
}
}

功能展示

在网页上设置亮度, 均能够在设备上得到实时的响应.
不同的亮度,亮起的区域.

© 2025 Do U Find IT? All Rights Reserved.
Theme by hiero