OpenRig 是我最近几个月一直在打磨的一个项目。起因其实很朴素:家里的成品运动设备换了两三台,但每次想把自己训练的数据导出来做分析,发现数据都锁在厂商自己的 App 里,导不出,也带不走。后来一台设备坏了,等了一个多月配件,客服还让我先自行排查线路,那一刻我就想明白了:设备可以是买的,但数据必须是我的,结构最好也是我能修的。所以我才动手做了 OpenRig,一套完全开放的、可以自己组装、自己校准、自己扩展数据的训练设备底座系统。
这套系统我做的是以力量训练和划船动作为核心的通用架体,搭配力传感器和姿态传感器,数据最后汇总到一块 ESP32 主控板上,再转发给自写的 Web 面板。你要是想复刻,不需要很强的动手能力,但需要一点耐心。整套硬件成本我压在了 800 元以内,全文我会把选型逻辑、固件框架、校准细节和踩过的坑都写出来,适合创客、业余健身爱好者,以及所有不想被品牌生态绑架的人。
1. 为什么放着成品不买,非要自己拼一套 OpenRig
很多人问我这个问题,我一般不会直接回答,而是让他们先看一下自己手边智能设备的传感器是什么型号、数据存在哪里、设备停产后还能不能用。看完这三个问题,大部分人自己就有了答案。
1.1 成品设备的硬件黑洞
运动器械这行很有意思,外观做得越来越炫,但内部其实没有太多高科技在里面。很多所谓智能划船机,核心就是一个磁阻飞轮加一个角度传感器,测量拉绳长度的方式可能还是最基础的电位器滑动变阻。这些东西不是不能用,只是精度和耐用性都有限,换一个第三方电位器可能比你找原厂配件容易得多,但厂商通常不公布原理图,你还得自己反向研究。
更要命的是数据封闭。我用过某款设备,训练历史全部走云端,App 一停服,我的几百条训练记录就再也无法分析,只剩厂商那句"感谢你的长期支持"。这类事在圈子里算是正常操作。但换个角度想,我花钱买的是硬件,硬件产生的数据凭什么归平台所有?这也是 OpenRig 最初的核心诉求:数据要留在本地,想怎么用就怎么用。
1.2 OpenRig 的设计目标
OpenRig 的定位不是去复刻一台几千块的成品器械,而是搭建一个底层的、可复用的"动作传感器平台"。我这个版本重点支持三类动作:划船拉拽、深蹲站起、卧推类水平推拉。通过更换或微调机械限位,它可以覆盖大部份复合动作的训练场景。
架构上我定了几条硬性原则:
- 硬件零件全部可买到,主体采用工业铝型材和标准紧固件,3D 打印只用来做非承力结构件,坏了随时重打。
- 传感器选型通用化,不搞定制 IC,只用市面上常见的重量传感器、IMU 模块、编码器,方便你 copy。
- 数据接口全开放,通过串口输出结构化文本帧,同时支持蓝牙和 WiFi,上位机随意换。
- 校准流程人性化,我一共提供两步标定流程,用家用体重秤和几瓶矿泉水就能完成,不需要专业实验室设备。
1.3 这套方案适合谁、不适合谁
如果你只是想每天划船 20 分钟打卡,那 OpenRig 不是最优解,成品设备开箱即用,省心得多。但如果你有一丁点数据洁癖,或者你想在自己训练计划里做动作分组、峰值功率分析,再或者你喜欢每周动动手,那 OpenRig 的路径会让你很舒服。
不适合的人我也必须提醒一下:如果你希望一装上就能用、不想看任何代码,那这个项目的前期成本会比较高,大概要 3 到 5 个晚上。OpenRig 更适合"我先组装、再理解、最后改造"的路径,是拿来玩的,不是拿来省事的。
2. 结构件与传感方案:OpenRig 的硬件底座怎么选
硬件选型是整个 OpenRig 项目最需要想清楚的部分。因为一旦结构做完,再想换传感器就得拆一堆螺丝。我第二次迭代时把承力传感器从 S 型拉压传感器换成了悬臂梁式称重传感器,就花了一整个下午重新设计了连接座。
2.1 结构材料:工业铝型材加打印件
OpenRig 的承力框架我用的是 4040 欧标铝型材,配合 M8 规格的 T 型螺母和角件。为什么不用方钢管?因为铝型材的优点是可调整、可拆装、公差友好,你不需要焊接,也不需要精确的切割尺寸,所有连接点都能松动调整。训练设备的力和角度其实是要一遍一遍试出来的,铝型材允许你装完以后微调 10 毫米、20 毫米,这在钢管结构上就很难实现。
连接件方面,承力角件用型材配套的标准角件,不省成本;非承力部分,比如传感器支架外壳、线缆卡槽、限位挡块,则全部用 PLA 打印。PLA 刚性够,但耐热差,所以放在远离电机和功率电阻的位置。
2.2 力的感知:悬臂梁称重传感器加 HX711
我最终选择的是 50kg 量程的悬臂梁式称重传感器,配 HX711 转换模块。选它的原因在于:这类传感器在家用厨房秤、体脂秤里量非常大,价格便宜且一致性不错;而且它的形变量只有零点几毫米,装在铝型材架上不会带来突兀的结构位移感。
HX711 是专为桥式传感器设计的高精度 24 位 ADC 模块,虽然有轻微漂移问题,但胜在稳定,而且库在 Arduino/ESP32 里非常成熟。这里我给出我的接线参考:
| HX711 引脚 | 接 ESP32 |
|---|---|
| VCC(模拟电源) | 3V3 |
| SCK | GPIO 18 |
| DT(数据输出) | GPIO 19 |
| GND | GND |
需要注意,HX711 模块分带稳压和不带稳压两种版本,我建议选带稳压的版本,它能给传感器提供更稳定的激励电压,读数更稳。电源不要直接接 5V,我试过接 5V 会导致模块温漂明显变大。
2.3 动作感知:IMU 与编码器的分工
单纯的力信号只能告诉你用了多大力,但没法判断动作是否标准。比如划船动作中,你是全靠手臂拉,还是先蹬腿再后倾背部,峰值力曲线完全不同。所以我加了两个感知维度:
- 杆端 IMU(MPU6050 或 BMI270):装在握把上,测量拉拽过程中的加速度和角速度,用来判断姿态变化。
- 底座编码器(增量式旋转编码器,600 线):安装在滑轮端,测量绳索拉出的长度和速度,用于计算做功距离和功率。
编码器方案上我踩过一个坑:最初用的是霍尔传感器加磁钢,想在滑轮上测转速,但下压和回程方向混在一起,只靠软件没法可靠区分,后来还是老老实实装增量编码器。虽然机械结构稍微复杂一点,但方向判断在固件里直接读 A/B 相位就能解决,一块两个 GPIO 的事。
2.4 主控选型:ESP32 的理由
主控板上我选了 ESP32 DevKitC 开发板,几块钱一块,但能力非常够用:双核 240MHz、内置 WiFi 和蓝牙、大量 ADC 引脚、还有丰富的外设接口。为什么不用 Arduino Uno?因为 Uno 的 ADC 只有 10 位(0~1023),精度在测量电压信号时明显不够,而且没有联网能力,数据链路到了 WiFi 就需要另外接模块。
ESP32 的 ADC 虽然也只有 12 位,但经过 HX711 做桥式信号的专用转换,精度瓶颈其实在传感器和供电稳定性上,不在主控。如果你后面想接心率带或者 GPS 模块,ESP32 的 UART 和 I2C 资源也充裕,无需再换板。
2.5 供电与走线
OpenRig 的整机供电我用了一块 12V 3A 的电源适配器,然后通过降压模块分成三路:ESP32 的 5V、传感器的 3.3V、以及将来想扩展的散热风扇 12V。这里我有一个很实际的建议:传感器和电机/电磁铁的供电必须隔离。我第一次调试时,只要电机一转,力传感器读数就跳好几个数,最后发现是共地干扰,把模拟供电单独用一路 LDO 并做好滤波电容后才稳定下来。
3. 固件与数据链路:让每一个力值都变成数字
硬件组装到能受力之后,剩下的事情都是让数据流动起来。这一部分也是 OpenRig 里软件含量最高的环节——它决定了你用起来顺不顺手、数据准不准。
3.1 从 HX711 读到的数据为什么不能直接用
很多人第一次接 HX711 就会遇到"数据一直在跳"的问题。这其实是正常的物理现象:力的作用本身就有高频波动,加上传感器和架子之间存在结构共振,直接读到的数值没有任何训练学意义。所以我在固件里做了三层处理:
- 原始采样:HX711 读取持续不间断,而不是按固定时间点读一次。
- 低通滤波:对原始值做一阶低通滤波(用简单的滑动加权),把 20Hz 以上的振动衰减掉。
- 去零漂:定期读取空载基准值,并把当前值和基准值的差作为有效输出。
// 一阶低通滤波,alpha 取值一般 0.2~0.6 float filteredValue = 0; void updateForceRaw(int rawValue) { filteredValue = (1 - alpha) * filteredValue + alpha * rawValue; forceValue = filteredValue - zeroOffset; // 减去零点漂移 }alpha 取值取决于你和设备的交互频率。划船拉拽大约 1~2 秒完成一次,alpha 可以取 0.4 左右,既保留峰值力,又不会因为滤波过度把峰值抹掉。
3.2 采样率怎么定
力值通道我定在 50Hz,姿态通道我定在 100Hz,编码器位置通道 100Hz。为什么力值不高一些?因为力量训练本身是慢速动作,拉一把最多 2 秒,峰值力持续时间有几百毫秒,50Hz 已经能很好还原曲线。采样率太高反而增加数据量和噪声处理负担,没有意义。
姿态的解算频率要高一些,特别是划船回桨阶段,手腕姿态变化快,低了容易丢失关键姿态拐点。ESP32 双核跑这两个频率绰绰有余,我让 Core 0 负责读取传感器,Core 1 负责数据打包和 WiFi 发送,互不阻塞。
3.3 数据帧格式:让外面的人也能接你的数据
OpenRig 输出的数据帧设计成最简单的文本行协议。每一行是一帧,字段之间用逗号分隔。这样任何一个上位机语言——Python、Node.js、甚至微信小程序——都能轻松解析。
OFRIG,TS=1234567890,F=310.4,P=68.2,V=1.83,A=0.45,HR=0字段说明:OFRIG 是协议头;TS 是微秒级时间戳;F 是力值(牛顿);P 是功率(瓦特);V 是速度(米每秒);A 是姿态状态编码;HR 是本次拉拽中的动作编号。这个格式我特意保持在 64 字节以内,方便未来做低功耗蓝牙广播。
3.4 传输链路:串口、蓝牙、WiFi 三选二
我在固件里做了三种传输模式:
- 串口模式:USB 接电脑直接读,调试时最方便。
- 蓝牙模式:接手机 App,适合在外面不想带电脑时用。
- WiFi 模式:UDP 广播到局域网,上位机 Web 面板实时绘制曲线。
这三种模式共用同一套组帧函数,只是发送目标不同。WiFi 模式我建议用 UDP 而不是 TCP,因为训练数据丢失一两帧完全没有影响,TCP 的拥塞和重传反而会造成曲线卡顿。
void wifiSendFrame(char* frame) { udp.beginPacket(ip, 9800); udp.printf("%s\n", frame); udp.endPacket(); }4. 校准与精度:数据能不能用的关键
这一章我要非常直白地讲:OpenRig 里最难的部分不是结构,也不是代码,而是让读出的数据可信。不校准的设备读数只能自娱自乐,没法做长期对比,也没法和商用设备横向评估。这里的功夫值得投入。
4.1 零点漂移和温漂,我总结出的规律
HX711 和传感器都有漂移。刚开始上电的 10 分钟里,读数会缓慢变化,这就是温漂——芯片内部和传感器应变片逐渐达到热平衡。所以我的固件里设计了一个"预热+自动归零"逻辑:开机 15 秒之内不记录训练数据,15 秒后取连续 50 次读取的平均值作为零点基准。
温漂的另一个来源是环境温度,尤其是放在阳台这种昼夜温差大的地方。我在面板后面加了一个温度传感器,实测下来,环境变化 5℃ 会让零点漂移约 0.5 牛顿。这个量级在力量训练中完全可接受,但如果你追求精确,可以做一段简单的线性温度补偿。
4.2 线性校准:两个砝码、一次计算
HX711 的读数跟实际力的关系是近线性的,但比例因子不是固定的整数。校准的方法不复杂:
- 先记录空载读数 zero0。
- 放一个已知重量的物体,比如一个 10kg 的杠铃片(有条件用 20kg 标准砝码),记录读数 load1。
- 重量 W 换算成力 F = W * 9.8(牛顿)。
- 换算比例系数 scale = (load1 - zero0) / F。
- 固件存储 scale 和 zero0,之后每个原始读数转换为 F = (raw - zero0) / scale。
我这里放一段 Arduino 环境下读取 HX711 并计算校准参数的示例逻辑,方便你直接集成:
#include <HX711_ADC.h> HX711_ADC LoadCell(19, 18); void calibrate() { LoadCell.tare(); Serial.println("请放上已知重量砝码..."); delay(10000); // 放置砝码 float knownForce = 98.1; // 10kg * 9.8 float rawAtLoad = LoadCell.getData(); scale = (rawAtLoad - LoadCell.getTare()) / knownForce; EEPROM.put(0, scale); EEPROM.put(4, LoadCell.getTare()); }我在测试中对比了家用电子秤、商用划船机和 OpenRig 在静载下的读数,误差稳定在 1% 以内,这在运动分析场景中已经足够优秀。多次重复测试的关键是:每次测试之间的重复性比绝对精度更重要。因为训练趋势分析依赖的是差值而不是绝对准确值。
4.3 动态精度:为什么静态测出来准,发力时还是差
静态校准解决的是恒力读数,但运动是动态的,数据里既有力又有加速度,还有结构形变。我的实际经验是:动态精度更多取决于机械刚性,而不是传感器精度。铝型材连接点如果存在松动(哪怕零点几毫米),拉拽时就会产生额外的振动信号,滤波器再强都救不回来。
因此,你在组装 OpenRig 时,请务必做到:第一,所有承力角件的螺栓都用扭矩扳手按标称值锁紧;第二,传感器连接端不能直接用 3D 打印件,必须加金属转接板。这两条做好了,动态精度才有基础。
5. 上位机应用:从数据流到训练复盘
硬件把数据吐出来了,但数据落在 Python 终端里没人愿意看。OpenRig 的完整体验,其实还包含一个可视化层:实时曲线、动作计数、历史对比。这是我花时间最多、但也是让项目真正落地的地方。
5.1 实时绘图面板
我用 Python 的 pyqtgraph 写了一个本地桌面面板,局域网内直接订阅 UDP 数据,画出三根曲线:力值、速度、功率。选 pyqtgraph 的理由是性能好,数据更新到 100Hz 也不卡。
如果你更想用浏览器方案,可以用 Node.js 的 WebSocket 服务端加 Chart.js 前端,二者选一个就行。我的建议是,第一版先用 Python 做,因为迭代代码快,后面稳定了再迁移到 Web 端。
# 简化版 UDP 接收代码 import socket import pyqtgraph as pg sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind(("0.0.0.0", 9800)) while True: data, _ = sock.recvfrom(128) frame = data.decode().strip().split(",") if frame[0] == "OFRIG": force = float(frame[3].split("=")[1]) # 追加到绘图曲线5.2 动作计数与姿态判断
姿态状态编码 A 是上位机逻辑的关键。我用 IMU 的数据把动作过程切分成四段:准备、发力、保持、回程。上位机根据这四个状态的时序组合,再加上力值的阈值条件(比如力度超过体重的 20% 才计一次),就能准确计数。
很多成品设备计数不准,问题就出在只用力值判断单次动作。我用姿态加力值双条件之后,误计率从 12% 降到了 2% 以内。具体做法很简单:把 IMU 融合出来的俯仰角变化量当作启动条件,力值过阈值作为完成条件。
5.3 数据导出与外部对接
OpenRig 的上位机支持一键导出 CSV,但还不够。我做了三件事让数据价值更大:一是把原始曲线图片导出为长图,方便做训练笔记;二是生成每周汇总统计,包括总做功、平均功率、峰值功率、训练时长;三是按开源协议开源全套代码,方便别人直接扩展。
如果你希望把 OpenRig 数据接到专业运动软件,比如 TrainingPeaks 或 Golden Cheetah,可以通过自写的 FIT 文件转换器实现。这一步稍微繁琐,但好在 FIT 文件格式是公开的,社区也有 Python 解析库,动手能力强的朋友可以尝试。
6. 成本清单与踩坑记录
最后这部分是很多读者最关心的:一共花了多少钱,哪些地方最容易翻车。我按 BOM 的维度做了一份表,你可以直接在电商平台搜同款。
6.1 硬件成本明细
| 部件 | 数量 | 参考单价(元) | 用途 |
|---|---|---|---|
| 4040 铝型材(1 米) | 4 根 | 45 | 主体框架 |
| 铝合金角件 | 12 个 | 3 | 框架连接 |
| 悬臂梁称重传感器 50kg | 1 个 | 35 | 力感知 |
| HX711 模块(带稳压) | 1 个 | 12 | 力桥信号采集 |
| MPU6050 模块 | 1 个 | 9 | 姿态感知 |
| 增量旋转编码器(600 线) | 1 个 | 28 | 绳索位置追踪 |
| ESP32 DevKitC | 1 个 | 30 | 主控 |
| 12V/3A 电源适配器 | 1 个 | 25 | 供电 |
| 降压模块(LM2596) | 2 个 | 6 | 电压转换 |
| 绳索与滑轮组件 | 若干 | 40 | 传动 |
| 3D 打印零件 | 约 100g | 30 | 非承力结构件 |
| 线材、端子、热缩管 | 若干 | 50 | 连接与保护 |
| 合计 | - | 约 780 元 | - |
需要注意的是,这个价格没有包含工具(台钻一把 60 元),不考虑快递费。整体看,用成品设备三分之一的价格,得到了一套数据完全开放的平台,性价比很高。
6.2 我踩过的几个坑
第一个坑是 ADC 精度。ESP32 的 ADC 噪声比预期大,直接采集桥式信号时峰值抖动非常明显。后来我把数据读取改到 HX711 之后才解决。以后凡是桥式传感器信号,我都优先走专用 ADC 芯片,不会让 MCU 自带 ADC 直接干这个活。
第二个坑是电源干扰。因为我在同一个供电链路里放了电机驱动器,只要电机启动,力值面板就会跳字。排查到最后确认是电源地回路共阻抗的问题。解决办法是模拟部分和功率部分完全隔离,各用一个 LDO 或 DCDC 单独供电。这里花了整整一个晚上排查,我不希望你重走这段路。
第三个坑是蓝牙距离。ESP32 的蓝牙默认发射功率调到最高也只有 7~8 米稳定距离,隔一堵墙就开始出现延迟。所以在运动场景下,我优先推荐 WiFi 模式,除非你手机打算一直放在器材边上。
6.3 后续还能做的扩展
OpenRig 目前的版本已经能稳定支持力量训练的数据采集和复盘。下一步我觉得值得做的方向有三块:第一,把动作识别从划船和深蹲扩展到硬拉、引体向上;第二,加入语音反馈,让训练时实时播报每一把的功率;第三,加一个简单的机器学习模型,通过姿态数据推测动作质量,给出训练建议。
如果你也打算做一套,我的建议是不要一上来就想做全能版,先把力值通道跑通,再加姿态,再加网络,一层一层来。硬件项目的乐趣很大程度就来自于这种逐步叠加的过程。这套系统的代码和图纸目前都整理在项目仓库里,用关键词 OpenRig 就能找到,里面包括我调试时留下的原始数据和完整注释。希望这个故事能帮你省掉一些弯路,早点把数据握在自己手里。