结论:SAM 电动车这份 CAN 资料的价值不在规模,而在它把每一条解码修正的证据来源都写清楚了:37 条 BO_ 报文、161 条 SG_ 信号之外,另有十余处改动被分成「固件确认」「车主确认」「推断未确认」三档。最关键的一条是 0x292 的 FECU 故障寄存器——字节 6 与字节 7 相对标准 Intel 24 位读法是互换的,按错的字节序会把 0x200000 读成 0x00020。二次使用前应先按证据等级过滤,而不是把 DBC 整体当标准答案。
规模与总线前提:37 条报文是怎么构成的
这份 DBC 面向单一项目车辆,覆盖电池、电机、充电器、ECU、仪表与故障六类流量,不属于任何厂商车系的通用定义。报文总数 37 条里有一条是 Vector 的零长度独立信号容器,并非实际发送的帧,因此真实可收发的报文比计数少一条。总线速率是 125 kbit/s,但这个数字并不来自 DBC 自身:BS_: 行没有记录波特率,125 kbit/s 是车辆的已知实际设置,在回放工具里作为默认值写入。
轨迹侧的限制同样需要提前确认。配套解析只支持 PCAN-View 的 .trc v2.0,早期 v1.1 格式(列布局不同、没有 DT 标记)会被解析成零行,表现为「未找到任何 CAN 数据帧」的提示而不是报错崩溃。SAMPlay 记录仪的 .TXT 导出也被接受,且两种格式共用一个加载按钮,靠嗅探首个非空行的内容来分派,而不是看扩展名——后者只有 .txt 后缀,从扩展名上无法与其他文本区分。
时间轴上的取数模型也值得先明确:加载时每个信号在整段轨迹上完整绘制一次,光标滑块移动的是一条竖线,仪表、指示灯与状态标签按零阶保持重新取值,也就是取「最后一次实际收到的值」而不是插值。播放由 50 毫秒周期的定时器驱动,且每一拍都按起始时刻加实际经过的时间设置光标,而不是按固定步长累加,因此播放速度与墙上时钟一致,不受回调抖动影响。单步前进或后退跳到的是相邻帧自身的时间戳,所以「一步」始终等于一条报文。
| 项目 | 数值 | 说明 |
|---|---|---|
BO_ 条目 |
37 | 含 1 条零长度独立信号容器,非真实发送帧 |
SG_ 条目 |
161 | 覆盖电池、电机、充电器、ECU、仪表、故障 |
| 总线速率 | 125 kbit/s | DBC 的 BS_: 行未记录,取车辆已知设置 |
| 轨迹格式 | .trc v2.0、SAMPlay .TXT |
v1.1 解析为零行 |
| 电芯数 | 36 | 0x406 循环 37 个槽位,第 37 槽恒为 0 mV |
| 采样模型 | 零阶保持 | 刷取取「最后一次实际收到的值」,不做插值 |
三档证据:哪些改动能直接用
这份笔记最值得借鉴的做法,是把修正按可信度分档,而不是统一标注为「已修正」。固件确认档的依据是车辆仪表节点的 STM32 CAN 接收处理代码——代码不会撒谎,因此符号位、报文内容、字节序这类结构性错误一旦被代码确认,就可以当定论用。车主确认档来自车辆使用者的直接说明。推断档则只有数据回归作为支撑,必须保留原始计数并列显示,不能当作标定过的物理单位。
| 证据等级 | 涉及报文与信号 | 改动内容 | 判据 |
|---|---|---|---|
| 固件确认 | BO_912 Motor_speed |
无符号改为有符号 | 此前出现的约 65535 rpm 假尖峰由此而来 |
| 固件确认 | BO_658(0x292)FECU_error |
字节 6 与字节 7 互换 | 接收处理以 16 位指针取 RxData[6] 起两字节,再或上 RxData[5] 左移 16 位 |
| 固件确认 | BO_448 VoltageLV |
系数由 1 改为 0.00625 V/count | 固件阈值判断中直接出现该常数,改后读数约 13.8 V |
| 固件确认 | BO_960(0x3C0)Ustopcharge |
解码前先屏蔽字节 1 高 2 位 | 该 ID 在固件中被复用为 3 条子报文,高 2 位是复用标志而非数据 |
| 固件确认 | BO_400(0x190) |
占位信号名整体替换为 5 个 Skai 状态与故障位 | 固件对应分支定义了启用、功率模块错误、硬件错误、驱动错误、驱动告警 |
| 车主确认 | BO_657 trip_km |
系数由 1 改为 0.1 | 原始值按 100 m 步长存储,车主于 2026-08-05 确认 |
| 推断未确认 | BO_401/BO_656 扭矩 |
系数由 1 改为 0.005 Nm/count | 原始值在全部 5 段行驶日志中都精确截幅在正负 10000 |
| 推断未确认 | BO_657 加速与刹车踏板 |
有符号改为无符号 | 各日志中 28% 至 45% 的帧原始值落在 32768 以上 |
为什么 0x292 必须脱离 DBC 单独处理
故障寄存器不是一个连续字段,而是由三段拼接而成:字节 6 是最低字节,字节 7 是中间字节,字节 5 是最高字节。这种字节置换无法用一条连续的 SG_ 表达,因此该信号在 DBC 里干脆不再有信号行,改由解码函数直接从原始字节重建。后果很直观:按旧的连续小端 24 位读法,5 段行驶日志里每一帧都被解成 0x00020,而按固件正确的字节序是 0x200000——两者相差四个数量级,故障码从「20」变成「200000」。这类错误不会表现为异常,只会表现为一个看起来合理的错误码,所以必须拿固件代码交叉验证,而不是靠肉眼比对数值范围。
推断档:系数是怎么回归出来的
推断档的共性是找不到固件依据,只能拿总线上的另一个独立测量做参照。直流母线电压拿 BMS 的包电压做基准,比例稳定在 0.0997 附近,等于精确的一分之一;充电器高压沿用同一族系数,实测比例 0.06211 与十六分之一相差约 0.6%,落在两个独立电压传感器加零阶保持重采样的合理误差内。12 V 侧电流没有独立参照,改用功率平衡交叉验证:13.8 V 乘以换算后的电流,得到的 DCDC 输出功率中位约 160 W、区间 95 至 215 W,与车辆已知典型负载吻合。
| 信号 | 报文 | 采用系数 | 回归证据 |
|---|---|---|---|
skai_DC_Link_Voltage |
BO_656(0x290) |
0.1 V/count | 与包电压比值 0.0997 正负 0.002,样本约 36k |
VoltageHV |
BO_448(0x1C0) |
0.0625 V/count | 比值 0.06211 正负 0.00001,与包电压同族系数 |
DCDC_12V_Current |
BO_704(0x2C0) |
0.0625 A/count | 功率平衡后中位约 160 W,区间 95 至 215 W |
DCDC_HV_Current |
BO_704 |
0.0625 A/count(仅对称推定) | 约 36k 样本恒为 0,无任何非零验证点 |
Inside_temp/Outside_temp |
BO_960(0x3C0) |
0.1 摄氏度/count | 系数为 1 时读数 280 至 377 度,物理上不可能 |
| 扭矩(指令与实际) | BO_401/BO_656 |
0.005 Nm/count | 正负 10000 count 对应实车约正负 50 Nm |
仍以原始计数呈现、未做标定的有四类:DCDC_HV_Current、Voltage_12V、加速与刹车踏板开度、Ustopcharge。它们在界面上带原始计数标记,避免被误读成百分比或电压。
电芯内阻:两个不能跳过的测量约束
逐芯内阻估算用的是同一电芯相邻两次读数的电压差与电流差,按过原点拟合,这样未知的开路电压及其 SOC 漂移在差分中抵消。方法上有两条约束是数据逼出来的:电流必须取 10 Hz 的 0x386 而不是 1 Hz 的 0x186;电压相对电流存在约 1 秒滞后,忽略滞后会把相关系数从约 0.96 拉低到约 0.74,并使内阻低估约 25%。
| 环节 | 取值 | 影响 |
|---|---|---|
| 电流源 | 0x386,10 Hz |
0x186 仅 1 Hz,只作兜底 |
| 电压滞后 | 0.95 至 1.0 秒 | 滞后取 0 时相关性约 0.96 降到约 0.74,内阻低估约 25% |
| 电芯刷新周期 | 3.7 秒 | 0x406 循环 37 槽位,第 37 槽恒为 0 mV |
| 结果(新 BMS 车) | 约 0.67 至 0.70 毫欧/芯 | R 方约 0.95,95% 置信区间约正负 0.02 毫欧 |
| 结果(原厂 BMS 车) | 约 1.8 至 2.5 毫欧/芯 | 一致离群:10 号 +28%、19 号 +17%、28 号 +13%、12 号 +10% |
| 已知干扰 | BMS 启动垃圾帧 | 需按 1500 至 5000 mV、电流绝对值 1000 A 以内的合理窗过滤 |
两辆车的差异说明这套方法对 BMS 版本敏感:新 BMS 上报的 0x306 内阻最小、平均、最大三个值都是 1.0,看起来是占位值;原厂 BMS 则给出真实数值。跨车比较前必须先确认 BMS 变体。还有两点需要在使用结果时说明清楚:一是这里得到的是约 1 至 4 秒尺度上的有效内阻,包含快速极化,并不等于电芯规格书上的 1 kHz 交流内阻,而且它随温度变化——新 BMS 轨迹里的电芯温度读数平坦在 21 至 22 摄氏度,因此未做温度修正,只在汇总里显示范围;二是充电轨迹是恒流工况,几乎没有可用的电流变化,此时界面直接说明无法计算,而不是给出一个看起来合理的数字。另外,电芯离群判定默认阈值设在相对中位数高出 15% 及以上,在当前约 4% 的离散度下,逐芯排序在不同行程之间只能部分复现,因此单次结果不足以判定某颗电芯劣化。
验证步骤与三个真实陷阱
没有交互式显示环境可用,全部功能通过 matlab -batch 无头验证:以带路径参数的构造函数打开轨迹,再直接驱动返回结构体上的回调来模拟拖动、切页与按钮点击,把仪表、指示灯与状态值逐个对照手工解码的原始字节。回放通道则在 MathWorks 虚拟 CAN 回环上验证——一个通道发、另一个通道收——单步、突发顺序、解除武装、断连四类动作都逐帧比对,只有 USB 驱动层未经实测。另外还有一条一次性检查:确认界面配置里引用的每个信号键都真实存在于 DBC,改任一侧都应重跑。
| 陷阱 | 现象 | 定位与处理 |
|---|---|---|
| SAMPlay 文本解析 | FECU_error 在 389 帧里恒为 0 |
sscanf 的 %2x 只跳空白不跳逗号,遇到首个逗号即停,字节 1 至 7 全为初始 0;改用正则取两位十六进制记号后修复。影响面是所有位于字节 0 之外的信号 |
| 效率中位值大于 1 | 另一辆车未修正时中位效率 1.20 | 按「电池功率 = k 乘机械功率 + 损耗」逐格拟合,k 约 0.946(本车)与约 0.71(另一辆),两车控制器参数化不同 |
| 「2 秒后 CAN 上无 BMS」故障位 | 位 0x00200 在 3 份日志中从未置位 |
已核对原始字节,非解析缺陷:这些日志里 0x186、0x206、0x286、0x306、0x386、0x406、0x486、0x506、0x705 全部缺失,仅有的 0x205 发送方是仪表 ECU,只能说明仪表在命令接触器,不能证明 BMS 在线 |
| 回放安全 | 接入实车总线后习惯性点播放 | 连接本身不发送任何帧,需单独勾选「播放或步进时发送」才武装;BLE 断连、CAN 超时、按键三者任一都会释放 |
常见问题
这份 DBC 能直接用于我的车辆解析吗?
不能。37 条 BO_ 报文与 161 条 SG_ 信号面向单一项目车辆,覆盖电池、电机、充电器、ECU、仪表与故障流量,既不是厂商车系的通用定义,也不构成车型年款适配承诺。可作为同类电动车报文组织方式与修正记录方法的参考。
为什么故障码会显示成完全不同的数值?
因为 0x292 的 FECU_error 不是连续小端 24 位字段,而是字节 6 作最低字节、字节 7 作中间字节、字节 5 作最高字节。按标准字节序读会把 0x200000 读成 0x00020,两者相差四个数量级,因此必须按固件接收处理的方式从原始字节重建。
推断档的系数能不能当标定值用?
不能。扭矩的 0.005 Nm/count 只依据原始值在 5 段日志中一致截幅于正负 10000 与实车约 50 Nm 上限推出,没有独立传感器做回归;直流母线电压与充电器高压则有比值证据支撑,可信度更高。界面上保留原始计数并列显示,就是为了让使用者自行判断。
估算电芯内阻时最容易犯的错误是什么?
忽略电压相对电流约 1 秒的滞后,以及用 1 Hz 的 0x186 替代 10 Hz 的 0x386 作为电流源。前者会让相关系数从约 0.96 降到约 0.74 并使内阻低估约 25%,后者在零阶保持下会显著放大散点。
回放轨迹到真实总线上有什么前置条件?
需要车辆网络工具箱与适配器驱动,且连接并不等于发送:必须单独勾选武装开关才会真正发帧。未检测到适配器时会退回到虚拟通道。官方说明也提示,除驱动层外其余代码路径已在虚拟回环上验证,正式依赖前建议再做一次真实硬件冒烟测试。
延伸阅读
- 公共 CAN/DBC 数据集怎么选:四类来源与三道筛查 —— 把证据等级核对放进选源流程
- foxBMS 2 的 CAN 报文:41 条组件级定义与双许可证边界 —— 同为电池侧报文组织方式的对照
- 车载信号为什么会说谎:TTL、源时间与 500 ms 新鲜度阈值 —— 零阶保持与采样滞后对结论的影响
- Waterloo 2024CAR DBC 档案:115 个报文与 890 条信号 —— 车队级 DBC 的规模与维护方式
- 车型数据库 —— 按车型查 CAN 档案
参考资料
- 项目 01 ——
public-can-dbc-datasets/additional/janniksteiner-sam-can/PROJECT_NOTES.md(架构、解码修正的证据分级、推断系数回归依据与已知限制) - 项目 01 ——
public-can-dbc-datasets/additional/janniksteiner-sam-can/README.md(应用定位、支持的轨迹格式与项目文件构成) - 项目 01 ——
public-can-dbc-datasets/additional/janniksteiner-sam-can/SOURCE.md(37 条BO_与 161 条SG_的规模、两种 BMS 变体差异与许可证状态说明)
免责声明
本文所述的 DBC 与解码修正均为社区逆向工程与研究笔记产物,不代表车辆制造商的官方数据。文中数字均来自上述公开仓库的说明文件,未经独立实车验证;不同车型年款、ECU 固件与 BMS 版本可能存在显著差异,跨车套用字节偏移与系数前必须重新回归。该仓库为 GPL-3.0 许可,二次分发前请自行确认其对底层 DBC 与早期贡献的适用性。涉及安全相关用途时请仅作参考,并以实际测量与官方资料为准。
更新记录
- 2026-10-15 初稿