标签: CAN总线

  • 雪铁龙 C2 的 PSA 舒适总线:125 kbit/s、38 个 ID 与四级证据

    结论:雪铁龙 C2(BSI gen 2、AEE2004)的 CAN-Confort 走 125 kbit/s、11 位 ID,接入点在收音机后方 Quadlock 的 10 脚(CAN-H)与 13 脚(CAN-L),OBD 口不暴露这条总线。实测约 185 帧/秒、38 个不同 ID,其中 16 个是已识别的 AEE2004 PSA ID。真正决定可用性的不是 ID 数量,而是四级证据标记:只有方向盘按键、灯光、车门、续航、油量等少数信号做了实车动作对照,冷却液温度与机油温度仍停在单点标定,外部温度与里程表则存在互相冲突的公式。

    先把三条总线分清:舒适、IS 与诊断

    PSA AEE2004 平台上「CAN」不是一个东西。CAN-Confort 是 125 kbit/s,承载车身舒适与信息显示类信号,物理接入在收音机后方;CAN-IS 是 500 kbit/s,承载发动机、ABS、安全气囊,本文范围之外;诊断走的是另一条路——Lexia/Diagbox 通过 OBD 与 BSI、发动机 ECU 等模块对话。

    这个划分有直接后果:电池电压在舒适总线上取不到,材料明确写它需要经 UDS 从 BSI 读;进气温度同样不在舒适总线上。反过来说,诊断侧能看到的值(真实里程 110506.9 km、机油温度 64–72 °C)也不等于舒适总线上有对应报文——里程表就被明确记为「在 CONF 总线上找不到、由组合仪表本地管理」。

    四级证据标记:这份档案最有价值的部分

    标记 含义 可信程度
    ✅ 在 C2 上验证过:物理动作与该位变化对应(2026-04-26 场地测试),或数值经用户确认 可直接用于功能
    🎯 只在单一测量点(Lexia/Diagbox)上标定过,斜率未验证 该点附近可用,外推不可靠
    📄 取自参考结构(PSAVanCanBridge AEE2004),未在 C2 上验证 仅作候选,须实测
    ⚠ 来源互相冲突,见「证据边界」 暂不可用

    两个哨兵值也要单独记住:温度类字节为 0xFF、里程为 0xFFFFFF 时表示「BSI 刚唤醒、尚未就绪」,解码器必须返回空值,而不是把它们当成真实读数。

    已解码的接收帧

    ID 字节.位 / 字节 字段 解码 证据
    0x0B6 b0–b1 大端 发动机转速 ÷ 8,怠速 704–768 RPM ✅
    0x0B6 b2–b3 大端 车速 ÷ 100 km/h,静止已验证 ✅
    0x0F6 b1 冷却液温度 字节 − 53 °C(92 °C ↔ 0x91) 🎯
    0x0F6 b0.3–4 钥匙位置 0 STOP、1 CONTACT、2 STARTER、3 FREE 📄
    0x128 b0.5 / b2.1 手刹 / 危险警告灯 位为 1 即激活 ✅
    0x128 b4.1 / b4.2 / b4.5–7 左转向 / 右转向 / 远光·近光·示宽 位图;远光与近光互斥 ✅
    0x161 b3 燃油百分比 百分比直读;升数 = 百分比 × 油箱容量(默认 41 L) ✅
    0x161 b2 机油温度 字节 − 64 °C(71 °C ↔ 0x86,解出 70) 🎯
    0x21F b0.1 / b0.2 / b0.3 SOURCE / VOL− / VOL+ 位图;本车 VOL+ 与 VOL− 与 PSA 通用文档相反 ✅
    0x21F b1 滚轮计数 累加计数,应用取相邻两帧的有符号增量 ✅
    0x220 b0.7 / b0.6 / b0.3 左前门 / 右前门 / 尾门 位为 1 即开启 ✅
    0x221 b3–b4 大端 续航里程 km;0xFFFF 为未计算(440 km 已验证) ✅
    0x261 b4 行程平均油耗 ÷ 10 L/100(7.6 ↔ 0x4C) ✅
    0x3A7 b3–b4 / b5–b6 保养剩余里程 / 天数 大端;对照值 15560 km、691 天 📄

    0x21F 是这份档案里唯一被完整验证的帧,也是项目初始目标。除了位图,它还有一个实用细节:按键按上升沿处理并加 200 ms 去抖。0x0B6 的另一个作用是定节奏——它以 20–50 Hz 发出,界面按 10 Hz 采样,音频则逐帧跟随。

    方向盘按键与 PSA 通用文档不一致

    通用文档给出 0x04 = VOL+、0x08 = VOL−,而这辆 C2 的实测结果是相反的:0x04 = VOL−、0x08 = VOL+,0x0C 由应用约定为 MUTE。另有 bit 0、bit 4、bit 5 在这辆车上无效果,已实测排除。这类「平台通用、单车相反」的差异,正是照搬同平台档案最容易踩的坑。

    发送帧与它的前置条件

    ID 内容 状态
    0x3E5 EMF 按钮位图 6 字节;模式激活期间每 65 ms 发一次 00×6,按键时发置位帧 仅当 BSI 被远程编码为「RD4 存在」时有效,否则 EMF 忽略
    0x39B 5 字节:年份 − 1872、月、日、时、分 对 EMF 时钟无效
    0x21F 方向盘按键位图 仅供测试(收音机在同一总线上)

    0x3E5 的按钮位分布来自 PSAWifiDisplayControl 的 CanMenuStructs.h:字节 0 的位 0/4/6 为 AIRCON、PHONE、MENU;字节 1 的位 4/6 为 MODE、TRIP;字节 2 的位 2/4/6 为 DARK、ESC、OK;字节 5 的位 0/2/4/6 为 LEFT、RIGHT、DOWN、UP。材料同时警告:所有发送都落在车辆真实总线上,发送类试验不得在行驶中进行。

    Diagbox/Lexia 侧真值:哪些只在诊断侧确认过

    2026-05-03 的 Lexia 会话留下了一组 ground truth,用来给解码器做标定。必须区分清楚:这些值是诊断工具读出来的,其中一部分已在舒适总线上找到对应字节并打上 ✅,另一部分至今没找到对应报文。

    字段 Lexia 读数 在舒适总线上的状态
    怠速转速 704–768 RPM 已确认:0x0B6 b0–b1 大端 ÷ 8
    平均油耗 7.6 L/100 已确认:0x261 b4 ÷ 10
    外部温度 23 °C 已确认:0x0F6 b4,(字节 − 49) ÷ 2(字节 0x5F = 95)
    冷却液温度 86–92 °C(变动) 单点标定:字节 − 53 °C,斜率未验
    机油温度 64–72 °C 单点标定:字节 − 64 °C,斜率未验
    总里程 110506.9 km ❌ 舒适总线上未找到,由组合仪表本地管理
    进气温度 47–48 °C ❌ 未在该总线上找到
    电池电压 12.30 V(熄火)→ 14.10–14.20 V(运行) ❌ 需经 UDS 从 BSI 读取
    燃油量 原始 22.70 L / 显示 22.58 L / 油表阻抗 162 Ω 百分比已确认,升数由百分比换算

    诊断侧还确认了模块身份:EMF(ECRAN_A)PSA 件号 96 597 970 77、供应商 Magneti Marelli、软件版本 007.016;发动机 ECU(J34P)供应商 JCAE、ECU 参考号 9651696680、软件版本 0B02。这条信息解释了后面的一处死结:这台 EMF 是 Magneti Marelli 自有固件,与文档中常见的其他供应商 EMF 不同。

    证据边界:待验证与未解

    项目 冲突或缺失 材料给出的验证程序
    外部温度 ⚠ 三个公式都只拟合到同一点 23 °C:代码用 b6 − 102;场地测试用 (b4 − 49) ÷ 2;第三方用 (b5 右移 1) − 40。PSA 常见斜率为 0.5 °C/位,用 − 102 时在 10 °C 处偏差可达约 6 °C 在两个相差较大的环境温度下抓 0x0F6,记下 EMF 显示值,选同时贴合两点的公式
    总里程 ⚠ 字节 2–4 ÷ 10 取自参考结构;场地测试未找到匹配模式;代码里记的 Lexia 点也不自洽(0x10D85F = 1103967,而非 1103455) 出行前后各记一次组合仪表读数与 odo 对比
    水温 / 油温斜率 🎯 各自只有一个标定点 冷车与热车各测一次,与 Lexia 比对
    行驶中的车速 0x0B6 车速只在静止状态验证过 与 GPS 对比(界面同时显示两者)
    保养帧 0x3A7 未与 Lexia 值(15560 km / 691 天)比对 下次会话直接比对
    行程距离 0x261 仪表显示的 884 km 未在任何字节中复现,格式未确认 待定
    EMF 时钟 0x39B、0x276、0x228 在 AEE2004 LS.CONF 上无效;AEE2004 的时钟主是 EMF 自身,经 0x3F6 以 1 Hz 广播;Lexia/Diagbox/PP2000 被三个独立来源确认无法设置该时钟 仅存三条替代路径:临时接入二手 RD4、完整 RD4 模拟器、直接改用收音机时钟
    BSI 日期帧 0x276 在这辆 C2 的舒适总线上完全缺席 解码器保留,但只有当该帧出现时才有意义

    「EMF 是时钟主」这一点推翻了常见的模型:BSI 是消费者而非提供者。因此任何试图用 CAN 帧把时间写进 BSI 的做法,在这代平台上从方向上就是错的。

    常见问题

    CAN-Confort 能不能从 OBD 口读到?

    不能。这辆 C2 的舒适总线接入点在收音机后方的 Quadlock 连接器:10 脚 CAN-H、13 脚 CAN-L,材料明确写明 OBD 口不暴露这条总线。实测配置是 CANable 2.0(slcan 固件),总线上已有终端电阻,因此适配器侧不加 120 Ω。

    为什么电池电压、进气温度这类值一直找不到?

    因为它们不在舒适总线上。材料把电池电压标注为 AEE2004 舒适总线上无法干净取得,需经 UDS 从 BSI 读取;进气温度同样未在该总线上找到。这两项属于 CAN-IS 或诊断路径的范围,用舒适总线的抓包去找必然无果。

    外部温度该用哪个公式?

    暂不能确定,三个公式都只拟合到同一点 23 °C:代码当前用 b6 − 102,场地测试给出 (b4 − 49) ÷ 2,第三方实现用 (b5 右移 1) − 40。PSA 常见斜率为 0.5 °C/位,用 − 102 在 10 °C 处偏差可达约 6 °C。需要在两个相差较大的环境温度下各测一次才能定斜率。

    往总线上发 0x3E5 为什么没有反应?

    因为 EMF 只在 BSI 被远程编码为「RD4 存在」时才监听该帧。材料记录用户在 Diagbox 中重新启用了 RD4 远程编码,此后 EMF 应回到监听 RD4 帧的模式;在此之前发送会被忽略。另外该帧需要在模式激活期间每 65 ms 发一次全零保活,按键时才发置位帧。

    能不能用 Diagbox 把 EMF 的时钟调好?

    不能。材料称 Lexia/Diagbox/PP2000 对 C2 的 EMF 时钟无效,依据来自三个独立来源(PSA 经销店、207 与 RCZ 论坛),且没有针对 EMF 时钟的文档化 DID。三个已测无效的 CAN ID(0x39B、0x276、0x228)在 AEE2004 LS.CONF 上根本不存在;该平台的时钟主是 EMF 自身,经 0x3F6 以 1 Hz 广播。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/wasabules-citroen-c2/docs/can/signaux_decodes.md(四级证据标记、RX 帧逐位定义、TX 帧与待验证清单)
    • 项目 01 —— public-can-dbc-datasets/additional/wasabules-citroen-c2/docs/can/psa_can_confort.md(125 kbit/s 与 500 kbit/s 分工、方向盘按键 ID 纠正、0x3F6 时钟模型)
    • 项目 01 —— public-can-dbc-datasets/additional/wasabules-citroen-c2/docs/can/lexia_diagbox_findings.md(2026-05-03 会话的模块识别与 ground truth 表)
    • 项目 01 —— public-can-dbc-datasets/additional/wasabules-citroen-c2/docs/can/c2_field_test_results.md(2026-04-26 场地测试的 38 个 ID 与失败项)
    • 项目 01 —— public-can-dbc-datasets/additional/wasabules-citroen-c2/README.md(车辆与硬件配置、Quadlock 引脚、发送风险警告)

    免责声明

    本文所述解码均为社区逆向工程产物,不代表 Stellantis、雪铁龙或 PSA 的官方数据。文中所有 ID、字节位与数值均来自上述公开仓库的说明文件,其中标注为单点标定或参考结构的部分未经充分实车验证;不同年款、ECU 版本与远程编码配置可能存在差异。向车辆总线发送报文存在干扰电控单元、耗尽蓄电池等风险,切勿在行驶中进行发送类试验。

    更新记录

    • 2026-10-15 初稿

  • 奔驰 W212 仪表的 CAN 笔记:0x001 一个字节控制点火状态

    结论:2010 款梅赛德斯-奔驰 E350 轿车(底盘 212.056)的仪表在 20 针连接器上只有 7 个脚需要接:1 脚地、4 与 6 脚 +12 V、12/13 脚 CAN E、17/18 脚 CAN B。用一块 Arduino Mega 2560 加 MCP2515 屏蔽板以 500 kbit/s 只驱动 CAN E,就足以把仪表在预启动与整车上电状态之间反复切换——控制只需一个 ID、一个字节:CAN ID 0x001,字节 0 取 04 为全开、00 为关闭。而这个 ID 并不在随附的 DBC 文件里。

    七根线的接线表

    仪表背面只有一个连接器且没有任何标注。依据原厂维修文档的电气图,20 个脚里只有 7 个需要关注:1、4、6 三脚是地与电源(其中一路推测为点火触发),剩下四脚分成两组 CAN。

    仪表引脚 连接
    1 接地
    4 +12 V
    6 +12 V
    12 CAN E Low
    13 CAN E High
    17 CAN B Low
    18 CAN B High

    两组 CAN 各自在两端配置 120 Ω 终端电阻,屏蔽板一端与仪表一端各一个。只通电而没有有效报文时,模拟时钟归位到 12:00,屏幕、背光、警告灯与指针全部保持不动——这个现象本身就是有用的基线判据。

    本次台架只有一块 Arduino Mega 2560,因此一次只能驱动一条总线,下列结果全部来自 CAN E(12、13 脚),CAN B 未连接。配置参数为:Seeed Studio CAN-BUS Shield V2.0(MCP2515 控制器)、CAN 速率 500 kbit/s、MCP2515 时钟 16 MHz、串口 115200 波特并以换行结束。

    DBC 的十进制陷阱与八条报文的实测结果

    参考用的 mercedes_benz_e350_2010.dbc 给报文起名字、描述已知信号在载荷里的位置,但它不保证每条定义都完整或正确。这份文件里有一个必须先纠正的坑:报文 ID 用十进制书写,写进 Arduino 程序前必须转成十六进制。

    DBC 报文名 十进制 ID 十六进制 CAN ID 当前结果
    DRIVER_CONTROLS 69 0x045 显示屏唤醒与 OK 键控制可用;方向盘其余按键未解
    IGNITION 581 0x245 DBC 未给出任何字节或信号定义;静态载荷穷举无可见响应
    WHEEL_SPEEDS 515 0x203 未测试;车速表控制的主要候选
    DOOR_SENSORS 643 0x283 车门开与关状态可用
    SEATBELT_SENSORS 885 0x375 未测试
    GAS_PEDAL 261 0x105 未验证;DBC 含发动机转速字段但定义不完整
    GEAR_LEVER 109 0x06D 未测试
    GEAR_PACKET 115 0x073 未测试

    另一个容易混淆的点:日志里偶尔出现仪表发出的十六进制 ID 0x581,它与十进制 581 不是同一条报文——十进制 581 是 0x245。DBC 帮着确认了 0x045 与 0x283 的可用性,也给出了 0x245 这个点火相关候选,但真正的点火控制最后是在 DBC 之外的 0x001 上找到的。

    一个字节的点火状态表

    最初的候选载荷带一个七字节后缀 80 CF AD AA 07 10 55,逐一把字节 1 到 7 清零后,四个状态的行为完全不变——字节 0 单独就够用。以 100 ms 周期发送、DLC 为 8:

    字节 0 字节 1–7 台架确认行为 当前标签
    00 全零 回到预启动状态,屏幕随后休眠 OFF
    04 全零 自行唤醒仪表并产生完整上电响应 最小全开
    C2 全零 仅安全带警告灯与 SRS 故障提示,仪表背光不全亮 受限 / 类 ACC
    CC 全零 警告灯全亮、仪表与屏幕背光亮、循环显示缺失系统警告、有提示音 备用全开
    CF 全零 从全开状态约 1.5 秒后回到预启动 延时关闭
    07 全零 持续保持时约 1.5 秒后回到预启动;保持 450 ms 后切回 CC 则维持全开 过渡候选,含义未知

    最简可靠的开/关对因此是:ON 为 04 00 00 00 00 00 00 00,OFF 为全零。另一个关键结论是 0x001 的点火报文可以自行唤醒仪表——把 0x045 唤醒报文关掉后它依然生效,说明 0x045 只负责屏幕与菜单交互,不是上电响应的必要条件。

    0x045 自身的两个载荷也被重新确认过:唤醒用 00 00 00 00 FF 00 00 00,会亮屏并显示「PRE-SAFE Functions Limited」;b[5] 由 00 变为 02 相当于短按方向盘 OK 键,用来清掉这条提示。车门帧 0x283 按 DBC 的交替编码:bit 0/2/4/6 分别为左前、右前、左后、右后「关闭」,bit 1/3/5/7 为对应「开启」,全关是 55 00 00 00 00 00 00 00,左前开是 56 00 00 00 00 00 00 00。

    用仪表自己发出的报文做机器可读判据

    仪表在运行中会自己发报文,很多 ID 在预启动与全开状态下都在发,所以「某条报文存在」没有判断价值,有价值的是可重复的载荷变化。两条报文成了可靠的状态指示器:

    仪表状态 CAN ID 0x015 CAN ID 0x39D
    全开 3D FE 00 00 80 02 FF FF 00 8E 70 XX
    关闭 / 预启动 00 FE 00 00 FF 02 FF FF 00 8E 70 XX

    0x39D 的字节 0 就是状态位:80 为全开、FF 为关闭。该帧最后一个字节按 07, 0F, 17, 1F, 27, 2F, 37, 3F, 47, 4F, 57, 5F, 67, 6F, 77, 7F 循环,很像 alive counter,判断状态时不能当固定值用。

    关闭时序也被这两条报文量了出来:命令切到 CF 后,0x015 的字节 0 在约 1.45 秒后由 3D 变为 00,0x39D 的字节 0 在约 1.50 秒后由 80 变为 FF。这是「CF 是有效的延时关闭命令」的直接证据。

    仪表发出的 ID 观测到的变化 当前解释
    0x1C1 启动序列中由 00 00 00 00 短暂变为 08 00 00 00 后归零,仪表仍保持点亮 启动或警告灯自检标记,不是稳定的点亮判据
    0x19F 在含 F0 00、FF FF、F0 01、F0 02 等形态间变化 内部显示或运行状态,变化慢,不适合做主判据
    0x3E1 字节 0 在延时关闭附近短暂由 11 变 10 再回到 11 短时过渡事件或确认,未解
    0x39F 多个字段在点火试验前后持续变化 可能含计数器或计时器,而非单个点火标志

    这些都是仪表的输出,适合用来监控,不应该当成点火命令去回放。

    07 的时序试验做了什么

    为了判断 07 是不是启动(crank)状态,项目单独写了一个测试:先发 CF 三秒,再用 CC 直到 0x015 等于 3D 且 0x39D 字节 0 等于 80 各被确认三次,继续发 CC 500 ms,然后发 07,请求时长 450000 µs、实测 450432 µs,随后切回 CC 观察 8 秒。脉冲期间所有 0x015 保持 3D FE 00 00、0x39D 字节 0 保持 80、0x1C1 保持全零,没有出现任何独特的可见或可听响应;恢复 CC 后仪表维持全开,8 秒内没有发生延时关闭。

    已解与未解清单

    功能 状态
    CAN E 电气连接 已确认
    屏幕唤醒(0x045) 已确认
    方向盘 OK 键(0x045) 已确认
    车门全关 / 左前门开(0x283) 已确认
    最小全开(0x001 字节 0 = 04) 已确认
    受限 / 类 ACC(C2)、备用全开(CC)、延时关闭(CF) 已确认
    450 ms 的 07 脉冲后接 CC 保持全开 已确认
    点火期间是否需要 0x045 唤醒 / 0x2F8 均不需要(已确认)
    机器可读的开/关判据(0x015、0x39D) 已确认
    DBC 中 0x245 的静态载荷搜索 无响应
    方向盘其余按键、车速表、转速表、燃油与水温表 未解
    CAN B 网络 未测试

    全开状态下仪表会循环显示大量缺失系统的警告并发出提示音,原因是台架没有提供 SRS、ESP/ABS、发动机、变速箱、PRE-SAFE、Tele Aid、胎压等系统以及 CAN B 上各模块的报文。这些警告恰恰是「仪表确实进入了完整工作状态」的证据,不代表那些系统已被模拟或解码。

    证据边界

    未决问题 现状
    0x001 是否为原厂点火开关报文 未证明;只证明它在该台架上可复现地控制状态
    04 / C2 / CC / CF / 07 的原厂含义 未从真实车辆录制中确认;标签只描述台架行为
    07 是否为启动状态 未证明;也可能只是未通过 1.5 秒关闭延时的非 ON 值
    0x2F8 伴随帧 单独发送无变化;与 C2 同发时出现「SOS Tele Aid Inoperative」;与 CC 同发无即时变化,含义未知
    DBC 的 0x245 64 次单位置位、每字节 12 个候选值、每字节 00–0F 共三轮穷举均无响应;可能仍需计数器、校验、伴随帧或前置状态
    0x1C1 / 0x19F / 0x3E1 / 0x39F 未完全解码
    单总线测试 一次只能驱动一条 CAN,无法复现整车内的全部交互

    这里有一条方法论上的界线值得单独说明:一条报文即使原厂含义未知,也完全可以在模拟器里好用。标签描述的是台架上看到的行为,不等于它在每一代 W212 上的生产编码。

    常见问题

    为什么 DBC 里的 581 不是 CAN ID 0x581?

    因为该 DBC 用十进制书写报文 ID,581 要转成十六进制才是 0x245。日志里偶尔出现的十六进制 0x581 是仪表发出的另一条报文,与十进制 581 无关。写进 Arduino 程序前必须做这次进制转换,否则发到了完全不同的 ID 上。

    只接 CAN E 能不能让仪表完整工作?

    不能。仪表同时接收 CAN E 与 CAN B,只接 CAN E 时它拿不到其余系统的信息,因此会循环显示缺失系统的警告并发出提示音。本次台架受限于只有一块单片机,全部结果都来自 CAN E,CAN B 尚未测试。原厂文档也说明仪表需要两路总线输入、电路 15 状态、轮速来计算车速,以及发动机运转信息与转速来驱动转速表。

    怎么判断仪表是否真的进入了点火状态?

    不要看某条报文是否存在,而要看可重复的载荷变化:0x015 在全开时为 3D FE 00 00、关闭时为 00 FE 00 00;0x39D 的字节 0 在全开时为 80、关闭时为 FF。发 CF 后,两者的切换分别发生在约 1.45 秒与约 1.50 秒。注意 0x39D 的末字节是循环计数,不能当固定值比对。

    DBC 里 0x245 的静态穷举没有任何反应,是不是说明这个 ID 无效?

    不能这样推断。DBC 只给了 BO_ 581 IGNITION: 8 XXX,没有信号位置、计数器、校验或有效载荷示例。单位置位 64 次、每字节 12 个候选值、每字节 00–0F 共三轮搜索都无可见或可听反馈,但真实报文可能需要多个非零字节、alive counter、校验和、伴随帧或某个前置状态。既然 0x001 已能提供可靠的台架控制,继续盲搜 0x245 的优先级较低。

    07 到底是不是启动状态?

    还不能确认。已证明的是:由 CC 保持 07 超过约 1.5 秒会让仪表回到预启动;而保持约 450 ms 再切回 CC 则维持全开,脉冲期间 0x015、0x39D、0x1C1 均无变化。这可能是一个真正的启动状态,也可能只是一个没能撑过仪表关闭延时的非 ON 值,需要补一次同样 450 ms 的 CF 对照试验来区分。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/izakulus-w212-cluster-notes/README.md(引脚表、DBC 十进制 ID 对照、0x001 状态表、RX 判据与未决问题清单)

    免责声明

    本文所述内容为社区逆向工程产物,不代表梅赛德斯-奔驰或任何车辆制造商的官方数据。所有 ID、载荷与时序均来自上述公开仓库的说明文件,其效力仅限于作者自述的个人台架环境,未经真实车辆录制验证;不同年款、市场与配置可能存在差异。文中用于搜索 CAN ID 与字节组合的程序明确只适用于独立的台架环境,不得用于整车。请勿在安全相关用途中引用本文内容。

    更新记录

    • 2026-10-15 初稿

  • 2008 款 Impala 的 GM CAN 报文:50 个 ID 与 20 条 opendbc 对照

    结论:2008 款 Chevrolet Impala 的 HS-CAN 可以在 OBD-II 6/14 脚以 500 kbit/s、11 位 ID 直接读取,6 次采集共出现 50 个 ID,其中 20 个能在 opendbc 的 gm_global_a_powertrain.dbc 里找到同名条目。但这份档案的全部采集都在原地怠速下完成,轮速、车速、转向角三类公式只有定义没有实测;转速公式还必须先纠正字节偏移——原来的 b[0]、b[1] 取法是错的。

    采集条件先决定了这份档案能证明什么

    档案由 5 段约 15 秒的针对性采集(制动踏板、换挡、左转向灯、方向盘扫掠、ACC 累积基线)加 1 段约 90 秒的累积基线组成,车辆状态全程为静止、发动机怠速。这个条件直接限定了结论范围:凡是依赖车辆运动的信号,在这份档案里都只能给出公式,不能给出验证。

    仓库侧的量级有两个口径:随附的自定义 DBC 登记 22 条报文、71 条信号,数据 README 则将高置信度信号记为 17 条、自定义 DBC 记为 40 条以上。取哪个数取决于你要的是「报文定义条目」还是「实车核对过的信号」——前者包含大量照搬 opendbc 的定义,后者才是原地工况真正能背书的量。

    已确认的解码与一处必须先纠正的公式

    ID 源模块 信号 公式 单位
    0x0C9 PCM 发动机转速 uint16_BE(b[1], b[2]) / 4 RPM
    0x0C9 PCM 制动踏板标志 b[5] & 0x01 bool
    0x0F1 EBCM 制动压力 b[1](原始值,估计约 1.3 kPa/单位) kPa
    0x1F5 TCM PRNDL 挡位 b[3]:1=P 2=R 3=N 4=D 枚举
    0x191 PCM 喷油脉宽 uint16_BE(b[0], b[1]) * 4 µs
    0x4C1 PCM 冷却液温度 / 进气温度 b[2] - 40 / b[3] - 40 °C
    0x4D1 PCM 机油温度 b[5] - 40 °C
    0x3C1 / 0x3C9 BCM/TPMS 胎压(前左?/ 前右?) b[1] * 2 kPa
    0x514 / 0x4E1 PCM VIN 分段 1 / 2 ASCII b[0:8] 字符串
    0x1E1 ASCM 方向盘按键 ACC / LKA / 车距 / 驾驶模式 位域
    0x2C3 未知 3 组 uint16 未解,缓慢变化 —

    转速公式的纠正很关键:原始草图用 ((data[0] << 8) | data[1]) / 4 解码,实际 0x0C9 的 b[0] 高 4 位是一个 0–F 循环的滚动计数,不是转速数据。改为 b[1]、b[2] 后,怠速原始值落在 2624–3240,除以 4 得 656–810 RPM,与实车怠速吻合。同理,0x191 的喷油脉宽在怠速解出 0x06AA = 1706,乘 4 µs 得 6824 µs,与 GM 3.9L V6 进气道喷射的怠速脉宽量级一致。

    方向盘扫掠为什么没有解出转向角

    0x19D 曾被认为是转向或悬架模块,但方向盘扫掠采集里没有一个字节出现干净的单调扫掠:b[6] 变化最多(扫掠中出现 221 个不同值),可怠速时同样剧烈变化,因此不能判定为转向角。b[0] 的位 7–5 是一个四态滚动计数(0x20 → 0x60 → 0xA0 → 0xE0)。档案给出的最佳猜测是悬架高度或车身姿态,标注为未确认。

    opendbc 对照带来的四处纠正

    50 个 ID 中有 20 个与 opendbc 的 GM Global A 动力总成定义同名。但 2008 款 Impala 并不是 opendbc 的支持车型(该库面向 2016 年以后的 Volt、Malibu、Bolt、Silverado),因此 ID 一致不等于字节定义一致。对照后纠正了四处先前判断:

    ID 先前判断 opendbc 结论 对使用的影响
    0x4E1 标定 ID 第 1 段 VIN_Part2,VIN 后 8 字符 本车解出 81371876,不是标定号
    0x2F9 BCM 心跳 / 计数器 BRAKE_RELATED_2,用户制动压力为位偏移 47 处的 9 位值 b[0] 的自增是报文内部滚动计数,与 BCM 无关
    0x184 BCM 滚动计数 PSCMStatus,b[1] 为 RollingCounter 归属从车身模块改为转向助力控制模块
    0x1C3 疑似喷油相关 GasAndAcc,油门信号在 b[6] b[0:4] 的 uint16 对本年款含义另需确认
    0x140 未出现 opendbc 定义 BCMTurnSignals(0=None 1=Left 2=Right) 采集的 50 个 ID 里没有 0x140,转向灯状态不可得

    转向灯的缺失有两种解释:2008 款 BCM 用了不同 ID,或者该报文是事件驱动的、只在转向灯激活时才发。区分方法写在档案里:从采集开始前就持续拨住转向灯杆,看基线里是否出现新 ID,并专门盯 0x140。

    证据边界:三类公式没有实车验证

    信号 / 条目 当前状态 还缺什么验证
    0x0F1 制动压力 b[1] 静止 5–9,制动升至约 196;估计 1.3 kPa/单位 未与压力传感器基准对照,比例系数未确认
    0x1E5 转向角 按 opendbc 解 int16_BE(b[0],b[1]) * 0.0625,样本 0x8200 得 −2016°,超出量程 需要带已知转向位置的行驶采集;ID 与模块归属已确认,比例未确认
    0x348 / 0x34A 轮速 ×0.0311 km/h,四轮 + 方向位;采集全零 需要停车场低速蠕行采集确认比例与轮位分配
    0x0C1 / 0x0C5 轮速 110 Hz 成对冗余广播,疑似 uint16_BE(b[0],b[1]) 与 uint16_BE(b[4],b[5]) 单位与轮位均未确认
    0x3E9 车速 uint16_BE(b[0],b[1]) * 0.01 mph,采集全零 需要已知车速的行驶采集
    0x1C7 曲轴计数 b[2:4] 在 4 个相差约 16383 的值间循环 定为曲轴位置编码器或高分辨率点火计时,属推断
    自定义 DBC 一致性 AcceleratorPedalPos 起点在位 48,而报文 BO_ 417 只声明 3 字节 自相矛盾,严格解析器可能直接拒绝该 DBC
    采集与授权 原始采集文件不在受检快照中;仓库未附许可证 只能作离线研究,再分发前须先确认权利

    无解码进展的 ID

    ID 约 Hz 样例载荷 说明
    0x120 <1 00 DA 77 00 00 仅见 3 帧,疑似初始化
    0x134 / 0x138 10 / 1 00 00 10 / 00 00 00 00 0B 近乎常量,不在 opendbc 中
    0x17F / 0x1CD / 0x1F3 / 0x334 / 0x500 10 / 56 / 31 / 33 / 4 全零 五个 ID 载荷恒为零
    0x1F9 33 00 00 00 00 80 00 FF 00 近乎常量,不在 opendbc 中
    0x2C3 20 08 55 06 A0 07 4A 3 个 uint16,缓慢变化
    0x3F1 4 00 CB 56 18 FF FC b[1] 随时间缓慢递增
    0x4E9 1 C1 40 常量,疑似模式标志
    0x771 / 0x772 / 0x773 / 0x77F 1 7 字节,多为零 四个 UDS/KWP 诊断响应节点在总线上存在

    另有 0x3F9 已部分解开:b[1:5] 是一个 32 位值,相邻两次采集之间增量分别约 2280 万与 8080 万,与微秒级运行计时吻合,可作会话时间戳使用。

    档案自己列出的六项补采

    要把上面那些「有公式无验证」的条目推进到可用,档案给出了顺序明确清单:一次已知车速的行驶采集可同时验证 0x3E9、0x348、0x34A 与 0x0C1、0x0C5,并解锁 0x1A1 油门;急加速与急减速用来验证非怠速区间的 0x0C9 转速公式与 0x191 喷油脉宽,同时激发 0x1E9 的横向加速度与横摆率;方向盘全程缓慢扫掠用来确定 0x1E5 的比例系数;持续拨住转向灯杆用来区分 0x140 是事件驱动还是根本不存在;开关暖风或空调用来试探 0x0F9 与 0x4E9;最后一项是 OBD-II 1 脚——部分 2008 款 GM 车型在该脚上有低速 GMLAN,若可接入,能看到 HS-CAN 上看不到的车身功能。

    常见问题

    0x0C9 的发动机转速为什么不能用 b[0] 和 b[1] 计算?

    因为 0x0C9 的 b[0] 高 4 位是一个 0–F 循环的滚动计数,不属于转速数据。正确取法是「data[1] 左移 8 位后与 data[2] 合并,再除以 4」;用它解怠速数据得到 656–810 RPM,与实车怠速一致,而原取法会把滚动计数混进高位。

    转向灯状态为什么在这份档案里找不到?

    opendbc 把 BCMTurnSignals 定义在 0x140,但采集到的 50 个 ID 里没有 0x140,而同一 BCM 的 0x12A 与 0x1F1 都在,说明模块本身在总线上活动。可能是 2008 款用了不同 ID,也可能是该报文事件驱动、只在灯亮时才发,需要一次从采集前就持续拨住灯杆的专项采集来区分。

    50 个 ID 里有 20 个能对上 opendbc,剩下 30 个能直接照搬吗?

    不能。2008 款 Impala 不在 opendbc 的支持车型内,该库主要覆盖 2016 年以后的 GM Global A 车型,ID 同名不代表字节定义相同。档案里就记录了 0x1C3 的分歧:opendbc 认作 GasAndAcc、油门在 b[6],而本年款在 b[0:4] 出现了喷油量级的 uint16 对。

    0x0F1 的制动压力能用于量化分析吗?

    只能用于相对比较。b[1] 在静止时为 5–9、重踩时升到 186–196,趋势清楚,但 1.3 kPa/单位是由 186 单位约等于 242 kPa 反推的估计值,档案明确标注需要与压力传感器基准对照后才能确认,不能当作绝对压力。

    这份档案能用于行驶中的车速与轮速解析吗?

    不能直接用于。全部采集都在静止怠速下完成,0x348、0x34A、0x3E9 的载荷在所有采集里都是零,0x0C1、0x0C5 也接近零。公式来自 opendbc 定义与字节位置推断,必须先做一次已知车速的低速行驶采集才能确认比例系数与轮位分配。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/dwilson2547-impala-2008/can_data/analysis/gm/chevy_impala_2008.md(50 个 ID 的总表、已确认解码、opendbc 对照与无进展 ID)
    • 项目 01 —— public-can-dbc-datasets/additional/dwilson2547-impala-2008/SOURCE.md(DBC 的 22 报文 / 71 信号、DBC 一致性问题与授权边界)
    • 项目 01 —— public-can-dbc-datasets/additional/dwilson2547-impala-2008/can_data/README.md(采集目录结构、车型覆盖表与高置信度信号计数)

    免责声明

    本文所述解码均为社区逆向工程产物,不代表通用汽车或任何车辆制造商的官方数据。文中所有 ID、公式与数值均来自上述公开仓库的说明文件,未经独立实车验证;不同车型年款、市场与 ECU 版本可能存在差异。涉及安全相关用途时请仅作参考,并以实际测量与官方资料为准。

    更新记录

    • 2026-10-15 初稿

  • rusEFI 开源 ECU 的 CAN 接口:GPL-3.0 三条附加条款与取证路径

    结论:把 rusEFI 当作 CAN 报文约定的来源时,第一件事不是找 ID,而是读许可证附加条款:它在 GPL-3.0 之上另加三条用途限制(仅限非道路的陆上/水上车辆、不符合汽车环保法规、未批准用于载人航空)。本次受检快照只保留 README.md 与 license.txt 两个文件,不含任何 DBC 或 CAN ID 表,因此报文定义必须回到固件源码、simulator 与 rusEFI console 三条路径上取证。

    三条附加条款先划出使用边界

    GPL-3.0 本身处理的是「改了要不要开源」,而 rusEFI 在许可证正文之前单独加了三条附加条款,处理的是「能不能用在这个场景」。对任何打算把它的报文约定或移植代码接入产品的团队,这三条比许可证传染性更早构成否决条件。

    条款 原文含义 对接入方的影响
    rusEFI#1 面向非道路的陆上与水上车辆 道路车辆项目须自行评估合规责任,不能把「开源」当作上路依据
    rusEFI#2 不符合汽车环保法规 排放相关标定与后处理功能不能引用其实现作为合规证据
    rusEFI#3 未批准用于载人航空应用 航空场景直接排除,无需再做技术评估
    GPL-3.0 主文 传染性,修改后分发须同许可证开源 闭源产品宜以运行期数据/独立进程隔离,不要静态链接固件代码

    这三条的表述方式值得注意:它们写在许可证正文之前的「附加条款」段,而不是放在 README 的免责声明里。也就是说,它们是许可证的组成部分,不是项目方的使用建议。

    快照里有什么、没有什么

    受检快照只含两个文件:README.md 与 license.txt。README 是一份目录索引,描述了仓库顶层各子目录的用途,但源码、硬件文件与 DBC 都没有随快照保留。这意味着本文不能给出任何报文 ID、波特率或信号缩放——任何这类数字都不在受检范围内。

    仓库子目录 官方说明中的定位 快照是否含该文件 能拿来做什么
    firmware 面向 STM32 芯片的开源发动机控制单元源码,含实现概述 否 CAN 报文定义的最终出处,需回上游仓库核对
    simulator 固件的 win32 或 posix 版本,无需任何硬件即可探索 否 不接 ECU 硬件时验证解析逻辑的主要手段
    java_console rusEFI 自有的原生标定软件 否 观察运行中变量与报文交互的参考实现
    hardware 较旧 PCB 的 KiCAD 文件 否 确认 CAN 收发器与引脚连接
    unit_tests 固件各部分的单元测试,公开覆盖率报告 否 判断哪些报文处理路径有回归保护
    java_tools 杂项开发工具集 否 格式转换与辅助脚本
    misc 软件开发流程说明 否 了解上游的变更与评审节奏
    firmware/CHANGELOG.md 发布变更日志 否 确认报文约定在哪一版发生变更

    把这张表理解成取证顺序而不是功能列表:firmware 是定义的唯一权威来源,simulator 是不接硬件时的验证手段,java_console 是观察交互行为的参考实现。三者都缺失时,任何关于报文的说法都只能是推断。

    不接硬件的三步取证路径

    CAN 接口类项目的常见错误是先写解析器再找真值。rusEFI 的目录结构给出了一条成本更低的顺序:先用 simulator 的固件版本在没有 ECU 的情况下跑通解析,再用 console 观察变量与报文的对应关系,最后回固件源码确认定义与校验逻辑。

    步骤 使用对象 能得到的结论 前置条件
    1. 跑通解析 simulator 解析器能否处理固件实际发出的帧序列 需要按 README 完成构建,win32 与 posix 二选一
    2. 对齐语义 java_console 报文字段与标定变量名的对应关系 需要与 simulator 或真实硬件建立连接
    3. 确认定义 firmware 报文 ID、字节布局、缩放与校验的真实出处 需要能阅读 C/C++ 源码并定位到对应版本
    4. 锁定版本 firmware/CHANGELOG.md 报文约定在哪次发布发生变更 需要把结论固定到具体发布版本号

    四份外部资料的分工

    README 同时指向四类外部资源,取证的可靠性差别很大:Doxygen 生成的源码文档在 rusefi.com/docs/html,反映代码现状,适合定位具体实现;wiki 承担使用说明,适合理解配置项含义;论坛承担问答,适合确认某条约定是否已有结论但不构成证据;变更日志随固件发布更新,是判断「某个行为从哪一版开始变化」的唯一顺序依据。做报文取证时应当以 Doxygen 与变更日志为准,把论坛结论当作待验证的线索。

    构建环节有三个必须确认的契约点

    README 对构建只给了三条硬性提示,但每一条都会直接影响报文取证的可复现性:仓库使用了 submodule,克隆后必须执行 git submodule update --init,否则依赖缺失会表现为编译失败而非功能缺失;推荐 GCC 版本写在 firmware/gcc_version_check.c 里,版本不符可能只在高优化级别下暴露问题;构建产物从 build server 取,说明本地构建与官方二进制可能存在差异,比对报文行为时须注明用的是哪一个。

    契约点 要求 跳过会怎样
    子模块 克隆后执行 git submodule update --init 依赖缺失,编译在早期阶段失败
    编译器版本 以 firmware/gcc_version_check.c 为准 可能构建成功但运行行为与官方二进制不一致
    产物来源 官方二进制来自 build server,需注明版本 不同来源的报文行为差异被误判为协议问题
    文档口径 Doxygen 文档与 wiki 分开维护 只看一处会漏掉近期的接口变更

    常见问题

    这份快照里能直接拿到 rusEFI 的 CAN 报文 ID 吗?

    不能。受检快照只有 README.md 与 license.txt 两个文件,README 仅描述顶层目录用途,源码、硬件文件与 DBC 均未随快照保留。报文 ID、波特率与信号缩放必须回到上游仓库的 firmware 目录,并配合 simulator 与 java_console 交叉确认。

    GPL-3.0 的三条附加条款是不是意味着完全不能上车?

    不等于禁止,但它把合规责任明确留给了使用方。三条条款分别声明:项目面向非道路的陆上与水上车辆、不符合汽车环保法规、未批准用于载人航空应用。道路车辆项目不能把「开源」本身当作上路或排放合规的依据,需要自行完成评估与认证。

    没有 ECU 硬件能不能先验证报文解析逻辑?

    可以。README 列出 simulator 目录提供固件的 win32 或 posix 版本,允许在没有任何硬件的情况下探索。配合 unit_tests 目录公开的覆盖率报告,可以判断哪些报文处理路径已有回归保护。但前提是先把构建跑通,包括子模块初始化与 GCC 版本对齐。

    克隆下来就能直接编译吗?

    不能只做一次克隆。README 明确说明仓库使用 submodule,必须在克隆后执行 git submodule update –init;同时推荐 GCC 版本写在 firmware/gcc_version_check.c 中,需按该文件核对。若只需二进制,官方构建产物从 build server 获取。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/rusefi-can/license.txt(GPL-3.0 主文与 rusEFI#1 至 rusEFI#3 三条附加条款)
    • 项目 01 —— public-can-dbc-datasets/additional/rusefi-can/README.md(顶层目录用途、子模块构建要求、GCC 版本检查与 build server 产物说明)

    免责声明

    本文仅记录受检快照中 README 与许可证文件所载内容,未包含任何未经材料支持的报文 ID、波特率或信号定义。rusEFI 为社区开源项目,文中引用的目录用途与许可证条款以材料原文为准;快照未包含源码与许可证以外的第三方组件信息。涉及道路车辆、排放合规与安全相关用途时,请以官方资料与实际测量为准,并自行完成合规评估。

    更新记录

    • 2026-10-15 初稿

  • 沃尔沃 C30 嗅探记录:35 个 29 位 ID 与 462 条 VIDA 请求

    结论:2011 款沃尔沃 C30 T5 是少数可以直接从诊断口同时够到两条总线的车:它的高速总线 500 kbit/s、低速总线 125 kbit/s,全部使用 29 位扩展 ID、每帧固定 8 字节,且诊断口与整车之间不存在网关,两条总线都被引到 OBD 连接器上。配套研究留下两份清单——35 个广播 ID 的嗅探记录(24 条带功能注释)与 462 条 VIDA 请求条目,其中 147 个是唯一的 ECM 故障码。真正需要警惕的是请求表里混着执行器动作、ECU 复位、擦除与全总线静默这几类命令,它们和读数据命令只有第三个字节的差别。

    双总线拓扑:为什么这台车的嗅探门槛很低

    这台车有两条 CAN 网络。高速总线挂 ECU、转向模块、制动及其他模块,低速总线挂收音机、车门模块、仪表组合及附属电器,中央电子模块 CEM 在两者之间做网关。关键在于:诊断口与整车其余部分之间没有额外网关,两条总线都被引到了 OBD 连接器上,因此不需要任何中继设备就能同时观察两侧流量。

    代价是物理层和寻址方式都比常见乘用车更特殊:29 位扩展 ID、每帧一律 8 字节、两条总线速率差四倍。作者也说明,同年代更早的车型需要先通过 K 线激活诊断继电器才能从诊断口访问 CAN,这台车不需要,因此那份资料对老车型不适用。兼容性方面的表述很克制——其他采用同款博世 ME9 实现的车型大概率无需改动即可工作,但有报告称广播 ID 会随车辆变化,需要自行调整。

    总线 速率 主要节点 接入方式
    高速总线 500 kbit/s ECU、转向模块、制动模块 诊断口直连,29 位扩展 ID
    低速总线 125 kbit/s 收音机、车门模块、仪表组合 诊断口直连,29 位扩展 ID
    网关 — 中央电子模块 CEM 诊断口与整车之间无额外网关
    帧长度 — 所有 ECU 的所有帧 一律 8 字节
    前置条件 — 更老车型 需经 K 线激活诊断继电器

    VIDA 请求帧:与 UDS 的差别只在开头两个字节

    VIDA 是与 UDS 类似的诊断协议,但帧结构不同:第一个字节是数据长度码,第二个字节才是 ECU 地址。这一点决定了它不能直接用标准 UDS 工具发。以读取增压压力为例,请求帧 ID 为 0x000FFFFE,数据为 CD 7A A6 12 9D 01 00 00:首字节 CD 等于 C8 加上后续有效字节数,7A 是发动机 ECU 的地址,A6 是按标识符读当前数据,12 9D 是增压压力参数,01 大概是「只回送一次」,其余补零凑满 8 字节。

    响应帧 ID 为 0x00400021,数据 CD 7A E6 12 9D 95 00 00:E6 是对 A6 的正响应,12 9D 回显所请求的参数,95 才是返回值。也就是说,解析时要先按首字节裁出有效长度,再按「地址—命令—参数—值」的顺序取值,不能假定整帧都是有效载荷。

    字节位置 请求帧示例 响应帧示例 含义
    帧 ID 0x000FFFFE 0x00400021 请求与响应使用不同 CAN 地址
    字节 0 CD CD C8 加后续有效字节数
    字节 1 7A 7A ECU 地址,此处为发动机 ECU
    字节 2 A6 E6 按标识符读当前数据及其正响应
    字节 3–4 12 9D 12 9D 参数标识,此处为增压压力
    字节 5 01 95 请求侧为回送次数,响应侧为返回值
    字节 6–7 00 00 00 00 补零至 8 字节

    命令字节全集与风险分档

    第三个字节决定动作类型,资料里列出的取值及其含义如下。需要特别注意的是其中几类并非只读:跳转执行、运行代码段、启动引导、擦除、复位,以及以 FF 为 ECU 标识的全局命令「全总线静默」与「全总线复位」。这些命令与读数据命令在帧结构层面完全相同,只差一个字节的值,因此任何把请求表整体接入自动化脚本的做法都必须先做白名单过滤。

    命令字节 含义 风险档
    A6 按标识符读当前数据 只读
    AE 发送数据(资料中主要用于读故障码) 只读
    B9 读 ECU 硬件/软件件号与序列号、防盗通信计数 只读
    A3 防盗安全访问:发送或重锁防盗 PIN 写入
    A8 设置引导段结束 写入
    AF 清除全部已存储的 2 字节故障码 写入
    B1 执行器动作,如逐缸喷油器开启 动作
    B2 启停泄漏快检 动作
    B4 结束取数与校验和 写入
    B8 写防盗 PIN 与安全码 写入
    9C / A0 / C0 跳转地址 / 运行跳转点代码段 / 启动引导 高危
    C8 / F8 复位 ECU / 擦除 高危
    86 / C8(ECU 为 FF) 全总线静默 / 全总线复位 高危

    462 条请求条目:规模与命令分布

    请求清单共 507 行,其中 462 行是带分号分隔的有效条目,按命令字节分布为:A6 读数据 236 条、AE 读故障码 152 条、B1 执行器动作 59 条,其余十余条分散在 B9、A3、B2、B8、AF 上。也就是说,这张表约八成是只读请求,但剩下的两成里有 59 条会直接驱动执行器。

    每条只读请求附带换算式,这是它比起单纯的参数列表更有价值的地方。换算形态有三类:线性乘系数、含偏移的线性式(如温度统一按乘 0.75 减 48 得摄氏度)、以及按位掩比较(用于开关量与状态位)。同一参数在不同条目里出现不同换算式的情况也存在,例如喷油时间在两处分别给乘 0.002666 与除 375,使用时应以实车回归为准。

    参数 请求数据 换算式 单位
    增压压力 A6 12 9D 01 乘 10 hPa
    增压压力传感器电压 A6 12 9C 01 乘 5.0/1024 V
    发动机转速 A6 10 1D 01 乘 40 rpm
    车速 A6 11 40 01 乘 1.25 km/h
    冷却液温度 A6 10 D8 01 乘 0.75 减 48 摄氏度
    进气温度 A6 10 CE 01 乘 0.75 减 48 摄氏度
    点火提前角 A6 10 36 01 乘 191.25/255 BTDC
    空气质量流量 A6 10 29 01 乘 4 kg/h
    蓄电池电压 A6 10 0A 01 乘 0.07 V
    油门踏板(模拟输入) A6 10 04 01 乘 100/65535 %

    故障码清单:147 个唯一码与它的取法

    读故障码统一使用 AE 11,即按 2 字节故障码请求,清单里共出现 147 个唯一的 ECM 前缀码,覆盖增压压力传感器、点火线圈逐缸信号、喷油器逐缸、节气门单元内部故障、控制模块内部故障、前后氧传感器、失火逐缸与催化器损伤、涡轮控制阀、燃油泵继电器、系统继电器、5 V 供电、配置故障等。清单中还有一条写作 ECM-XXXX,标注为「当前控制模块版本下的未知故障码」,这是解读时的一个重要提示:同一数值在不同软件版本上可能对应不同含义。

    清码使用 AF 11,描述为「清除全部已存储的 2 字节故障码」。这是一次性的 bus-write 动作,在只读采集脚本里不应出现。与此相对,B9 F0、B9 F5、B9 F8 分别读取 ECU 硬件件号、软件件号与硬件序列号,是确认所连车辆软件版本最安全的方式,排在读故障码之前更合理。

    35 个广播 ID 的嗅探记录

    广播侧的记录共 35 条,字段为 ID、数据长度码、8 字节数据、周期、观测计数与注释;其中 24 条带功能注释,11 条留空。周期列取值从 30 到 1088,观测计数从 8029 到 184057。注释里最有价值的是「CRITICAL FOR CLUSTER」这一类标记——它指出哪些帧是仪表正常工作所依赖的,一旦在总线上缺失或篡改,仪表会出现可见异常;这类帧在实验里应只观察、不注入。

    ID 周期 观测计数 注释要点
    021204B8 30 184057 转向灯
    03C3F7FC 31 170711 点火状态
    09C050B8 52 91376 仪表与里程计数;字节 1 的第二个半字节为亮度,字节 4 与 5 为转速,标记「仪表关键」
    0EE0500A 101 50799 气囊灯,标记「仪表关键」
    1093F7FC 248 8029 标记「仪表关键」,无进一步说明
    1760E008 153 29186 仪表车速与告警灯
    1AD10068 600 12205 字节 1 为油量;字节 2 在仪表开时为 0x04、关时为 0x07
    19F010FC 201 25299 巡航控制按键
    16124008 97 38201 胎压告警灯
    16801028 233 32269 ABS 与制动失效灯

    这份记录也说明了作者的实现策略:优先从广播帧取数,因为开销和总线占用都低;只有在广播里根本不出现的量(增压压力就是典型)才改用请求。仪表亮度、点火状态、方向盘按键都在后台循环里持续更新全局变量,供显示循环使用——代码采用一种伪多任务结构,接收循环在其他循环不运行时始终在跑,因此广播变化不会漏掉。此外还记录了一个交互细节:长按巡航取消键超过 2 秒切换显示页面。

    硬件侧也有参考价值:控制器用 Arduino Due 配合其双 CAN 接口的库,显示屏是一块 2.2 英寸圆形串口屏,两者都挂在诊断口上而不经过任何改装线束。显示项最终定为增压压力、冷却液温度、进气温度与点火提前角四个,其中三项要靠请求才拿得到。仪表指针还做了模拟化处理:数值跳变超过 1 时不允许瞬时跨越,必须逐级走完中间值,以避免数字仪表的跳变感。

    常见问题

    这台车的诊断口能直接读到两条总线吗?

    能。它的高速总线 500 kbit/s、低速总线 125 kbit/s,诊断口与整车之间不存在网关,两条总线都被引到 OBD 连接器上。但要注意更老的同品牌车型需要先通过 K 线激活诊断继电器才能访问 CAN,这份资料不适用。

    VIDA 协议能不能用标准 UDS 工具发?

    不能。它与 UDS 的差别在帧开头:第一个字节是数据长度码,第二个字节才是 ECU 地址,而 UDS 的寻址方式不同。解析响应时也要先按首字节裁出有效长度,再按地址、命令、参数、返回值的顺序取值。

    增压压力为什么必须靠请求而不是广播?

    因为这类量在广播帧里根本不出现。该研究优先使用广播帧取数以降低总线开销,只有广播中不存在的数据才走请求路径,增压压力就是其中之一,对应请求数据为 A6 12 9D 01、换算为乘 10 得百帕。

    请求表里有哪些命令不能随便发?

    约两成条目不是只读。59 条 B1 会直接驱动执行器(如逐缸喷油器开启),AF 清除全部故障码,A3 与 B8 涉及防盗 PIN,9C、A0、C0 涉及跳转与引导,C8、F8 是复位与擦除,而以 FF 为地址的 86 与 C8 会作用于整条总线。自动化脚本应先做命令白名单过滤。

    这些广播 ID 能套用到其他车吗?

    不能默认可以。作者明确表示与其他车辆的兼容性未知,采用同款博世 ME9 实现的车型大概率无需改动,但有报告称广播 ID 会随车辆变化。此外清单里存在 ECM-XXXX 这类条目,标注为当前控制模块版本下的未知故障码,说明同一数值在不同软件版本上含义可能不同。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/alfaa123-volvo-c30-research/README.md(车辆年份与型号、双总线速率、29 位扩展 ID、硬件构成与兼容性说明)
    • 项目 01 —— public-can-dbc-datasets/additional/alfaa123-volvo-c30-research/Codes.txt(VIDA 请求帧结构、命令字节全集与 462 条带换算式的请求条目)
    • 项目 01 —— public-can-dbc-datasets/additional/alfaa123-volvo-c30-research/Sniffing/RX List.txt(35 个广播 ID 的数据、周期、观测计数与功能注释)

    免责声明

    本文所述的总线参数、请求帧结构与故障码清单均为社区逆向工程的研究笔记,不代表车辆制造商的官方数据,文中数字均来自上述公开仓库的说明文件,未经独立实车验证。该仓库快照中未发现任何许可证,仅可作私有离线研究副本,再分发或集成前须先行确认权利。文中列出的执行器动作、故障码清除、ECU 复位与擦除、全总线静默等命令不得在未知车辆或公共道路上使用;诊断请求与主动 CAN 流量不得假定对另一辆车安全。涉及安全相关用途时请以官方资料与实际测量为准。

    更新记录

    • 2026-10-15 初稿

  • OSCC 开源车辆控制:归一化命令、200 ms 保活与三层安全边界

    结论:OSCC 的价值在于它选了一条最难但最可辩护的路线:不欺骗 CAN 报文、不改原厂安全用例、不破解 ADAS 功能,而是把控制命令注入到转向盘扭矩传感器、油门位置传感器与制动位置传感器这三个物理接口上。代价是必须自己补上原厂本来承担的安全机制——文档里能明确数出来的有三层:enable/disable 门控、每 200 毫秒必须调用一次的看门狗、以及默认开启的操作者超控。任何把这三层当可选项的实现,都偏离了它的设计前提。

    接口定位:低层注入而不是报文欺骗

    这套系统由软件 API、固件与硬件设计三部分构成,通过车载通信网络与控制系统的模块化接口实现计算机控制。它的能力边界可以拆成三件事:向车辆发送控制命令、从车辆的 OBD-II CAN 网络读取控制报文、转发当前车辆控制状态报告(如转向角与轮速)。控制命令并不直接操纵执行器,而是作用于部件 ECU 的传感器输入端——转向盘扭矩传感器、油门位置传感器、制动位置传感器。汽油版起亚 Soul 不具备线控制动能力,因此额外加装了一套辅助执行器来实现制动。

    这种低层接口的意义在于完整保留原厂安全用例:原车的失效检测、冗余与机械链路都还在,注入的只是一个「驾驶员意图」。这与在总线上伪造一帧转向命令有本质区别——后者绕过了原厂所有校验,前者仍然在原厂设计的信号链里。目前官方支持的车型是 2014 年及以后的起亚 Soul(汽油版与纯电版),但 API 与固件在设计时就为新增车型留出结构:按既有车型头文件的格式新增一个头,并补充一个构建选项即可。

    版本矩阵:四件事必须同时对齐

    需要跟踪的版本有四件:传感器接口板(油门与转向,版本印在板正面)、车辆控制模块(纯电版制动)、执行器控制板(汽油版制动),以及共用同一版本号的 API 与固件。文档对版本更新给的评价很重——每次有新版本都必须更新,以确保没有使用带有已知安全问题的版本。这不是礼貌性提醒,因为板卡版本与固件版本的配对关系会直接影响启动自检能否通过。

    板卡 板卡版本 要求的固件版本 说明
    传感器接口板 大于等于 1.0.0 大于等于 1.0.0 承担油门与转向
    车辆控制模块 0.1.0 大于等于 1.1.0 纯电版制动
    执行器控制板 大于等于 1.2.0 大于等于 1.0.0 汽油版制动
    执行器控制板 小于 1.2.0 大于等于 1.0.1 需额外关闭启动自检

    最后一行是唯一需要额外操作的组合:较新的执行器控制板利用了新的引脚做启动阶段的附加安全检查,旧板没有这些引脚,因此构建时要显式关闭制动启动测试,否则自检会失败。这是硬件演进与安全检查相互耦合的直接例子。

    命令契约:归一化取值范围与 200 毫秒保活

    API 只暴露三个发布函数,参数全部归一化,与具体车辆的电压标定解耦:制动与油门位置取 0.0 到 1.0,转向扭矩取负 1.0 到正 1.0,其中负为逆时针、正为顺时针。API 负责把归一化值换算成需要注入的欺骗电压,并内置安全检查以确保不会发出超出车辆预期范围的电压。这个换算层是安全边界的一部分——应用层永远碰不到原始电压。

    保活要求是这套接口里最容易被忽略的硬约束:三个发布函数每一个都必须至少每 200 毫秒被调用一次,否则模块会判定与上位机失去通信并自行禁用。它把「上位机死机」和「主动松开控制」统一收敛成同一种失效结果,这正是看门狗该有的行为。反过来说,一个只在上位机有输出时才发命令的控制循环,一旦进入长时间稳定状态就会自己把系统关掉。

    接口 方向与取值 约束
    oscc_open / oscc_close 通道编号 建立与终止到固件的 CAN 通道连接
    oscc_enable / oscc_disable 无参数 禁用时仍可接收报告,但无法发送命令
    publish_brake_position 0.0 至 1.0 每 200 毫秒至少调用一次
    publish_throttle_position 0.0 至 1.0 每 200 毫秒至少调用一次
    publish_steering_torque 负 1.0 至正 1.0 负为逆时针、正为顺时针,同样需 200 毫秒保活
    subscribe_to_brake_reports 等 回调函数 制动、转向、油门、故障四类报告各自独立订阅
    subscribe_to_obd_messages 回调函数 转发非本系统的 CAN 帧,可按 ID 自行解析

    还有一条实现层面的注意事项:API 会捕获 CAN 帧到达时产生的信号并为其安装处理函数,把有效报文转发给应用。因此应用中对中断敏感的代码段,应在该段执行期间临时阻塞该信号、结束后再解除,否则回调可能在临界区中被触发。

    三层安全边界

    把这些约束放在一起看,OSCC 的安全设计是分层的,任何一层单独失效都不会立刻导致失控。

    层级 机制 失效时的行为
    应用层 oscc_enable 与 oscc_disable 门控 未使能时命令发不出去,但报告照常接收
    通信层 三个发布函数各需 200 毫秒内再次调用 超时即判定通信丢失,模块自行禁用
    信号层 API 内置电压范围安全检查 换算后的欺骗电压被限制在车辆预期范围内
    操作层 操作者超控检测,默认全部开启 驾驶员施加扭矩即退出,转向灵敏度可调
    硬件层 启动自检(新板用新引脚做附加检查) 自检不通过则不上线
    流程层 强制跟随版本更新 避免停留在带已知安全问题的版本

    转向超控为什么默认开启且不建议关闭

    所有模块的操作者超控检测默认开启,但文档对转向给出了额外警告:系统激活时试图抓住转向盘可能导致严重伤害,因此推荐的转向超控方式是制动踏板或急停按钮,而不是去扳方向盘。若确实需要关闭,可在构建时传入关闭标志,此时灵敏度由对应车型头文件中的扭矩差阈值控制。

    这个阈值是一个典型的双向权衡:调低会让模块对超控更敏感,但在转向齿条机械极限或快速反复变向等高扭矩区域产生误判;调高则误判更少,但人工接管转向变得更困难。文档没有给出默认值之外的推荐值,因为最优解取决于具体的转向系统与应用场景,这正是需要在实车上标定的参数。

    构建、刷写与测试命令

    固件用 CMake 构建而非 Arduino IDE,目的是绕开 IDE 的限制并支持命令行刷写。前置条件是 Arduino Core 1.8.5 及以上与 CMake 2.8 及以上。构建时通过车型标志选择目标:汽油版 Soul、纯电版 Soul 与 Niro 各有对应标志。生成的构建目标可以整体构建,也可以按模块单独构建,四个模块分别是制动、CAN 网关、转向与油门。

    环节 命令或标志 说明
    选择车型 构建时传入车型标志 汽油版 Soul、纯电版 Soul、Niro 三选一
    关闭转向超控 追加关闭超控标志 默认开启,不建议关闭
    关闭制动启动测试 追加关闭启动测试标志 仅旧版执行器控制板需要
    发行构建 指定构建类型为 Release 关闭调试符号并开启优化
    单模块构建 制动 / 网关 / 转向 / 油门四个目标 可只构建所需模块
    刷写 单模块上传目标与全量上传目标 按字母顺序连接模块可获得稳定端口分配
    单元测试 打开测试标志后运行单元测试目标 依赖 Cucumber 2.0.0 与 Boost
    属性测试 打开测试标志后运行属性测试目标 依赖 Rust、Cargo 与 libclang

    测试分两类且覆盖角度不同。单元测试以行为描述的方式验证报文处理,例如油门模块的「接收命令」用例会给出传感器读数与两路 DAC 输出值的对照表,四个样例点分别是 0 对应 0、256 对应 1024、512 对应 2048、1024 对应 4096。属性测试则验证控制器库的不变式,一组运行包含积分项、微分项、比例项、反转输入、相同输入产生相同控制、以及清零共七项。两类测试都有分模块的独立运行入口,也有一次性运行全部测试的便捷入口。

    许可证分工:硬件与软件不是同一种授权

    这一点常被忽略但对集成决策影响很大:硬件源材料——原理图、电路板布局、接线图、数据手册、物理安装文档、三维模型等——采用 CC BY-SA 4.0 授权;固件与软件源则采用 MIT 授权,除非第三方依赖另有声明。也就是说,照着板卡设计做改动后的再分发义务,与修改代码后的义务并不相同。此外文档整体声明按现状分发、不提供任何担保。

    组成部分 许可证 主要义务
    硬件源材料(原理图、布局、接线图、安装文档、三维模型) CC BY-SA 4.0 署名并以相同方式共享衍生作品
    固件与软件源(源码、头文件、文档、构建脚本) MIT 保留版权与许可声明
    第三方依赖 以各自声明为准 需逐项核对

    项目还提供商用的整车控制接口方案作为交钥匙选项,覆盖纯电版 Soul 与 Niro 混动,包含集成控制模块、车规级线束与急停开关。对研究者而言,开源版本与商业版本的区别在于支持范围与工程化程度,接口契约本身是一致的。

    常见问题

    OSCC 是在 CAN 总线上伪造报文吗?

    不是。它把控制命令作用于部件 ECU 的传感器输入端——转向盘扭矩传感器、油门位置传感器与制动位置传感器,属于低层接口,因此能在不改动原厂安全用例、不欺骗 CAN 报文、不破解 ADAS 功能的前提下实现全量程控制。纯电版以外的汽油车因不具备线控制动能力,需额外加装辅助执行器。

    为什么控制命令必须每 200 毫秒发一次?

    这是模块侧判定上位机是否存活的看门狗:三个发布函数中任意一个超过 200 毫秒未被调用,模块就认定与上位机失去通信并自行禁用。它把上位机死机与停止控制统一成同一结果。因此控制循环不能只在数值变化时才发命令,长时间稳态下也必须持续调用。

    可以关闭转向超控吗?

    可以在构建时传入相应标志关闭,但不建议。文档明确警告系统激活时抓握转向盘可能造成严重伤害,推荐的转向超控方式是制动踏板或急停按钮。若保留开启,灵敏度由车型头文件中的扭矩差阈值控制:调低会增加高扭矩区域的误判,调高会让人工接管更困难。

    板卡版本与固件版本不匹配会怎样?

    会直接影响启动自检。较新的执行器控制板用新引脚做附加的启动安全检查,旧板没有这些引脚,必须用关闭制动启动测试的构建标志处理。其余组合按官方配对表选择固件版本即可,文档同时强调每次发布新版本都应及时更新,以避开已知安全问题。

    硬件设计和软件代码的授权一样吗?

    不一样。原理图、电路板布局、接线图、数据手册、物理安装文档与三维模型等硬件源材料采用 CC BY-SA 4.0,衍生作品需署名并以相同方式共享;固件与软件源采用 MIT,只需保留版权与许可声明;第三方依赖以各自声明为准。集成前应按组成部分分别核对义务。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/polysync-oscc/README.md(接口定位、版本矩阵、API 契约与 200 ms 保活、构建与测试命令、许可证分工)
    • 项目 01 —— public-can-dbc-datasets/additional/polysync-oscc/LICENSE.md(硬件源材料的 CC BY-SA 4.0 条款与固件软件的 MIT 条款全文,含免责与责任限制)

    免责声明

    本文所述内容来自公开开源项目的说明文件,不代表车辆制造商的官方数据,文中数字均摘自上述文件,未经独立实车验证。该项目按现状分发、不提供任何担保:硬件源材料(原理图、电路板布局、接线图、数据手册、物理安装文档与三维模型)采用 CC BY-SA 4.0,衍生作品须署名并以相同方式共享;固件与软件源采用 MIT,须保留版权与许可声明;第三方依赖以各自声明为准,集成前应逐项核对。对车辆进行任何控制改装都涉及人身与财产安全,本文仅作技术资料梳理,不得作为上路或载人测试的依据;实际操作须在封闭场地、由具备资质的人员在急停开关与完善的失效处理机制下进行,并以官方资料与实际测量为准。

    更新记录

    • 2026-10-15 初稿

  • SAM 电动车 CAN 笔记:37 报文、161 信号与一处字节序纠错

    结论: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%,后者在零阶保持下会显著放大散点。

    回放轨迹到真实总线上有什么前置条件?

    需要车辆网络工具箱与适配器驱动,且连接并不等于发送:必须单独勾选武装开关才会真正发帧。未检测到适配器时会退回到虚拟通道。官方说明也提示,除驱动层外其余代码路径已在虚拟回环上验证,正式依赖前建议再做一次真实硬件冒烟测试。

    延伸阅读

    参考资料

    • 项目 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 初稿

  • Talaria 电动越野车 CAN 信号:250 kbit/s 下 15 个 ID 与四处证伪

    结论:Talaria 电动越野车的车载 CAN 是一条 250 kbit/s、11 位标准 ID、15 个报文 ID、约 92 帧每秒的总线,用一颗 3.3 V 收发器挂在 ESP32-S3 的 TWAI 控制器上即可只读取数。真正有复用价值的不是那张 14 项信号表,而是表里被明确证伪的四处:0x103[0] 不是电量、0x202[6:8] 不是里程、0x490 不是温度也不是单字段、节流需求偏移随固件而变。把这几条排除后再取数,才不会把「看起来像」当成「就是」。

    总线前提与接入方式

    这条总线在电机控制器处即可挂到 CAN_H 与 CAN_L,硬件侧只需要一个 3.3 V 的 SN65HVD230 收发器:发送脚接 GPIO7、接收脚接 GPIO8,直连而非交叉——这一点与同一块板上的 GPS 串口不同,后者是交叉的。CAN 外设用的是 ESP32-S3 自带的 TWAI 控制器,外部模块只承担物理层。

    两个电气细节必须在上电前处理。第一,模块板上那个标着 121 的 120 欧终端电阻要拆掉:车辆总线两端已经各自终端,跨 CAN_H/CAN_L 量到的是 60 欧,再并一个电阻会掉到 40 欧,波形裕量直接被吃掉。第二,一旦 CAN 双线接入,设备的地就通过降压模块的负极与车辆共地,此时再插 USB 会把车辆电池负极接到保护地,同时 USB 的 5 V 与降压模块的 5 V 在 VUSB 上相撞;拔掉车端连接器可以同时隔离这两个风险,遥测数据改走无线链路读取。

    总线默认是只读取模式:收发器从不驱动总线,甚至不应答,因此即便波特率猜错也不会扰动车辆。这一点是整套方案能从「只读」安全扩展到「可写」的前提。

    参数 取值 备注
    波特率 250 kbit/s 扫描子命令会遍历波特率与标准/扩展 ID 组合
    ID 类型 11 位标准 ID 与整车厂常见的 29 位扩展 ID 不同
    总线报文 ID 数 15 固件当前只解析其中 8 个
    帧率 约 92 帧/秒 全总线合计
    终端电阻 60 欧(熄火状态下测量) 读到 120 欧说明只挂到了单端
    接地 无需单独地线 通过降压模块负极已与车辆共地
    DBC 规模 9 条报文、26 条信号行 每条信号的验证过程写在 CM_ 注释里

    已解码信号与字节定义

    下面这张表是这份研究的核心产出。所有偏移都按小端处理,物理量的缩放因子在最后一列。值得注意的是,电芯最高/最低电压与序号共用同一帧的不同字节组,序号分别落在字节 4 与字节 5。

    信号 帧 ID 字节与位 缩放
    车速 0x303 字节 0–1,小端 0.1 km/h
    电机转速 0x203 字节 0–1,小端 1 rpm
    功率 0x203 字节 2–3,小端 1 W
    电流 0x302 字节 4–5,小端 0.1 A
    电池包电压 0x101 字节 0–1,小端 0.1 V
    电量百分比 0x401 字节 0 1 %
    最高电芯电压与序号 0x201 字节 0–1 小端,序号在字节 4 1 mV
    最低电芯电压与序号 0x201 字节 2–3 小端,序号在字节 5 1 mV
    边撑 0x202 字节 0 第 7 位 1 为放下
    骑行模式 0x202 字节 0 第 5:4 位 1 节能、2 运动
    动能回收等级 0x490 字节 0 第 2:0 位 1 至 4
    骑行模式(仪表指令) 0x490 字节 0 第 5:3 位 1 节能、2 运动
    里程 0x402 字节 2–3,小端 1 km
    转把需求 0x202 字节 3–4,小端 单位未确认

    交叉验证给了两个可信锚点:车速与转速在两次独立骑行中保持 5.887 的固定比值,相关系数 0.999,对车速积分也能还原出合理的骑行距离;最高与最低电芯电压的平均值乘以 16 能复现电池包电压到 0.02 V 以内,这坐实了 16 串的电池包结构。这两条把「解析对了」从感觉变成了可检验的判据。

    遥测包里的 CAN 块与门控位

    解码后的车辆数据占遥测包第 50 至 69 字节,配套一个状态字节:第 0 位表示总线存活,第 1 位是边撑,第 3:2 位是骑行模式,第 6:4 位是回收等级。规则只有一条但必须遵守——超过 2 秒没有收到任何帧时,整个字节块会被清零、存活位同时拉低,因此判空要门控在存活位上,而不能相信「速度为零」。否则一辆停着的车和一根拔掉的线在数据上完全一样。里程字段在第 88 字节,取的就是 0x402[2:4],读到 0 表示还没见过该帧。

    四处已被证伪的字段

    这份研究最值得照搬的不是结论,而是它把「曾经以为」逐条推翻并留下判据的过程。四条错误里前两条是典型的形状误导,第三条是位域切分错误,第四条是跨设备外推错误。

    被误认的字段 为什么看起来像 证伪判据 正确取法
    0x103[0] 当电量 数值形态像百分比 实际电量在别处变化时它恒为 100,几乎可以确定是健康度 取 0x401 字节 0
    0x202[6:8] 当里程 单调递增,形态极像里程计 与车速的相关系数为负 0.0005,两次骑行的每公里计数相差 34% 取 0x402[2:4],整公里
    0x490[0] 当温度或单字段 整字节与模式的相关系数 0.99,看起来整字节都是模式 第 5:3 位是模式、第 2:0 位是回收等级;节能模式下第 3 位被置起,回收 1 会读成 0x09 而非 0x01 掩 3 位而不是 4 位
    转把需求偏移固定 同车型同帧 ID,默认偏移可复用 本车在 0x202[3:5],参考日志里那辆车在 0x202[2:4] 且根本不跟随转把 换车必须重新验证偏移

    里程的发现过程有一条通用经验值得单独记:这份研究曾长期写着「总线上没有找到里程计」,而这个结论是从固件捕获的 8 个帧里得出的,0x402 恰恰属于没人解码的那 7 个。后来是照着车辆仪表自己显示的 400 km 去全总线捕获里找这个数,0x402[2:4] 正好读出 400。由于总线上存在 1200 这类整常数(同时出现在 0x101[4:6] 与 0x302[6:8]),单次对上整数只是提示而非证明,因此它被明确标注为待验证——需要一次实际骑行看它自增。

    从只读到可控:0x490 是命令不是回声

    0x490 长期被当作控制器的回声,直到一次按键对比实验才被推翻:连续五次按键里,0x490[0] 每次都先动,0x202 在 20 至 27 毫秒之后才跟着变,同时带上新的模式位与新的需求下限(运动 1100、节能 750)。在仪表持续以 5 Hz 发运动模式的同时注入节能,控制器在整个注入期间被钉在需求 750 上。结论是仪表与控制器是两个不同节点,控制器服从总线上最近一次 0x490,而且从不锁存。

    这就决定了「覆盖」不能以命令的方式实现,只能以持续争论的方式实现:仪表下一帧在 200 毫秒后就会把单次发送的内容推翻,所以只要覆盖还生效,就必须应答仪表发出的每一个 0x490。实测差距很明显——自由运行在 20 Hz 注入会输掉 24% 的帧,而收到即回则在控制器自己的 297 帧里守住了 297 帧。决定成败的是延迟,不是发送频率。

    机制 行为 后果
    锁存 控制器不锁存,服从最近一帧 覆盖必须持续应答,发一次无效
    注入方式 收到即回,守住 297/297;自由运行 20 Hz 丢失 24% 延迟是机制,频率不是
    释放路径 无线断连、CAN 超时、车把按键任一触发 100 毫秒内回到仪表控制
    可验证性 模式可见,回收等级无法验证 回收不带动总线上任何其他量,功率与电流都是无符号的
    仪表显示 仪表不监听总线 覆盖期间仪表显示与实车状态真实不一致
    回收限制 电量高于约 90% 时车辆自行抑制 指令发出但正确地不产生效果

    另外,喇叭与灯光根本不上总线,它们是车把开关直接控制的 12 V 回路;刹车拉杆在部分车上有信号,改装的无传感器拉杆什么也发不出。这些边界决定了这套数据能覆盖到什么程度。

    嗅探工具与验证命令

    逆向过程被固化成四个子命令,全部跑在主机侧,配合一个串口转 CAN 适配器工作。 scan 负责扫波特率与 ID 类型组合,如果到处都是零帧,最常见的原因是 CAN_H 与 CAN_L 接反——无害,换过来即可;sniff 给出实时表格,包含解码后的物理量、每个 ID 的速率、逐字节变化图;events 先自学哪些字节会自行漂移,然后只打印真正的变化,使用时一次只操作一个控件,就能定位该控件落在哪个字节;log 落盘为 .asc、.blf 或 .csv 供离线分析。

    子命令 用途 典型判据
    scan 扫描波特率与标准/扩展 ID 全组合零帧通常是 CAN_H/CAN_L 反接
    sniff 实时表格:物理量、每 ID 速率、逐字节变化图 用于确认波特率与帧清单
    events 过滤自发漂移,只打印真实变化 一次只动一个控件
    log 录制 .asc/.blf/.csv 供离线回归与跨骑行比对

    配套环境搭建只需两条命令:先建虚拟环境并安装依赖,再用 250000 的波特率参数调用对应子命令,串口设备名按实际枚举结果传入。整个链路不需要改动车辆任何部件,这也是只读取数能长期稳定运行的底气。除了这套主机侧工具,固件侧还有一个专门的 CAN 探测程序,它把解码后的仪表直接输出到屏幕与无线链路上——之所以刻意走无线,是因为车辆与 USB 主机任何时候都不能同时连接。

    最后补一条容易被忽略的经验:总线上的 15 个 ID 与实际解析的 8 个之间的落差,本身就是最大的风险来源。任何「总线上没有某个信号」的结论,只有在完整捕获全部 ID 之后才成立;而车辆仪表已经显示的数值,是验证解码结果最便宜的基准。

    常见问题

    这条总线能直接拿来读取车辆数据吗?

    可以,但必须只读取:收发器不驱动总线也不应答,波特率猜错也不会扰动车辆。前提是先拆掉收发器模块上的 120 欧终端电阻,否则总线的 60 欧会变成 40 欧。另外不要同时接 USB 与车辆,两者会在 VUSB 上相撞并把车辆地接到保护地。

    为什么我读到的电量一直是 100?

    因为取的是 0x103 字节 0,那个字段在真实电量变化时保持不变,几乎可以确定是电池健康度。真实的电量百分比在 0x401 的字节 0,缩放为 1%。

    里程到底在哪个帧?

    在 0x402 的字节 2 至 3,小端,单位 1 公里。曾经被误认为里程的 0x202[6:8] 虽然单调递增,但与车速相关系数只有负 0.0005,两次骑行的每公里计数相差 34%,已被排除。由于总线上存在 1200 这类整常数,该结论仍标注为待一次自增骑行验证。

    能不能通过总线改骑行模式?

    可以,但不能用「发一次命令」的思路。控制器服从最近一次 0x490 且不锁存,仪表每 200 毫秒就会覆盖一次,因此必须持续应答仪表的每一帧;实测收到即回守住 297/297,自由运行 20 Hz 会丢失 24%。同时要注意仪表不监听总线,覆盖期间仪表显示与实车真实状态不一致,而回收等级发出后无法从总线验证。

    换一辆同型号车能直接复用这套偏移吗?

    不能。转把需求在本车位于 0x202[3:5],在参考日志那辆车上位于 0x202[2:4] 且完全不跟随转把。上游明确提示字节偏移随固件版本变化,换车必须重新验证,且这套解码本身是以另一份公开的 Talaria CAN 日志项目为地基的派生研究,并非独立来源。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/kbirand-talaria-tripper/README.md(总线参数、硬件接入、14 项解码信号表、四个字段证伪过程与覆盖机制实测)
    • 项目 01 —— public-can-dbc-datasets/additional/kbirand-talaria-tripper/SOURCE.md(DBC 的 9 报文 26 信号行规模、里程字段的待验证声明、派生来源与权利状态说明)

    免责声明

    本文所述的总线参数与信号定义均为社区研究报告产物,不代表车辆制造商的官方数据,文中数字均来自上述公开仓库的说明文件,未经独立实车验证。上游明确指出该解码是以另一份公开的骑行日志为地基的派生研究,适用车型、固件版本与其他车辆均未确立,字节偏移随固件变化,换车必须重新验证。该仓库快照中未发现任何许可证或逐文件再分发授权,仅可作私有离线研究副本,再分发或集成前须先行确认权利。涉及写入总线的操作请仅在封闭场地、由具备资质的人员执行,并以官方资料与实际测量为准。

    更新记录

    • 2026-10-15 初稿

  • 聆风 ZE0 的 CAN 信号:LBC 六组读数与 64 A 折返电流

    结论:2012 款 Nissan Leaf(ZE0)的只读遥测建立在两件事上:ELM327 走 Car-CAN 的 ISO 15765-4(11 位、500 kbit/s),以及一小撮 UDS 服务 0x21 组读取。这台车的标准 OBD-II PID 完全不实现,模式 01 的请求 0100 只会返回 NO DATA;真正的数据来自电池控制器的六组 UDS 应答。所有信号按「已验证、静态、待定」三档标注,其中最大的坑是第五组的包电流:它是有符号 16 位除以 1024,超出正负 32 A 就会以 64 A 为单位折返。

    传输层:先把 ELM327 的几条硬约束定死

    这套档案把所有适配器的公共事实放在最前面,因为它们决定了后面所有字节能不能拿到。协议用 ATSP6(ISO 15765-4,11 位,500 kbit/s,引脚 6/14 的 Car-CAN);UDS 对电池控制器需要一组固定的头与流控设置,而针对 Car-CAN 的被动嗅探必须用 ATCAF0——如果保留 ATCAF1,大部分原始帧会直接打印成数据错误。

    事实 细节
    协议 ATSP6,ISO 15765-4 CAN,11 位,500 kbit/s,Car-CAN(OBD 引脚 6/14)
    标准 OBD-II PID 这台车不实现,0100 返回 NO DATA
    电池控制器 UDS 请求头 ATSH 79B、应答过滤 ATCRA 7BB、格式 ATCAF1、流控头 ATFCSH 79B、块大小与帧间隔设置,另加 ATFCSM1;由整车控制器在 Car-CAN 与 EV-CAN 之间桥接
    被动嗅探 必须用 ATCAF0,否则绝大多数原始帧打印为数据错误
    缓冲区 未过滤的 ATMA 约 24 帧就溢出,必须配 ATCRA 过滤
    EV-CAN(引脚 12/13) 标准 6/14 接口下不可达,需要改线的 OBD 延长线
    蓝牙连接 每次写入都要带应答标志,否则收不到通知

    同一份档案还维护了一条替代路径:把一台原生 USB-CAN 控制器直接接到诊断口上,由 USB ID 决定走哪条驱动。

    电池控制器:六组 UDS 读数的分工

    电池控制器的六组数据按职责分开轮询,而不是一次全读。分组第一、二、四、五组标记为已验证,第三与第六组仍属待定。偏移量是相对 61 NN 之后载荷的 0 基位置。

    组 长度 内容 状态
    01 电池状态 39 字节 高压电流两个传感器、包电压、12 V、绝缘电阻、HX、SOC、容量 已验证
    02 单体电压 192 字节单体数据,解析填充到 200 字节 96 路无符号 16 位毫伏,末位之后用 0xFFFF 填充 已验证
    03 32 字节 字节 10–11 为最高单体毫伏,12–13 为最低单体毫伏,其余未知 待定
    04 温度 18 字节 四组「无符号 16 位原始值 + 有符号 8 位摄氏度」,字节 12 看起来是均值 已验证
    05 扩展状态 74 字节 最高/最低单体、温度原始值、放电标志、包电流、绝缘、分段差值与组电压 已验证
    06 均衡 25 字节 24 个数据字节即 192 位,每单体对 2 位,非零疑似表示正在泄放 待定

    第一组的字节偏移

    字节 字段 量纲
    0–3 高压电流传感器 1 有符号 32 位除以 1024 安
    6–9 高压电流传感器 2 有符号 32 位除以 1024 安;在一次 13 分钟行驶中测到负 66 安,库仑积分占 SOC 乘容量推算值的 96%
    18–19 包电压 无符号 16 位除以 100 伏,与 96 路单体之和相差在 0.1 伏内
    20–21 12 V 蓄电池 无符号 16 位除以 1024 伏
    22–23 绝缘电阻 千欧
    26–27 HX 无符号 16 位除以 100
    29–31 SOC 无符号 24 位除以 10000,单位百分比
    33–35 容量 无符号 24 位除以 10000 安时,SOH 再除以 66 安时
    4–5、24–25 未知,静态 样本值分别为 0x0287 与 0x00F2

    电流传感器的行为也定了处理规则:三个电流来源在怠速时绕着零点漂正负 0.5 安,第五组的放电标志跟着噪声走;传感器 1 很粗,以约 2 安为台阶。500 瓦负载下,传感器 2 与第五组相差在 0.05 安以内。于是读取器以传感器 2 为基准逐周期取值,每 5 秒学一次相对第五组的偏移,再叠加上本车的零位标定,并在控制器报告放电时把正电流钳零;仪表侧把绝对值小于 0.6 安(功率小于 0.25 千瓦)视为怠速。

    第五组的电流会折返,不是饱和

    这是这套档案里最有决策价值的一条。第五组的包电流是有符号 16 位除以 1024,理论上在正负 32.0 安处就该饱和,但这台车的实际电流远大于此。2026-09-03 的一次 13 分钟行驶给出了答案:171 条记录、92 个新鲜第五组样本,第一组传感器 2 达到负 66.5 安。

    假设 超过正负 32 安样本的中位误差(21 个)
    线性延伸(第五组等于传感器 2) 8.49 安
    在正负 32 安处饱和 8.49 安
    另一套斜率(半量程) 11.88 安
    折返(16 位混叠) 2.50 安

    饱和假设被直接证伪:邻域超过 40 安的样本没有一个停在轨值上,全部 169 个样本里只有 4 个落在 30 至 32 安区间,绝对电流分布直到边界都是平滑的;最大值只到 31.919 安,而且跨越边界时符号会翻转——传感器 2 为负 34.11 安时第五组读到正 31.71 安,负 47.50 安时读到正 15.57 安,负 41.13 安时读到正 23.58 安。轨内标度则是对的:在三行窗口内传感器 2 移动小于 3 安的 25 个样本中,两者中位相差 0.27 安、最差 1.43 安,拟合关系为 g05 约等于 0.956 倍传感器 2 减 0.199,R² 0.995。

    工程后果很具体:读取策略把传感器 2 当作权威值是对的,但如果它每次都在新鲜第五组样本上学习偏移并在样本间传递,那么超过 32 安时学到的差值本身就是折返误差。那次行驶中,融合后的电流相对传感器 2 中位偏离 5.9 安、九十分位 23.6 安、最差 41.1 安,随后「正在放电却读到正电流就钳零」的规则又把大量行驶行直接归零。修正办法是只在第五组读数明确处于轨内、且两次读数接近时才学习偏移。另有一条仍未解决:传感器 1 在负载下读到的是传感器 2 的中位 1.358 倍(十分位 1.294、九十分位 1.429,48 个超过 15 安的样本),而做库仑积分能与 SOC 对上的是传感器 2。

    还有一处信任边界:存入数据库的是控制器报告的原值,不再是策略改写后的值。进程量全部落在 current_adj_a 与 power_adj_kw 上,并用 current_adj_src 注明经过的步骤;任何车型档案的策略都不得改写已报告字段。

    Car-CAN 被动帧与其他 ECU 探测

    车身侧的被动帧必须靠 ATCAF0 加 ATCRA 逐号抓。下面这批已验证的条目构成了挡位、灯光、车门、门锁与胎压的数据源。

    ID 字节 字段 解码 状态
    0x421 b0 挡位 08 停车、10 倒车、18 空挡、20 前进、38 经济 已验证,五种全部
    0x174 b3 粗挡位 AA 停车或空挡、99 倒车、BB 前进或经济 已验证,无法再细分
    0x358 b2 转向灯 80 关、82 左、84 右、86 危险灯 左右已验证,危险灯为社区值
    0x385 b2–5 胎压 psi 等于原始值除以 4,顺序为左前、右前、右后、左后 静态,数值合理;小于 5 psi 视为传感器休眠
    0x5C5 b1–3 里程 无符号 24 位,单位随 0x355 b6 bit5 静态,与仪表一致
    0x5B3 b1 仪表 SOH 原始值右移 1 位,百分比 静态,与电池控制器一致
    0x60D b0 车门 08 驾驶位、10 副驾、20 左后、40 右后、80 尾门 已验证
    0x60D b2 门锁 18 已锁、00 未锁 已验证
    0x60D b0 / b1 灯光 04 示宽、02 近光、08 远光、01 雾灯 已验证
    0x284 b4–5 车速 原始值除以 100 km/h 待定,只见过 0
    0x5A9 b1–2 剩余续航 无符号 16 位右移 4 位后除以 5 km 待定,标度未确认
    0x180 b5 加速踏板 原始值除以 2,百分比 待定
    0x292 b6 制动踏板 / 制动灯 原始值大于 0 即制动 待定

    其他 ECU 的探测结果基本是负的,构成了边界:整车控制器对所有模式 22 与 0x21 请求都返回否定码 0x80,需要原厂会话与安全访问;逆变器与转向模块完全无应答;ABS、车身模块与助力转向会回应第一组读取,尚未解码。EV-CAN 上的 0x1DB、0x1DA、0x55B 等报文虽然有公开社区可视化的布局记载,但在这台车上从未被看到过,档案只把它们作为待核对的假设放在帧仿真器里,而这些编码器刻意不与真实车辆的解码器放在同一处。

    OBD-II 引脚 信号
    6 / 14 Car-CAN 高低,普通 ELM327 用的就是这一对
    13 / 12 EV-CAN 高低,电池、逆变器与充电机所在网络
    11 / 3 AV-CAN 高低,信息娱乐网络,本项目不读
    4 / 5 底盘地 / 信号地
    8 仅在车辆上电时输出 12 V
    16 常电 12 V

    原生 USB-CAN 通道带来的量级变化

    把 ELM327 换成 CANable 2.0 一类的原生 USB-CAN 控制器后,被动项不再需要 ATCRA 加 ATMA 的停留开销,整个循环坍塌为纯 UDS 请求时间。2026-10-03 在这台车上的实测结果是:蓝牙约 2 秒的完整循环压缩到 0.58 秒,第一组读取 0.07 秒、96 路单体读取 0.29 秒;开单体日志后,全新 96 路读取的中位间隔为 351 毫秒(2.77 次每秒,最大 498 毫秒)。

    项目 实测结果
    识别方式 USB ID 16d0:117e 为 slcan 固件,1d50:606f 或 1209:2323 为 candleLight,0483:df11 为烧录模式
    被动窗口 10 秒内 1,692 帧每秒、49 个报文 ID、0 错误帧
    完整循环 0.58 秒,含电池各组、96 路单体、暖通模块三组读取和全部被动 ID
    ISO-TP 间隔 暖通模块 在间隔 0 毫秒时丢连续帧(6 次里只有 3 次完整),5 与 10 毫秒时 6 次全通
    终结电阻 适配器跳线必须断开;车辆诊断口在 6/14 与 13/12 间测得约 60 欧
    接线基准 优先用引脚 5 信号地,而不是承载车身负载电流的引脚 4 底盘地

    EV-CAN 那条通道则以只听模式为唯一打开方式:只听模式下的控制器连应答位都不驱动,总线在电气上与没有这个监听节点时完全相同;「曼哈顿 EV-CAN」配置项会强制只听,且不提供覆盖开关。需要注意的细节是,不同固件对只听的实现强度不同:candleLight 需要重新打开设备并回读模式,slcan 的静默命令无法从主机侧确认,而 SocketCAN 由内核强制且可被校验。

    常见问题

    为什么标准 OBD-II 的 PID 在这台 Leaf 上完全读不到?

    因为这台车压根没有实现这套标准诊断服务:模式 01 的 0100 请求直接返回 NO DATA。所以所有可用的数据都要从自定义的 UDS 服务走,主要是电池控制器的 0x21 组读与暖通模块 的 0x21 组读。这也意味着通用诊断 App 在这台车上基本拿不到东西。

    第五组的包电流为什么超过 32 安就不可信?

    因为它是有符号 16 位除以 1024 的字段,没有更宽的备选字段也没有钳位,真实值超出正负 32 安后就会以 64 安为单位连符号一起折返。13 分钟行驶里,邻域超过 40 安的样本没有一个停在轨值上,且跨越边界时符号必定翻转;四种假设中折返假设的中位误差最小,为 2.50 安。处理方式是把第一组传感器 2 作为权威值,并限制只在轨内学偏移。

    换成原生 USB-CAN 控制器后,提升具体体现在哪里?

    最直观的是被动项的开销消失:原先每个被动项需要一次「设过滤加监听」的停留,约 0.2 至 0.8 秒;原生控制器一直在收全部帧,被动项退化成一次字典查找。结果是完整循环从蓝牙的约 2 秒降到 0.58 秒,单体日志开启时 96 路新读数中位间隔 351 毫秒。另一个区别是它能挂到 EV-CAN 引脚上,而这在 ELM327 方案里做不到。

    想在 EV-CAN 上取数据需要什么条件?

    需要一根改线的 OBD 延长线,把母座的 6 与 14 分别接到插头的 13 与 12,或者直接通过引出全部 16 针的直通分流接头取 13/12 两针。两条总线同样是 500 kbit/s、11 位 ID,适配器终结跳线必须断开。软件侧把总线标识明确配置为 EV-CAN,强制以只听模式打开。

    数据库里存的是不是控制器原值?

    是。策略层不再改写电流与功率字段,保留的就是解码器产出的控制器原值;融合偏移、零位标定与放电钳零这些派生步骤全部落在带后缀的调整字段上,并用专门的字段注明经过哪些步骤。另有测试约束所有车型档案不得改写已报告字段。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/davidkarnowski-leaf-ze0/docs/SIGNALS.md(传输层事实、LBC 六组字节偏移、Car-CAN 被动帧、EV-CAN 引脚表与三档置信度分级)
    • 项目 01 —— public-can-dbc-datasets/additional/davidkarnowski-leaf-ze0/docs/CAN_TRANSPORT.md(原生 USB-CAN 的实现方式、接线与终结要求、只听模式作用域,以及验证与未验证清单)
    • 项目 01 —— public-can-dbc-datasets/additional/davidkarnowski-leaf-ze0/README.md(只读边界、安全说明与两个车辆档案的规模)

    免责声明

    本文所有 CAN ID、字节偏移、缩放系数与置信度标注均来自一台 2012 款 Nissan Leaf 的公开只读遥测档案,属社区逆向工程产物,不代表车辆制造商的官方数据,也未经独立实车复现。不同年款与市场区域的字节偏移可能发生变化,标注为待定的内容不得用于计量、交易或安全判定。文中提及的诊断请求仅用于读取,涉及动手接线时请先确认车辆断电状态与终结电阻,本文不构成任何维修、购买或行驶决策的唯一依据。

    更新记录

    • 2026-10-15 初稿

  • 特斯拉 iBooster Gen1 台架解码:双总线、已锁存故障与先验证清单

    结论:这份 Tesla iBooster Gen1(件号 1037123-00-B,适配 2016 至 2020 年 Model S)的台架笔记给出三条硬结论:只给 12 V 常电、地和点火三根线,助力就会出现,因此纯只听的监视方案成立;两条 500 kbit/s 总线的引脚和极性都已完成实测;踏板行程可以换算到毫米。但这些结论有一条严厉的前置要求——作者在专门的「先自行验证」文件里写了:踏板传感器引脚、件内部终结电阻、峰值工作电流等项目必须先在台架上量出来,未经核实不得写进固件、DBC 或线束。

    台架前提:哪些已经量过,哪些只是假设

    区分「已测得」和「来自其他车型的社区资料」是这份档案的第一原则。电源与 CAN 引脚是实测量;踏板传感器那几组引脚属于借用其他 iBooster 变体(不同厂商平台)的推论,置信度低。

    引脚 功能 状态 如何收口
    1 常电 12 V,40 A 熔断 已确认 配合 9 与 20 即可出现助力
    9 地 已确认 与壳体接地螺柱连通验证
    20 点火 12 V,5 A 熔断 已确认 只有在它带电时才出现助力
    25 / 16 车辆总线 CAN-H / CAN-L 已确认,含极性 该极性下抓到干净的 0x39D 帧
    18 / 10 YAW 总线 CAN-H / CAN-L 已确认,含极性 该极性下抓到 0x38E 与 0x38F
    17 常电 12 V,5 A 熔断 低置信度 Gen1 应有此针,本件未量
    2 / 8 / 22 / 23 踏板行程传感器 低置信度 社区对同代也有分歧,需台架确认
    24 / 4 制动信号输出 / CLIN 低置信度 可能本件根本不存在
    连接器 26 针 EuCon 中等置信度 按壳体标记与针腔数量核对

    另外三条至今没有量:助力时的峰值电流(社区说法是「几十安」,保险丝规格 40 A,未测前一律按电瓶供电准备);只接引脚 1 与 9 不给点火时是否还发报文;上电自检是否会让推杆移动(在证明不会之前按会来处理)。

    两条总线与关键报文的定位

    两条总线同为 500 kbit/s、11 位 ID,都不带内部终结电阻,因此适配器侧的 120 欧终结跳线必须闭合,并在部件端并一颗松脱的 120 欧电阻,形成两节点总线;上电前的高低速线间拓扑检查应读到约 60 欧。

    总线 引脚(H / L) 静态帧率 报文 ID 承载内容
    车辆总线 25 / 16 36.4 帧每秒(静态 4 个 ID,踏板动作时 11 个) 以 0x39D 为主 16 位踏板行程
    YAW 总线 18 / 10 149.5 帧每秒 0x38E(99.7 Hz)、0x38F(49.8 Hz) 12 位位置、状态与两个制动标志

    实际作业中用两台适配器时,USB 索引会重排,识别哪台在哪条总线上必须看内容——谁看到 0x39D 谁就在 25/16 上,绝不能按索引或 USB 地址判断。还有一个非常具体的陷阱:这条总线只有两个节点,只听模式下没有节点发应答位,发送错误计数会以每次 8 递增,约 32 次尝试就进总线关闭状态,再自动恢复,如此循环。同一器件、同一 12 秒窗口的对照结果是:只听模式抓到 1,006 帧每秒但只有 1 个唯一 ID,而应答模式是 37 帧每秒却有 4 个 ID。所以捕获一律用应答模式。

    0x39D:踏板行程的字节定义与两套标定

    这条报文是 500 kbit/s、DLC 4、25.0 Hz。它的 b0 是校验和,算法为 b1 + b2 + b3 + 0xA0 取低字节,在 2,250 帧上 100% 通过;b1 是半字节活跃计数器(每次加 1,模 16,高四位恒为 0);b2:b3 是小端无符号 16 位行程值,静态约 262,观测到的最大值为 14070。

    样例 解析
    B7 0E 08 01 计数器 14,行程 264(静止)
    85 00 C8 1D 计数器 0,行程 7624(行程中段)
    D4 0B F8 31 计数器 11,行程 12792(接近全行程)

    筛选方法值得一提:按「平滑度」而不是极差排序候选字段,判据是相邻差值均值除以值域。校验和与计数器铺满 00 到 FF 但帧间跳变随机,物理量则平滑移动;b2:b3 小端组合得分 0.009,计数器与校验和那对约 0.12。

    位置 实测原始值 样本数
    静止 263.1 319
    21 mm 6114.0 161
    42 mm 13125.2 80
    终点限位脉冲峰值 13606(合 43.44 mm) 无

    第一次跑给出 counts = 333.866 × mm − 897.2,即约 0.0030 mm 每计数。但静止点不落在这条直线上:263 计数外推得 3.475 mm 而不是零,合理解释是传感器啮合前约有 3.5 mm 自由间隙,低于该点读数被压在约 263 的底值上。第二次跑保持在 10、20、30 mm,结果与第一次不自洽——20 mm 读到 6886.4,反而高于第一次 21 mm 的 6114.0。单调传感器不可能如此,因此至少有一组物理位置是错的。

    组合 计数每毫米
    第一次跑(21、42 mm) 333.87
    第二次跑(10、20、30 mm) 361.93
    五个点全用 320.68

    结论很干脆:瓶颈是尺子而不是 CAN 数据。单次保持内的总线读数离散为约正负 20 计数(0.062 mm),而两次跑之间的物理位置偏差可达 4.4 mm——信号比它的测量手段精确约 70 倍。要真正标定,需要百分表配固定基准,并且一次跑完整个量程(因为误差出现在两次跑之间,而不是一次跑的内部)。用于显示和记录已足够,档案给出的组合拟合是 mm = (counts − 3.3) / 320.68。

    0x38E 与 0x38F:状态、两个制动标志与校检

    0x38E 是 500 kbit/s、DLC 8、99.7 Hz,静止值为 77 2B 00 40 11 00 00 00。它的 b0 不是数据,而是覆盖 b1 到 b7 的 CRC-8/SAE-J1850。b3 只是位置的低字节,b4 的低四位才是高字节位——这是这份档案纠正过的最重要一处。

    字节 字段 说明
    b0 CRC-8 覆盖 b1 至 b7,无 数据
    b1 活跃计数器 0x20 至 0x2F,高四位固定为 2
    b3 位置低字节 静止稳定值为 0x40,会因进位而回绕
    b4 低四位 位置高字节位 与 b3 组成 12 位位置,静止 320,全行程约 3052
    b4 高四位 状态 0 初始化中、1 正常助力、2 故障
    b6 制动标志 0 或 1,带约 0.55 mm 回差

    把 b4 高位从位置里剥离是人为诱发的 sensor 故障验证的:拔掉行程传感器后该 nibble 从 1 跳到 2,而 b3 完全没动,旧的 16 位读法整整偏移了 0x1000。健康工况下它恒为 1,所以两种解释只差一个常数,这也是早先的 16 位模型能拟合所有健康捕获、相关性仍达 0.9999 的原因。上电轨迹还能独立 佐证这个拆分:约 1.47 秒前 b4 读 0x01,之后读 0x11,而两侧的 12 位位置都是 320。

    标志 触发位置 回差 次数
    0x38E b6 建立 2.18 至 2.42 mm 约 0.55 mm 4 次上电周期
    0x38E b6 释放 1.72 至 1.75 mm 释放阈值在四次上电中重复到 2 个计数内
    0x38F b2 bit0 建立 1.45 至 1.66 mm 释放边沿未被采样间隔分辨 跨 4 次上电
    0x38F b2 由 0xE3 转 0xDB 39.75 至 40.16 mm 回程 38.77 至 39.51 mm 4 次

    0x38F 是同一总线的另一条报文,49.8 Hz,静止值 3F 2D E2 53 02 00 00 00,同样用 b0 承载同一套参数的 CRC-8。它的 b2 是状态字节:跨四次上电只见到六种取值,0xE2 为就绪且制动释放、0xE3 为制动施加、0xDB 为接近行程末端、0xCC 为故障,另三个只在启动前两秒依次出现。b3 虽然常变,但与位置的相关性只有 0.009、与踏板速度 0.000,也不是计数器,档案刻意留着不解码。两套制动标志对应两个阈值,形状上像稳定程序期望的冗余开关对;而 0x38F 的释放边沿在 49.8 Hz 下常只有一两帧落在过渡区,观测点散布在 1.45 到 4.11 mm,不要引用它的释放值。

    整份档案还有一条反向但有用的结论:独立的故障状态报文并不存在,状态就藏在位置报文的一个字段里。完整性方案则分两种:车辆总线的 0x39D 用加性校验和,YAW 两条报文用 CRC-8/SAE-J1850(多项式 0x1D、初值 0x00、异或输出 0x0A,输入输出均不反射),在四次上电周期的 46,960 帧 0x38E 与 23,478 帧 0x38F 上 100% 通过,合计 70,438 帧零失败;两条 ID 共用一套参数,说明 CRC 并未用报文 ID 做种子。

    故障行为:会锁存,且两条总线会不一致

    拔掉行程传感器可以诱发故障,助力随之消失,三个信号在约 10 ms 内一起变化。这里最关键的一条是它的可恢复性边界。

    步骤 状态 nibble 0x38E 位置 0x39D 行程 助力
    正常 1 实时更新 实时更新 有
    拔掉传感器 2 无 钉在 16354(0x3FE2) 无
    重新插回传感器 仍为 2 恢复实时(320 到 401) 仍钉在 16354 仍无
    断电重启 1 实时 实时 有

    两件事由此定下来。第一,钉住值带有效校验和,16354 在物理上不可达(终点限位才 13606),所以消费者不必认识这个哨兵值也能按量程拒绝。第二,状态位是「助力可用性」标志,不是「数据有效性」标志:插回传感器后位置已经有效并持续更新,状态却仍是 2、助力依旧关闭,只有断电重启才恢复。锁存期间的另一条后果是两条总线不再一致——YAW 总线报告真实位置,车辆总线仍钉在哨兵值,因此要位置就得用 0x38E。

    对实车的影响值得提示:插头瞬时接触不良(振动、腐蚀、压接不良)会把助力器锁进无助力状态,直到点火循环才恢复——踏板变硬并持续如此,而原车仪表没有任何东西能解释原因。制动仍然可用,只是需要大得多的踏板力。

    刹车后的突发报文:行为数据与推理教训

    最后一组可用数据是事件性的。0x31D、0x34D、0x36D、0x37D、0x38D 每次各发一帧、集中在约 120 ms 内,0x33D 也属于这一组。合并六份日志得到 12 次完整突发,其中 10 次跟在制动释放之后 0.64 至 2.20 秒,没有一次踏板施加会漏掉;另外 2 次是上电突发,约在累计运行 6.8 秒时出现,与踏板无关。

    字段 含义 标度 相关性
    0x38D b5:b6 小端 u16 该次施加的推杆行程峰值 129.3 计数每毫米 0.99975
    0x37D b0:b1 小端 u16 制动施加持续时间 27.50 计数每秒 0.99877
    0x31D b2 高四位 同上持续时间的对数分桶 1 到 7,约每翻倍一级 0.884
    0x31D b0:b1、0x3AD b0:b1 累计运行时间,非事件数据 9.99 计数每秒(100 ms 时基) 无

    0x38D 的峰值与标定过的行程在 34 mm 量程内相差在 0.66 mm 以内,比尺标定的 2 mm 不确定度还紧;三次上电中四次打到终点限位的读数彼此相差在 8 个计数内。但这一节所有数字都建立在 10 个事件上,候选字节远多于事件数:两个 0.999 级的拟合通过了 20,000 次置换检验,而相关性在 0.9 附近及以下的都只当线索。峰值与持续时间在这批标定扫描中部分耦合(踩得深通常也踩得久),还需要 20 到 30 次独立控制深度、速度与保持时间的施加才能收口。

    这节还留了两条反面教训。一是量程规则会被误用:针对消费者的「行程超出 13700 即拒」对分析是错的——终点限位读数 13606,但快速撞击会过冲到 14070,套用会剪掉真实行程,曾因此把系数写成 129.8(恢复过冲后为 129.3,且拟合更好)。二是运行时间会伪造相关性:后期事件往往更深更久,于是运行时间足以冒充测量量,0x37D b5 与峰值相关 0.90 却和运行时间相关 0.82,0x34D b5 与运行时间相关 0.88,两条都没敢主张。

    常见问题

    这份解码能不能直接写进 DBC 或线束?

    踏板行程、位置、状态与两条 ID 的校验部分是实测量,可以用;但标注为低置信度的行不能落地。作者在「先自行验证」文件里点名了必须先在台架上量出来的项目:踏板传感器引脚(2、8、22、23)、17 号针、24 与 4 号针是否存在、两总线是否真的没有内部终结电阻、助力时的峰值电流、以及上电自检是否会让推杆移动。未按日期把假设替换成实测之前,不要写进固件、DBC 或线束。

    为什么 0x38E 的 b4 高位不能当作数据有效位?

    因为它是助力可用性标志,不是数据有效性标志。人为诱发故障后把传感器插回,0x38E 的 12 位位置已经恢复实时更新(320 到 401),而该状态位仍为 2、助力依旧关闭,只有断电重启才恢复。位置本身的合法性应当另按量程判断:故障 Sentinel 是 16354,这个值带有效校验和且在物理上不可达。

    为什么捕获必须用 ACK 模式而不是只听?

    因为这条总线只有两个节点,只听模式下没人发应答位,发送错误计数以每次 8 递增,约 32 次尝试就进入总线关闭并自动恢复,循环往复。同一器件、同一 12 秒窗口的对照是:只听模式 1,006 帧每秒但只有 1 个唯一 ID,应答模式 37 帧每秒却有 4 个 ID——那 1,006 帧是重传循环而不是信号,而且它把其余三个 ID 全部隐藏了。

    踏板行程为什么会有两套换算系数?

    第一次跑只有 21 与 42 mm 两个点,得到计数等于 333.866 倍毫米减 897.2;第二次跑取了 10、20、30 mm,得到 361.93 计数每毫米。两次不自洽的标志是 20 mm 的读数高于 21 mm 的读数,单调传感器不可能这样,所以问题出在物理位置测量而不是总线数据。五个点合并后的系数是 320.68,用于显示与记录足够,而要把精度提高到毫米级则需要百分表加固定基准,并且一次跑完整个量程。

    传感器插头瞬时接触不良会发生什么?

    会把助力器锁进无助力状态:状态 nibble 变为 2,车辆总线的行程值钉在 16354,助力关闭。即使插头立刻恢复接触,YAW 总线的位置已经恢复更新,状态仍保持 2、助力也仍不回来,必须等到点火循环才恢复。实际后果是踏板突然变硬并持续变硬,而原车仪表上没有任何东西能说明原因;制动仍然可用,只是需要大得多的踏板力。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/pelosim-tesla-ibooster/docs/DECODE.md(两条总线的引脚与帧率、0x39D 与 0x38E、0x38F 字节定义、校验方案与故障行为)
    • 项目 01 —— public-can-dbc-datasets/additional/pelosim-tesla-ibooster/docs/PINOUT.md(引脚假设表、置信度分级、台架接线与实测结果)
    • 项目 01 —— public-can-dbc-datasets/additional/pelosim-tesla-ibooster/docs/BENCH_LOG.md(首次点亮记录、只听陷阱、二次离线分析的推行数据与推理教训)
    • 项目 01 —— public-can-dbc-datasets/additional/pelosim-tesla-ibooster/VERIFY_FIRST.md(必须先自行验证的清单与「打勾即等于用实测替换假设」的要求)

    免责声明

    本文内容涉及制动助力部件。所有 CAN ID、字节定义、系数与阈值均来自单一零件号的公开台架笔记,未在任何独立实车上复现,不构成装机、改装或维修依据。文中明确区分了已实测量与借用其他 iBooster 变体的假设,凡标注低置信度或未打勾的项目,在自行测量之前不得进入固件、DBC 或线束。制动系统属于安全相关件:助力失效时踏板力会显著上升,任何介入都应在具备夹持、限位与断电条件的台架上进行,并由具备资质的人员确认。

    更新记录

    • 2026-10-15 初稿