标签: 车型协议

  • 奔驰 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 初稿

  • 雪铁龙 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 初稿

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

  • 沃尔沃 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 初稿

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

  • MX-5 ND2 的 CAN 状态表:221 个开放字段与三级证据标签

    结论:这份 Mazda MX-5 ND2 的 HS-CAN 档案,价值不在仪表盘能画几个数,而在于它把总线上的每一个可用位域分成三层:已确认信号、带 _maybe 或 _related 后缀的开放字段,以及已经证伪的负结果。截至 2026-09-30:参考日志里 1,977 个会变化的位中,未被 DBC 信号覆盖的从 1,311 位降到 1,124 位;跨全部日志仍有 221 个字段在半数以上日志里变化却没对上物理含义。同期修掉的最严重问题不是某个信号定义,而是分析工具本身的缺陷:50 份日志重算后,离合器百分比公式被修正为严格的 0.5 倍原始值。

    硬件链路与双份 DBC

    这台车的采集链路很朴素:OBD 口的高速 CAN(引脚 6 为 CAN_H、14 为 CAN_L,4/5 为地,16 为常电 12 V)经一根自制 Cat5e 短接线接到 CANable 2.0 方案的 USB 适配器,再由树莓派按 KeyState 信号自动启停 candump 日志。总线为 500 kbit/s,通道只有 can0;适配器上的 R120 终结跳线必须拨到 OFF,因为它只是挂在总线上的一个分支,不是总线端点。

    项目 取值 这么定的原因
    USB 适配器 CANable 2.0 方案,工作模式 USB ID 1d50:606f,烧录模式 0483:df11 两种固件可从 USB ID 区分;误入烧录模式需断电数秒重插
    总线与速率 高速 CAN 单通道 can0,500 kbit/s ND2 的 OBD 口只暴露这一条高速总线
    终结跳线 R120 OFF 车辆总线两端已终结,第三颗 120 欧电阻会拉偏显性电平
    主用 DBC 持续维护的 MX5ND 高速总线扩展版 所有修正与新增都落在这一份
    上游原始 DBC 保持原样不做改动 来自社区 6th-Gen Mazda 项目,许可为 CC BY 4.0,留作对照基准
    运行环境 树莓派只读根文件系统加内存叠加层 只有挂日志的 U 盘可写,系统改动需要两次重启

    命名约定本身就是这套档案的核心契约:没有后缀的信号表示已在多份日志上定量确认;_maybe 表示释义或刻度尚未锁定,只允许原始值透传;_related 表示它与某个已知量同源但不是同一物理量,不能当成简单镜像。此外还有一批信号被显式标记成「名字看起来正常但实际不可用」,例如社区 DBC 里两个修正过的加速度通道,工程上一律改用车身控制模块的同名加速度通道。

    已锁定的场位:可以直接引用的定义

    下表摘自状态表与开放字段表的确认部分,包含 2026-09-26 实车测试新增的条目。每一条都带具体的判定依据,而不是「看起来合理」。

    信号 位置 公式 / 单位 判定依据
    离合器行程 已有 DBC 通道 百分比等于 0.5 倍原始值 2026-09-29 重算后 R² 达 1.000,旧的 0.4665 倍加 0.56 被判定为分析工具假象
    实际发动机百分比扭矩 0x167 byte4 3.0242 倍原始值减 177.849,残差 4.07 个百分点 与标准 PID 0x62 两次行驶对照,2026-09-29 再校准 +2.6%
    制动压力 已有 DBC 通道 斜率 0.0012413、偏移 +32.7986 与真实 OBD 参考通道 R² 0.986,2026-09-29 再校准 +2.4%
    倒挡 0x445 bit 7 布尔量 倒车时横摆率符号反向,吻合度 99.7%,样本 1,195
    牵引力控制介入 0x211 bit 40 布尔量 5 份日志 6 段弯心出弯工况,同时伴随发动机扭矩下降
    强减速标志 0x211 bit 43 布尔量 6 份日志 16 段,触发区间 0.46 至 0.84 g,中位数 0.60 g;两次实车全力制动已确认
    ABS 介入 0x211 bit 42 布尔量 35 分钟日志中占 0.052%,恰好落在两段真实调制区间;同日返程对照组为 0.000%
    DSC 指示灯 0x415 2|2 3 表示闪烁 介入时的值与自检灯阶段的值不同;旧定义长期读作关闭,已不作为状态依据
    冷机指示 0x4F7 5|2 3 表示冷机 21 次记录全部在冷却液正好 55.0 °C 时切换
    车身模块供电电压 0x43F 19|10 0.016 V 每 LSB R² 0.998,且恒定低于直流变换器通道 0.68 V
    燃油消耗计数器 0x420 byte2 每升 4,834 个计数 两次加满共加油 34.4 升;与空气质量流量及空燃比的速率相关性达 0.99 至 0.999
    行驶距离计数器 0x420 byte1 每步 0.1992 米 对着里程表增量标定,覆盖 5 份日志;早期 0.209 是车速高估带偏的结果
    剩余保养里程 0x3D1 47|14 公里,原始值等于 173764 减里程公里数 34 份日志 R² 达 1.000000,取代了原先取值混乱的同名字段
    转向角速度幅值 0x082 byte5–7 12 位,约 0.5 度每秒每 LSB,符号在 byte7 bit0 28 份日志中对角度求导,相关性达 0.988 至 0.998
    方向盘绝对角度(EPAS) 0x86 0.1 倍原始值减 1600 度 剔除无效帧后 R² 达 0.9997 至 0.99995,残差 0.65 至 0.94 度
    交通标志限速 0x35F 4|7 km/h 取值 30 到 120,与实际行驶速度吻合,0 表示无限速
    平均油耗 0x4F3 byte4–5 大端 0.01 升每百公里,60 秒更新一次 加油复位时刻对齐,后续与计数器、距离推算相差 2.6 毫升

    最后一行值得单独说明:瞬时油耗在高速 CAN 上并没有找到独立的广播通道,实践中可以用燃油消耗计数器除以行驶距离计数器自行计算;这也是这套档案一贯的写法——公开发的是方法,而不是整车轨迹数据。相比之下,机油温度与爆震退角这两个关键量完全不在广播里:机油温度对应厂商私有的模式 22 自定义数据标识 0x1310,公式是首字节乘 256 加次字节、再除 100 减 40,标准 PID 0x5C 在这台车上不被支持,因此每 10 秒主动轮询一次;爆震退角对应同样是厂商私有的标识 0x03EC,公式是有符号 16 位整数除 512,两次独立对照分别为 73% 和 81% 逐位相同。

    仍然开放的字段:221 个未知字段的分类

    开放字段表把「还没有名字」的东西也做了归类。参考日志里 1,977 个会变化的位中,未被 DBC 覆盖的从 1,311 位降到 1,124 位;跨全部日志统计,至少在半数日志中会变化的开放字段共 221 个:32 个测量场(419 位)、42 个状态场、128 个标志位、10 个计数器、9 个校验或噪声。剩余测量位大多集中在前视摄像头报文(0x242 至 0x246)与信息娱乐报文(0x3D2、0x4FE)里。完整报文聚类还给出另一个量级:151 条报文中有 74 条带动态未分配字段,其中 36 条完全未知。

    字段 观察到的行为 假设 定向实验
    0x200 byte4–5(偏移二进制) 载荷域,与踏板、扭矩的相关性达 0.72 至 0.94 驾驶员需求扭矩或指示扭矩 用牵引力控制请求量做牛米锚点
    0x200 byte2–3 多数取负 40 至正 10,能量回收时更低,冷机可到负 49 附件损失扭矩 怠速下逐项开关空调与后窗加热
    0x20A byte2–3 疑似有符号;清理后重扫,燃料切断在 15 份日志中相关性中位数 0.71,目标空燃比 7 份为 0.69 混合气或滑行状态 追加标准 PID 对照
    0x4DA byte0/1/2/4 起步取 50,滑行时下降,加载荷后缓慢上升 催化器温度或氧存储模型 同时记录催化器温度 PID
    0x4FA byte2–3 清理后重扫:扭矩 11 份日志相关性中位数 0.65,节气门 6 份 载荷或暖机自适应 暂缺
    0x21F byte4–5 清理后重扫:进气歧管压力 6 份日志相关性中位数 0.70 歧管压力或载荷量 暂缺
    0x4D4 byte0–5 点火后归零,几分钟后出现;byte0 在高速公路上升,byte1 在堵车时增长 驾驶评分或经济监视器 按时刻拍照记录显示屏
    0x09B bit 2 每 50 到 100 秒出现约 10 秒;怠速期间电流通道下降约 100 个计数 大功率用电设备,疑为散热风扇 听或观察风扇并记录时刻
    0x4DF byte0、byte5 冷启动时紧贴合进气温度,相关性 0.980 与 0.994,但斜率分别为 1.44 和 2.24 K 每计数 变换器或电容温度,也可能是随温限值 红外测温仪对比

    字节扫描工具本身也经历过一次去伪:早期版本把单个初始化帧造成的常值(例如 0x596)和锚点起始段的自检灯突变误判成候选,清理后候选对从 105 降到 58。工具保留了两处已知局限:排名把 R² 四舍五入到两位,导致「胜出的布局」常常只是一段近似区间;缺少分辨率细化能力时,较短且拟合相差不大的子域可能取胜,工具会对这种情况打印更长的备选提示。目前仍列为中等候选的开放字段是 0x20A byte2–3、0x4FA byte2–3、0x200 byte6–7 与 0x21F byte4–5。

    负结果与方法陷阱

    这套档案最值得借鉴的一点是它把「找不到」也写成了结论,并附上对照组强度。下面几条在别的 ND2 项目里很容易被重复劳动。

    结论 证据 后果
    垂直加速度、侧倾角速率与俯仰角速率不在高速 CAN 上 25 组「CAN 加手机」平行记录,正对照组横摆率相关性达 0.95;夜间启动也未见照度调节电机的位置斜坡 只能转向 UDS 会话或中速总线去取
    车上没有可用的日历时钟通道 600 多个未知字段做过计数行为筛查,最佳结果是 0x4FE 上的一个 3.33 Hz 点火计时脉冲,周期在 3 份日志上的变异系数仅 0.000025,但每次点火归零 无实时钟期间的日志只能靠文件名加偏移量纠时,后期加装了 DS3231 时钟模块
    高频轮询会挤掉同总线上的第三方适配器 约 170 次每秒的请求压力下,对方 19% 至 29% 的请求先读到我们的应答,5% 至 18% 完全无应答,应用侧请求率跌到 0 检测到 0x7DF 或 0x7E0 上有外来请求时,把自身轮询限流到 5 轮每秒
    把某个字段当成挡位会出错 原先用 MT_Gear_Actual 取 7 表示倒挡,实际那是点火后约两秒的初始化值,倒车时该字段为 0 挡位判定改用 0x445 bit 7
    分析工具差错会让比例尺系统性偏小 重采样函数在拟合时对稀疏参考做了线性插值,压低了 R² 与斜率 离合器、制动压力、扭矩、电池电压的比例尺全部重新折算

    还有一处工程细节值得注意:胎压是这套档案里唯一不做周期性广播的量,必须靠主动 UDS 请求获取(请求头 0x720,模式 22,应答落在 0x728,DBC 里按 PID 做多路复用),轮询周期刻意设为 120 秒以压低总线占用。轮位映射直到 2026-09-26 才完整收口:轮胎 1 为左前、轮胎 2 为右前,轮胎 3 与 4 分别为左后、右后。

    常见问题

    为什么这份档案里还有 221 个字段没有名字?

    因为作者把「未解释但会变化」的字段也当作成果登记,而不是静默丢掉。统计口径是至少在半数日志里发生变化的开放字段,共 221 个,其中包含 32 个测量场(419 位)、42 个状态场、128 个标志位、10 个计数器和 9 个校验或噪声字段;剩余测量位集中在前视摄像头与信息娱乐报文里。

    总线上的车速为什么比 GPS 高约 2.9%?

    这是这台车本身的特性,不是解码错误:70 份带手机 GPS 的日志做比值得到 0.971,即总线车速偏高约 2.9%。它会影响加速、制动、极速与滑行阻力拟合中的绝对数值,因此状态表里专门留了一条提示:性能模型使用绝对值时要扣掉这个偏差。

    为什么要给部分信号加 _maybe 后缀而不是直接用?

    后缀是这套档案的证据等级标签。_maybe 表示释义或刻度尚未锁定,只能做原始值透传,不能换算成物理量;_related 表示与某个已知量同源但不是同一物理量的镜像。历史上确有反例:某个 15 位扩展场曾被引申为非线性,后来发现是取错位导致的。

    第三方 OBD 适配器为什么会被本项目的轮询挤掉?

    因为快轮询组在 0x7E0 上以约 170 次每秒发请求,与手机端适配器共用同一个报文头,导致对方 19% 至 29% 的请求先读到我们的应答、5% 至 18% 完全得不到应答,应用侧请求率从约 19 次每秒掉到 0。修复办法是检测到外来请求时把自身轮询限流到 5 轮每秒。

    高速 CAN 上有没有可以直接对时的日历时钟通道?

    没有。600 多个未知字段做过专门的计数行为筛查,最佳候选是 0x4FE 上的一个 3.33 Hz 点火计时脉冲,周期在 3 份独立日志上的变异系数只有 0.000025,但它每次点火都会归零;另一个看起来像的量被证明是累计工作时间,熄火即停。因此无实时钟期间的日志只能靠文件名加偏移量纠时,后续加装了 DS3231 时钟模块。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/mainbrain-mx5-nd2-can/docs/status/can-bus.md(硬件链路、双份 DBC 策略、可解码信号分组、开放点与纠时机制)
    • 项目 01 —— public-can-dbc-datasets/additional/mainbrain-mx5-nd2-can/docs/status/can-open-fields.md(已确认信号表、实车测试新增项、开放字段分类与报文聚类数量)
    • 项目 01 —— public-can-dbc-datasets/additional/mainbrain-mx5-nd2-can/README.md(仓库定位、许可证与刻意不公开的内容说明)

    免责声明

    本文所述的 CAN ID、字节位定义、缩放系数与验证状态均来自一台 Mazda MX-5 ND2 车主自行记录的公开档案,属社区逆向工程产物,不代表车辆制造商的官方数据,也未经独立实车复现。不同年款、市场区域与 ECU 软件版本可能存在差异;标注为开放或假设的内容不得用于计量、安全判定或控制用途。本文不构成主动诊断、刷写或执行器操作的授权。

    更新记录

    • 2026-10-15 初稿

  • Ram ProMaster 2022 三总线地图:125 kbit/s 实测与 16 个 UDS 端点

    结论:2022 Ram ProMaster 的被动 CAN 工作必须按三条独立总线规划:C-CAN(OBD 引脚 6/14,500 kbit/s)、B-CAN / CAN IHS(DLC 引脚 3/11,125 kbit/s 实测)和 CAN CH(DLC 引脚 12/13,500 kbit/s 实测)。这批记录里登记的 UDS 端点共 16 个,全部走 29-bit ISO-TP normal-fixed 寻址。真正决定能不能落地的不是「能读多少帧」,而是三条边界:OEM 文档里的 CAN-B 50K 说法不能用来配波特率;B-CAN 上 0x760 的被动里程只被认可为中控模块的本地副本;0x1F4 字节 4 高位已被完整复核驳回,不能当当前挡位。

    三条总线的速率、引脚与证据来源

    三条总线里只有 C-CAN 的 500 kbit/s 同时有 OEM 文档和实测两个来源,另外两条的通信参数都来自本机实测。B-CAN 是最容易被带偏的一条:该车型的 COMMUNICATION / CAN BUS DESCRIPTION 明确把 CAN-C 写成 500K、CAN-B 写成 50K,但这份文档用的是 C-1 到 C-8 与 BH 这套分支命名,与 DLC 图的 CAN C/CH/IHS 命名体系并不对齐。2026-07-20 在引脚 3/11 上的被动捕获给出 125 kbit/s 且零 RX 错误,因此以实测为准,文档里的 50K 只保留为线索。

    总线 速率 引脚 接入方式 证据边界
    C-CAN / HS-CAN 500 kbit/s OBD 6/14 经 SGW 旁通的内部 C-CAN tap,Board A CAN1 角色 动力总成与诊断;法规要求的 OBD-II Mode 01 PID 不经此旁通
    B-CAN / CAN IHS 125 kbit/s(实测) DLC 3/11 标签转接线的 B-CAN 支路,Board A CAN2 角色 舒适与车身;派生配置的 8 个目标里 4 个已应答,另外 4 个仍超时
    CAN CH(第二条高速总线) 500 kbit/s(实测) DLC 12/13 灰色 12/13 适配器,Board B CAN1 角色 被动捕获零收发错误,同时完成 ABS、EPS、HALF、ORC 的身份读取

    永久安装用两块双通道适配器承载三个角色(gs_usb,USB VID:PID 1d50:606f):C-CAN 与 B-CAN 分别落在第一块的 dev_id 0(CAN1)和 1(CAN2),CAN CH 在第二块的 dev_id 0,剩下那一路保持 down。四块板载红色终结跳线全部拆除,因为三个 tap 接入的是车内已经终结的网络;虽然适配器支持 CAN FD,暴露出来的三条总线一律配成 classical CAN、FD off。角色由 USB 序列号加 dev_id 解析,Linux 的 canN 编号只是枚举顺序,不作为身份依据。

    16 个 UDS 端点的总线分布与行为差异

    下表是已登记的端点。它们的 DID 命名空间按 ECU 隔离——雷达的某个 DID 和其他模块的同名 DID 没有任何关系,所以不要把这些行合并成一张「整车 DID 表」。

    键 模块 总线 TX → RX 已记录的行为
    radar_acc Bosch ACC 雷达 C-CAN 18DA2AF1 → 18DAF12A 扫描途中切断点火仍会 ACK;车速只能走内部 DID,OBD PID 不可用
    pcm 动力总成模块(3.6L) C-CAN 18DA10F1 → 18DAF110 固定 DLC 8 零填充是已知可用配方;遗留会话请求已两次验证
    rf_hub RF Hub(TPMS / RKE) C-CAN 18DAC7F1 → 18DAF1C7 点火 OFF 仍应答,属 KL30 常电,是驻车取电压的入口
    tcm ZF 948TE 变速箱 C-CAN 18DA18F1 → 18DAF118 读取 211B–2132、2136–213E 与 026B 均为正向
    shifter 电子换挡器 C-CAN 18DA1FF1 → 18DAF11F 身份已读取,可用于模块级区分
    bcm_ccan 车身控制模块 C-CAN 端点 C-CAN 18DA40F1 → 18DAF140 执行类请求受电源模式门控,钥匙 OFF 常见否定响应
    cluster 组合仪表 IPC C-CAN 18DA60F1 → 18DAF160 已把若干仪表符号逐项绑定到具体 DID
    telematics 远程通信盒模块 C-CAN 18DAC6F1 → 18DAF1C6 唯一一个车上后台诊断客户端从不查询的已注册模块
    ics_bcan 中控面板 B-CAN 18DA85F1 → 18DAF185 里程 DID 2001 以 0.200 Hz 轮询,收到 302/302 正向应答
    uconnect_bcan 主机 / 显示屏 B-CAN 18DA87F1 → 18DAF187 身份与阶段性故障码家族匹配
    climate_bcan 自动空调模块 B-CAN 18DA98F1 → 18DAF198 所选变体未通过校验,其仪表标签不可直接套用
    emcm2_bcan 中控菜单 / 音量按键 B-CAN 18DAD9F1 → 18DAF1D9 设备子类型匹配加上 OEM CAN-IHS 角色
    abs_canch ABS / ESC CAN CH 18DA28F1 → 18DAF128 历史偶发故障码,最后一次测试通过
    eps_canch 电动助力转向 CAN CH 18DA30F1 → 18DAF130 无故障报告
    half_canch 前视摄像头辅助模块 CAN CH 18DA31F1 → 18DAF131 同一身份还可通过网关在 C-CAN 侧被动读到
    orc_canch 乘员约束控制器 CAN CH 18DAC0F1 → 18DAF1C0 无故障报告

    网关路由是这张表的隐藏前提:在 C-CAN 上发给 CAN CH 目标的物理请求会被网关逐帧转发,中位延迟 0.31 ms(51 次交互,落在 0.23–2.78 ms 区间),网关还会在 CAN CH 侧替换成自己的流控帧;ECU 应答被复制回 C-CAN 时目标字节被改写为 F2,所以 C-CAN 上看到的 18DAF2xx 是网关副本,不是第二个诊断仪。另有一条与时统高度相关的事实:车上存在一个后台诊断客户端,会在外部 F1 流量静默 92 秒以上后才启动只读扫描,一旦外部轮询恢复便在 1 至 2 秒内终止;做被动相关性分析时必须把这些窗口单独标出来。

    C-CAN 广播帧:可以直接进遥测的那部分

    下面这张表只收已经 allowlist 进遥测的信号。入选判据是「是否与同类 DID 做过定量化对照」,而不是看上去是否合理——这也是为什么同属 0x100 的扭矩字节还停在候选名单里。

    ID 字节 / 位 解码式 含义 验证强度
    0x2EF 帧存在性 无 点火 ON 门控 已验证;帧计数门控曾失败,存在性门控有效
    0x41A byte0 4.0 + raw × 0.05 V 系统电压 已验证,含驻车唤醒场景
    0x41D byte2 raw × 4 kPa 机油压力 与内部 DID 逐字节镜像,怠速 733/733 样本 R² 0.9998047
    0x2ED byte0 raw − 40 °C 冷却液温度 怠速 R² 接近 1.0,负载工况 1,351/1,356 样本
    0x0FC bytes0–1 BE u16 屏蔽低两位后除以 4 rpm 发动机转速 负载工况 1,351/1,356 样本 R² 0.9999794
    0x0F0 bytes3–4 高 11 位 右移 5 位后减 500 Nm 变速箱请求扭矩上限 236 样本 R² 0.99999986
    0x1F7 打包 17 位:byte0 bit0 加 bytes1–2 raw / 32 rpm 变速箱输出轴转速 低于 16 位边界 R² 0.99999578
    0x1F7 byte3 有符号 i8 0.375 × raw + 57 °C 变速箱油温 多次 RMSE 低于 0.89 °C,另含一次预热反例
    0x1F7 bytes4–5 BE u16 raw / 2 rpm 涡轮 / 输入轴转速 盲区复原 2,014 样本 R² 0.99996705
    0x101 byte0 bit0、byte1 左移 3 位、byte2 高 5 位 raw / 16 km/h 瞬时车速 由变速箱侧证据裁定为 /16,否决早期的 /32 候选
    0x0EE bytes0–1 BE u16 raw / 128 km/h 独立高分辨率车速 169 样本 R² 0.9990360
    0x5A0 byte3 / byte2 mph 与四舍五入后的 km/h ACC 设定车速 两字节在 1 km/h 内一致才允许发布
    0x0E0 byte0 raw mph 限速标志识别值 DLC 4、10 Hz,读数为 0 时不发布

    一处值得单独说明的工程约定:2026-07-19 的离线分析确认 0x101 的 bytes0–2 是瞬时车速,而不是旧笔记里写的里程累加器。两条日志分别给出 539,982 帧(约 99.998 Hz,原始值域 0–2153)和 224,137 帧,帧内 CRC-8/SAE-J1850 在 224,137 帧上全部匹配。0x0EE 独立跟踪同一物理量,回归关系约为 0x0EE_raw ≈ 8.0099 × speed_raw − 11.6,移动样本相关系数 0.9999919。两者 integrals 在另一条记录的差值为 0.007 km,证明的是彼此关系,不是物理量纲。

    被驳回的候选与还没闭环的边界

    这批记录的价值有一半来自「已经否掉什么」。下面四项在别的项目里很容易被当成常识采用,但在这里都有明确的驳回或降级理由。

    候选 结论 决定性证据
    0x1F4 byte4 高位 = 当前挡位 驳回 完整复核扫过 4,187,827 帧得到 42,574 对有效轴速比样本;开发段里 21,725 对取值为 7、6,548 对取值为 8,但两组中位数都是 0.699,而 OEM 八挡为 0.580
    B-CAN 0x760 = 整车里程 仅认可为中控本地副本 对 302 次内部里程应答,冻结公式为「十分之一公里值等于 10 倍被动原始值」;174 次邻近匹配 p95 误差 0 计数,但与仪表仍有约 11.6 mi 差
    0x417 bytes2–3 = 变速箱油温 驳回 两次独立盲驾都不支持该假设,最佳 R² 仅 0.44824 且斜率为负
    0x100 bytes0–1 = 实际扭矩 保留候选 2,014 样本盲区分段里 overrun 段 R² 仅 0.63031,不能当作实际扭矩发布

    里程那条还要多说一句:2026-08-30 的三总线行驶记录里,中控计数器在首个 25 分钟窗口增加 23.0 km(14.291537 mi),独立车速积分为 14.365140 mi,相差 0.512%;跨钥匙周期的第二次比对里,中控增加 116.817 mi、积分增加 116.511358 mi,相差 0.262%。这两组数字证明的是相对刻度,不是绝对基线。

    正面闭环的案例也有一个,就是机油寿命。在驻车、点火 ON、发动机 OFF 的条件下,向 PCM 发出一条固定 DLC 8 零填充请求 03 22 21 85 00 00 00 00,物理地址为 18DA10F1 → 18DAF110,收到正向应答 62 21 85 52,无符号字节换算后为 82%。这次读取没有会话切换、没有 TesterPresent、没有流控帧,C-CAN 发送计数仅从 127233 增加到 127234,三条总线的收发错误计数保持为零。存在 limits 的工程约定是:参数超出 0 到 100 时置为不可用,而不是裁剪成百分比。

    常见问题

    OEM 文档写明 CAN-B 是 50 kbit/s,为什么实际按 125 kbit/s 配置?

    因为那份文档使用的是另一套分支命名(C-1 到 C-8 与 BH),与诊断口的 CAN C/CH/IHS 命名体系并不对齐,其 50K 描述更可能指向另一条内部支路。2026-07-20 的被动捕获在引脚 3/11 上测得 125 kbit/s 且零 RX 错误,2026-07-25 的灰色适配器捕获又独立在引脚 12/13 上确认 500 kbit/s,两者都以实测作为配置依据。

    B-CAN 上的 0x760 里程值能不能替代仪表里程?

    不能。它与中控内部计数器的关系式已经冻结并复制过:十分之一公里值等于 10 倍被动原始值,174 次邻近匹配的 p95 误差为 0 计数、平均绝对误差 0.1724 计数;相对刻度也经两次独立检验,分别为 0.512% 与 0.262%。但它与仪表的绝对读数仍相差约 11.6 mi,因此只能当中控本地副本使用,不能据此摘掉仪表上的星标。

    为什么读取 PCM 机油寿命不需要切换诊断会话?

    2026-10-03 的实车验证显示,在驻车、点火 ON、发动机 OFF 条件下发出一条零填充请求,就拿到了正向应答 62 21 85 52。但这不能推广成「默认会话支持 22 读取」的普遍结论:继承会话没有被正面识别,且同一 PCM 的其他 DID 曾明确要求遗留会话。工程上的处理是沿无会话切换的配方发一次,被拒绝就上报需要会话并就此停止。

    0x1F4 的字节 4 高位能不能直接当成当前挡位?

    不能。2026-09-22 的两秒样本曾把它对上七挡比值 0.699,但完整复核扫过 4,187,827 帧、取到 42,574 对有效样本后,出现了大量比值稳定在 2.842、1.909、1.382 而该位仍为 7 的情形;开发段里取值为 8 的 6,548 对,中位数同样是 0.699 而不是八挡的 0.580。这些都是稳定工况下的反例,不是换挡瞬态。

    C-CAN 上出现 18DAF2xx 帧意味着什么?

    意味着那是网关把 CAN CH 上某个 ECU 的应答复制回 C-CAN 的副本,目标字节从 F1 改写为 F2,并不是第二个诊断仪在发话。转发延迟中位 0.31 ms,51 次交互落在 0.23–2.78 ms 区间,网关还会在 CAN CH 侧替换自己的流控帧。做被动归因时不要把它算成外部工具的流量。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/jakeiwen-promaster-2022/docs/bus-map.md(三条总线的速率、引脚与证据,16 个 UDS 端点,以及三条总线的广播帧表)
    • 项目 01 —— public-can-dbc-datasets/additional/jakeiwen-promaster-2022/findings/2026-07-19_ccan_drive_signal_analysis.md(0x101 与 0x0EE 车速字段的定位与两条日志的样本量)
    • 项目 01 —— public-can-dbc-datasets/additional/jakeiwen-promaster-2022/findings/2026-08-30_three_bus_drive_odometer_validation.md(中控里程与被动 0x760 的冻结公式及跨钥匙周期复制)
    • 项目 01 —— public-can-dbc-datasets/additional/jakeiwen-promaster-2022/findings/2026-09-22_gear_and_oil_life_offline.md(挡位候选驳回的完整复核数据与机油寿命闭环)

    免责声明

    本文所有波特率、引脚、CAN ID、字节位定义与转换系数均来自一台 2022 款 Ram ProMaster 的公开逆向记录,未经独立实车复现;不同年款、市场区域与 ECU 软件版本可能存在差异,标注为「已验证」的结论仅指在该车当时的捕获条件下成立。本文不构成对任何车辆执行主动诊断、刷写或执行器操作的授权,涉及安全相关用途请以实际测量与制造商资料为准。

    更新记录

    • 2026-10-15 初稿

  • 思域 FL5 的 25 个 DID 与 109 个信号:只读 UDS 请求流程

    结论:这份参考给出 25 个 UDS 服务 22 的 DID 与 109 个解码信号,来自同一辆 Civic Type R FL5(K20C1 2.0T,6 速手动)在 2026-09-08 至 2026-09-16 的八轮只读采集。第一件事不是数信号,而是承认它的形态:这辆车 OBD 口后面有网关,被动监听 24.8 分钟、59 万帧里 16 个 CAN ID 全是 18DAxxxx 诊断帧,广播帧数为 0。所以主键是「模块地址 + DID + 字节 / 位偏移」,不是 CAN ID。

    形态决定主键:为什么它不是一份 DBC

    钥匙 ON、怠速、行驶全程广播帧数都是 0,文档里每一个数字都是「主动问、ECU 答」得到的正应答字节。同一条物理通道上靠 29 位 ID 里的目标地址区分四个已解码 ECU(ECM、VSA、EPS、组合仪表)。

    因此 DBC 不适合作为主格式:DBC 描述周期广播帧的布局,而这里没有广播帧可描述。要机器读,应该用 data/signals.json 或 data/signals.csv,或者 OBDb signalsets/v3 兼容的 obdb-signalset.json——后者只收录「已确认(研究级)」与「中」两档,低置信与候选留在文档里不进 signalset。

    层 事实
    物理 OBD-II 口:6 脚 CAN-H、14 脚 CAN-L、4 脚 GND、16 脚 12 V 常电。6 / 14 按插进车的公头方向数,数反会得到 0 帧
    链路 经典 CAN 2.0B,500 kbit/s,单帧不超过 8 字节,无 CAN FD(12 份日志约 190 万帧,FD 帧计数 0)。只证明网关外的 OBD 侧
    寻址 29 位 ISO 15765 物理寻址:请求 18DA 加目标地址加 F1,应答 18DAF1 加目标地址;诊断仪地址固定 F1。点名全车用功能广播 18DB33F1。11 位 7E0 / 7E8 上 Mode 01 无任何应答
    传输 ISO 15765-2:请求单帧 03 22 DID高 DID低,用 0x55 填满 8 字节;应答 54 到 63 字节数据区 = 首帧 FF 加 8 到 9 个连续帧 CF。流控 30 00 00(填充 0xAA)必须在几毫秒内回,晚了 ECU 直接放弃
    应用 UDS 服务 22 ReadDataByIdentifier。本车默认会话免握手(不需要 10 03,更不需要 27);3E 保活实测不需要(600 s 连续采样零错误)。此条只在本车验证过
    偏移口径 offset 指去掉应答头 62 加 DID 两字节之后的数据偏移;[a:b] 不含 b;value = raw 乘 scale 加 add。默认大端,明确标注小端的除外

    时序与预算:单 ECU 串行上限约 33 Hz

    下表是主机侧观测值,不是 ECU 的硬限制。采集用的适配器无硬件时间戳,所以「VSA 80 ms」应读作首帧到末帧的整段,而不是帧间隔,也不能据此断定是 STmin 硬限制。

    模块 / DID 请求到完整 p50 p95 相邻 CF 间隔
    ECM 10:2610 24.9 / 27.4 ms 30.7 / 30.6 ms 约 2 ms
    ECM 10:2611 29.3 ms 33.5 ms 约 2 ms
    ECM 10:268F 27.3 ms 29.8 ms 约 2 ms
    VSA 28:4001/4004/4007/4073 约 100.1 ms 约 100.6 ms 约 10 ms
    EPS 30:48BD/48C0/48C4 约 67.9 ms 约 69 ms 约 8 ms

    串行模型是成立的:2051 轮逐轮恒等式「周期 = 各请求到完整之和 + 各间隙之和」残差为 0,轮间开销 1.48 ms/轮,由此得到单 ECU 串行上限约 1 秒除以 30.5 ms,即约 33 Hz(仅 ECM)。跨模块并发在协议上允许(不同地址各挂一个未完成请求),本车从未验证;按模块求和再取最大的理想周期只比串行快约 28%,不是 100 ms。作为对照,原厂调校工具自己轮询 22 2610 与 22 2611 各 18.13 Hz。

    NRC 含义 本车观察
    0x31 requestOutOfRange(该 DID 不存在) 扫描时的主力否定应答,全归档最常见
    0x11 serviceNotSupported 服务 21(五个模块各 256 个 LID)与服务 24 全部返回它,本车不支持,不必再试
    0x22 conditionsNotCorrect 有处理逻辑;扫描中零星出现
    0x78 requestCorrectlyReceived-ResponsePending 有处理(最多 5 乘 timeout);全归档统计里不计入否定应答
    0x80 厂商自定义 / 未列入标准表 第二轮扫 ECM 时出现过一次

    两条吃了亏才写下的采集纪律

    其一,一笔请求超时会触发对该地址的隔离,所以采样组的第一笔要放最稳的 DID。其二,行驶中不要把扫描和核心采样混在一条串行链上——边行驶边扫描的一份日志里核心采样最长断流 7.891 s,而纯核心采样的另一份最长只有 1.244 s。

    模块清单与扫描覆盖

    零件号由 22 F181 或 22 F110 读出,是同款车共有的零件号,不是单车序列号;数据集不含 VIN、ECU 序列号或任何单车唯一标识。功能广播点名时,公开信号集里有而本车无应答的地址有 0x2A、0x0E、0x11、0x1D、0x01、0x15、0x16。

    地址 身份 零件号 扫描覆盖 有正应答 DID 收录 状态
    0x10 ECM/PCM 发动机控制 37805-66V-H020 0000–FFFF 全段 77 个(26xx 52 + 30xx 5 + DC59–FFFF 段 20) 10 个 扫描中 6F2B / 6F8A / DC58 三个单点无应答触发隔离,未复读
    0x28 VSA 车身稳定(ABS/ESC) 57114-T60-AA20 0000–A082 31 个(4000–400A、4030–403B、4070–4073、0EEC、4100、48AF、48F5) 5 个 A083–FFFF 未扫
    0x30 EPS 电动转向助力 39990-T60-J030 0000–7EEB 20 个(全在 48xx) 5 个 重扫 0000–2A30 无新增;2A31–FFFF 待续
    0x3A ADS 自适应减振 39390-31M-A040 0000–FFFF 全段 16 个(48AF、48F5、52xx、5280/5281、E600、E602、F1xx) 0 个 10 个数据类里 9 个逐字节恒定,唯一在动的 520A 未解码
    0x53 SRS 气囊 77959-T60-H830 未扫 — 0 个 故意不碰
    0x60 组合仪表 78108-T60-H020 7000–70FF 18 个(有数据的 6 个) 5 个 其余段未扫
    0x70 未知(33137 系,疑似大灯控制) 33137T24Y112M1 未扫 — 0 个 功能广播点名有应答
    0xB0 多用途摄像头(Honda Sensing) 36161-T60-H050 0000–00C5 0 0 个 对服务 22 基本不配合,两次都在 00xx 某个 DID 超时被隔离;已放弃
    0xB3 Honda Sensing 子单元 36162-T51-H010 未扫 — 0 个 功能广播点名有应答
    0xB7 驻车雷达控制单元 39670T60E010M1 未扫 — 0 个 功能广播点名有应答
    0xED 车身控制 / 网关之一(38898 系) 38898-T60-H010 未扫 — 0 个 与 EF 成对
    0xEF 网关 / 车身控制之一(38897 系) 38897-T60-H010 未扫 — 0 个 功能广播时它最先应答,疑似网关

    信号总表摘录

    四个模块、25 个 DID、109 个信号,置信度分布为已确认(研究级)52、中 39、低 / 候选 18。文档不升不降任何一条的置信度。下面摘录 ECM 两个主包与几个跨模块的对照项;「实测范围」是全部采集里出现过的最小 / 最大值与样本数,只说明观察到过什么,不定义量程也不定义报警阈值。

    模块 : DID 信号 偏移 解码 单位 实测范围(样本数) 置信
    10:2610 ENGINE_RPM 6(2 B 大端) raw 乘 0.25 rpm 0 到 5300(53,908) 已确认(研究级)
    10:2610 MAP_ABS 9(2 B 大端) raw 乘 0.0078125 kPa 22.27 到 282.35(53,908) 已确认(研究级)
    10:2610 ECT 11(1 B) raw 减 40 摄氏度 33 到 90(53,908) 已确认(研究级)
    10:2610 VEHICLE_SPEED 18(1 B) raw km/h 0 到 137(53,908) 已确认(研究级)
    10:2610 BATTERY_V 22(1 B) raw 乘 0.1 V 6 到 14.6(53,908) 已确认(研究级)
    10:2610 OIL_PRESSURE 44(2 B 大端) raw kPa 0 到 626(53,908) 已确认(研究级)
    10:2611 LAMBDA 8(2 B 大端) raw 乘 3.0517578e-05 lambda 0.765 到 2.000(42,797) 已确认(研究级)
    10:2611 SHORT_TRIM 10(1 B) raw 乘 0.78125 减 100 % -10.16 到 17.97(42,797) 已确认(研究级)
    10:2611 GEAR 19(1 B) raw gear 0 到 6(42,797) 已确认(研究级)
    10:2611 PEDAL 20(2 B 大端) raw 乘 0.005 % 0 到 60.83(42,797) 已确认(研究级)
    10:2611 BOOST_PRESSURE 24(2 B 大端) raw 乘 0.013157894736842105 kPa 绝压 94.51 到 215.08(42,797) 已确认(研究级)
    10:2611 WASTEGATE 28(2 B 大端,有符号) raw 乘 0.001 mm(未证实) -0.176 到 8.412(42,797) 已确认(研究级)
    10:268F OIL_TEMP_MODEL 15(1 B) raw 减 40 摄氏度 32 到 82(20,684) 已确认(研究级)
    28:4005 BRAKE_PRESSURE 7(2 B 大端) raw 减 25 bar 0 到 106(4,840) 已确认(研究级)
    28:4007 REVERSE_GEAR 11(bit 1,掩码 0x2) raw 与 0x2 bool 0 到 2(3,515) 已确认(研究级)
    28:4007 CLUTCH_PEDAL 24(1 B) raw % 0 到 100(3,515) 已确认(研究级)
    30:48BD STEER_ANGLE 11(2 B 大端,有符号) raw 乘 0.1 deg -405.6 到 408.1(5,164) 中
    30:48C4 WHEEL_SPEED_FL 23(2 B 大端) raw 乘 0.01 km/h 0 到 115.23(3,193) 已确认(研究级)
    60:7022 ODOMETER_CLUSTER 6(3 B 大端) raw km 不公开(1,394) 已确认(研究级)
    60:7028 AMBIENT_TEMP 17(1 B) raw 摄氏度 26 到 34(2,059) 已确认(研究级)
    60:7029 FUEL_LEVEL 12(2 B 大端) raw 乘 0.01 L 16.46 到 43.88(1,393) 已确认(研究级)

    三条容易读错的约定

    同名信号出现在两个 DID 时(VEHICLE_SPEED_COPY、STEER_ANGLE_COPY),是两个不同位置的独立字段,解码与置信度各按所在 DID 读。标 kPa_abs 的是绝压;要增压表压请用同一应答包内的 MAP_ABS 减 BARO(同包相减,不要减 101.325 这类常数)。带掩码的位字段在「实测范围」列显示的是掩码后的原始值,例如掩码 0x8 的置位状态显示为 8,而不是 1。

    证据边界:未映射的变化字节与不可辨识项

    已映射的 25 个 DID 里还有 206 个未映射的变化字节、1,183 个位,其中在单次采集内部就会变的有 189 字节、1,124 位——由位级覆盖分析从全部采集算出。其中 4 个字节里「未映射位」与「已映射位」同处一室,按整字节做候选筛选的工具看不到它们。

    类型 位置 现状 缺什么
    未映射 10:2610 [8] 与 [27] 完全相同,燃压低字节镜像 未命名,仅登记
    未映射 10:2610 [16] 日志内变化,只有低 4 位(掩码 0x0F),5 种取值,与水温 r 约 -0.77 位域身份未定
    未映射 10:2610 [51] 0 到 240 阶梯,步长约 7.5 未扫,性质未知
    未映射 10:2611 [53:55] / [55:57] ECM 内部短时负向修正量,值域 -53 到 0;位宽不可辨识(该值域内 s8 与 s16 小端恒等);两者是单向包含关系 需要一个绝对值大于 127 的样本才能分开
    未映射 10:268F [12] / [13] / [14] 带 255 端点码;[12] 与转速的关系在差分与配对两道检验下都存活(r = 0.21 / 0.256),是 50 个候选里唯一存活的 不命名
    未映射 3A:520A 整包 64 B ADS 唯一在动的数据包,未解码;多字节字段候选 3 个(10:12、36:38、38:40,均大端) 整包未扫
    不可辨识 偏航率刻度 0.0045(运动学模型)对 0.003924(后轮差速几何法) 需外部偏航率参考(不低于 10 Hz、误差小于 3%)或实测轮距与滚动周长
    不可辨识 2610[39] 的门限 单一压力门限与 Schmitt 迟滞均已推翻;转速 / 档位分层使留出集 log-loss 改善 17 到 18% 未过 20% 门槛,判不出,不是无效应
    不可辨识 AIRC_MAX / AIRC_PROT / AIRC_COMP 三个字节 [49] / [57] / [58] 全程相等 三个名字在现有数据里无法区分
    不可辨识 扫描期链路停摆的机制 现象强相关;单 ECU 忙已排除,网关限流 / ISO-TP 异常 / 工具实现 / 静默超时四种都证据不足 缺适配器状态遥测,分不开「工具阻塞」与「总线 / 网关静默」

    常见问题

    这份参考能直接转成 DBC 吗?

    不能,也不该转。DBC 描述的是周期广播帧的布局,而这辆车的 OBD 侧广播帧数为 0,全部数据来自服务 22 的问答。主键是模块地址加 DID 加字节 / 位偏移,同一条物理通道上靠 29 位 ID 里的目标地址区分四个已解码 ECU。要机器读请用 signals.json、signals.csv 或 OBDb 兼容的 signalset。

    为什么按 7E0 / 7E8 发 Mode 01 收不到任何东西?

    因为这辆车走 29 位物理寻址:请求是 18DA 加目标地址加 F1,应答是 18DAF1 加目标地址,诊断仪地址固定 F1;11 位地址上 Mode 01 全程零应答。另一个常见失误是引脚数反了——6 脚 CAN-H、14 脚 CAN-L 要按插进车的公头方向数,数反了同样得到 0 帧。

    轮询频率能开到多高?

    串行模型下约 33 Hz(仅 ECM),由 1 秒除以单事务约 30.5 ms 得出,轮间开销 1.48 ms/轮,2051 轮恒等式残差为 0。跨模块并发在协议上允许但本车从未验证,理想化估算只比串行快约 28%。作为对照,原厂调校工具自己只跑 18.13 Hz。

    为什么两条里程信号不给出实测范围?

    因为精确里程读数能定位到具体某一辆车,作者主动不公开。样本数照常给出:ECM 的 ODOMETER 是 365 个样本,仪表的 ODOMETER_CLUSTER 是 1,394 个,两条相互核对一致且单位都是 km(公开信号集里写成英里是错的)。

    「已确认(研究级)」是不是等于已经标定过?

    不等于。它只表示这一辆车上证据强——与独立仪表逐点对上、或与调校工具的未取整导出逐列拟合到 r 约等于 1、或有干净的前后对照动作。它不代表已用独立仪器标定,也不代表在原厂车上成立。这辆车装有调校工具,ECU 已解锁,市场版本也未确认。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/caldis-honda-civic-fl5-dids/SOURCE.md(固定修订、许可条款、25 DID / 109 信号的范围与限制)
    • 项目 01 —— public-can-dbc-datasets/additional/caldis-honda-civic-fl5-dids/README.zh-CN.md(分层事实、逐事务耗时、NRC、模块扫描覆盖与信号总表)
    • 项目 01 —— public-can-dbc-datasets/additional/caldis-honda-civic-fl5-dids/README.md(英文版信号总表与已推翻说法)
    • 项目 01 —— public-can-dbc-datasets/additional/caldis-honda-civic-fl5-dids/CHANGELOG.md(数据版本 1.0.0 与 1.0.1 的变更记录)

    免责声明

    本文所述 DID 与信号均为社区只读诊断所得,不代表本田的官方数据,全部来自同一辆装有调校工具(ECU 已解锁)的 Civic Type R FL5,年款与市场版本均未确认。采集与本文档制作全程只使用服务 22 及配套只读服务,不含任何刷写、安全访问或内存读取内容;被明确排除且不得据本文尝试的服务包括 27、23、2E、31、11、14 与 34 到 37。把这里任何一条用在别的车上之前请自行复核。涉及安全相关用途时请仅作参考。

    更新记录

    • 2026-10-15 初稿

  • Indian Springfield 2017 的解码计划:八个未解字节与请求墙

    结论:这份解码计划的证据底是 42,365 帧,来自 2026-08-15 一个下午的四份抓包;总线上 30 个 PGN 分四组——已发货 20、传输层 4、已理解但故意不发 1、真未知 5。收尾状态可以一句话说完:剩下「八个单字节、四个毫无变化的 PGN,以及一切需要主动请求的东西」。它没有 DBC,靠的是硬件只听模式加受控动作。

    总账:42,365 帧是变化数,不是发送数

    这是读这份计划前必须先接受的一条限制。固件只在某个 ID 的载荷与上一帧不同时才发布该帧(updateTable() 仅靠 memcmp 置脏标志),抓包工具记录的正是这条流。所以文件里每个「帧数」都是变化次数,不是发送次数。由此有三件事不成立,而每一件看起来都很像成立:

    • 推导不出报文速率。PGN 65381 在四次骑行里的 299 条记录说明它变了 299 次,不说明它慢。
    • 分不开周期性与事件驱动。两者在去重之后长得一模一样。
    • 滞后与相关是在不规则采样上算的。油门那条结论扛住了这一点——它有标准和手册双重印证——但这样找到的临界相关比看上去要弱。

    不过「跨 N 条记录恒定」仍然是有效陈述:它在每一次看到该报文变化时都确实保持了那个值,只是它不是关于 N 次发送的陈述。

    谁在总线上:地址声明比流量猜测可靠

    每个模块都在 PGN 60928 上用 64 位 J1939 NAME 宣布自己是谁:制造商、功能、实例。这些声明自 2026-08-15 起就在抓包里了,但模块地图此前有整整三周是靠流量猜的。这张表可信,是因为有两条自己会互相检验:SA 0 声明 Engine 并发送发动机数据;SA 23 声明仪表并发送里程、小计和外温。两次「说是什么」与「做什么」的独立吻合,才让功能 30 对 SA 39 也说得通。

    SA 声明次数 制造商代码 功能 原本靠流量猜的
    0 4 51 Engine(发动机) ECU ✓
    11 4 7 不在标准表里 ABS
    23 4 340 Instrument cluster(组合仪表) 组合仪表 ✓
    39 4 449 Management computer(管理计算机) 「VCU、车身」✓ 大意对
    136 8 146 Instrument cluster(组合仪表) 「声明了地址然后一句话不说」

    SA 136 是这一节的发现:它声明了与仪表相同的功能(19)却来自另一个制造商(146 对仪表的 340),而且从没发过别的任何东西。它还比谁都声明得勤——四次骑行共八次,其它模块每份抓包只有一次。一个通电、比谁都执着地自报家门、然后毫无贡献的模块不是坏模块,它更像是「显示类已装设备,而这辆车不给它活干」。

    另外 SA 11 的 NAME 解码不出来,这件事本身就值一行:它给出功能 194、车辆系统 78、行业组 7。行业组是三位,7 未使用;车辆系统 78 超出任何组的范围。反转字节序得到功能 255「not available」,这至少是一种合法的「拒绝声明」——但只反转这一个模块而不反转另外四个,是假设不是发现。记为异常,不解释掉。

    仍开放的字节:八个单字节与四个沉默 PGN

    下表汇自「仍开放」一节与逐字节清单,零基字节编号与代码一致。「标准怎么说」一列引用标准,标准从 1 计数,少数较老的注释也照此。

    PGN SA byte 取值 / 范围 已知 怎么验
    65382 0 0 255 个取值 / 4,721 帧 一个活的发动机量,负荷、点火提前角与喷油脉宽是候选。这是总线上最忙的未查字节,也是探针最后还在追的东西 开着巡航定速跑:稳住油门、改变负荷,看它跟负荷还是跟手
    65265 0 3,bit 0-1 取 0 和 1 开放线索,2026-10-04。位于标准给 SPN 595「巡航激活」的位置,且在八月抓包里会动 在下一次用到巡航的骑行里,把该值与派生出的 hold 一起记下来比对
    61444 0 7 75 / 103 到 185 标准里发动机需求扭矩(SPN 2432,偏移 -125)的位置。只读来打印,未发布 它应当跟随油门,并在油门松开瞬间转负
    65215 11 4 88 / 39 到 220 与车速 r = +0.84,偏移 125 = 零。若刻度成立,这是来自 ABS 模块的后轮速度——第三个速度源 一段已知急加速的抓包
    65265 11 0 2 / 63 到 127 标准:驻车制动 / 双速轴 / 巡航暂停,均为两位字段 一次受控测试
    61441 11 5 3 / 204 到 220 0xCC、0xCD、0xDC——与巡航开关字节相同的三个值,可能是镜像 停车按十分钟 SET 与 RESUME
    65265 0 6 2 / 240 到 241 241 出现在除六条之外的全部记录;240 出现过两次各约一秒 未知,价值低
    61445 39 4 2 / 32 到 83 标准 ETC2 字节 5 的变速箱字段;Indian 在此 PGN 已偏离标准(档位以 ASCII 编码放在字节 6) 未知,价值低
    65387 0 全部 无变化 钥匙开时发一次,作为对 SA 23 请求的应答 一段能触发新东西的抓包
    65388 23 全部 无变化 每次钥匙开时发一次,不是周期性的 同上
    65393 23, 39 全部 无变化(8 + 4 条记录) — 同上
    56832 23 全部 无变化(5 条记录) — 同上

    PGN 65382 的其余部分已经交出来了:字节 1 是转速除以 256(被撤回的「油门」),字节 3-4 是仪表显示的续航里程——十六位小端,字节 3 低、字节 4 高,一计数一公里,无缩放无偏移。所以 Indian 对发动机怎么运转还留着什么私货,最可能就在字节 0 里。

    一个仍未关掉的问题:油门字节有两个静止值

    PGN 65266 SA 0 字节 7(SPN 51)的解码本身已经定了,刻度也对:raw 250 恰好是 100.0%,正是 J1939 单字节百分比量程的顶端,全油门正落在上面。没定的是没人碰油门时阀片停在哪。车库里九小时、发动机从未启动的那一轮自己就证明了传感器只要点火开着就会报数——这个字节有 153 次变化。

    状态 中位数 最大
    发动机停转,低于 50 rpm 5.6% 到 6.0% —
    怠速,50 到 1200 rpm 4.4% 到 4.8% 12%
    骑行,高于 1200 rpm 9.6% 到 11.2% 100%

    停放着的机器读约 6%,这是阀片坐在怠速限位上而不是完全关闭,符合预期。不符合预期的是:同一天里这个字节还去过 0 到 1.6%,共二十六次,与正常的 4.0 到 4.8% 读数整天交替出现——不是另一次会话,两个簇在交替。发动机停着没人骑,阀片应该待在一个地方。候选有三个,都没测:回位弹簧没每次都把阀片留在同一位置;点火周期内传感器或 ECU 在首次真实读数前短暂报零;或者有别的东西在熄火状态下推动阀片,比如怠速执行器自检。

    已识别但故意不发货,以及确认不在总线上

    下面这些是已经看懂的,列出来是为了不让别人把它们当成未知,或者第二次去解它。

    PGN SA byte 它是什么 为什么不给字段
    65254 39 1, 2 时钟:分、时 快 12 小时 07 分,且不是显示屏上的那个钟
    65381 39 1,bit 2 / 4 / 6 转向灯开关左 / 右 / 取消,拨杆动作期间的一次短脉冲 灯本身已经从 65089 发货
    65386 39 1,bit 0 远光激活,全程保持 headlight 已经从 65381 取
    65276 23 1 组合仪表自己的油量读数 为了确定性选了 SA 0
    65265 39 6, 7 报文计数与校验和(SPN 524079) 不是信号
    65382 0 1 转速除以 256 —— 被撤回的油门 rpm 的粗副本
    65390 39 0 唤醒时的 DF 对 FF,同秒还有另外 8 个 PGN 在动 唤醒突发;总线活过来这件事本身说得更好

    「不在总线上」这一节有严格的入会条件:该信号必须在采集时被实际操作过且仍未出现。仅仅是「在它本来就不可能出现的数据里没出现」的,只能算未测。

    在总线上 不在总线上
    车速、档位、转速、胎压 喇叭
    灯、转向、危险警告 边箱锁
    刹车、巡航、加热手把 风挡电机(此地未装)
    倾斜、油量、温度 Trip 2

    规律是:这条总线承载的是别家模块需要的状态,不是便利性的作动。喇叭和边箱锁是「开关进模块、模块驱动自己的输出」,整条链路都在一个模块内部,没什么需要告诉别人。这也是为什么维修手册里 FMI 9「Abnormal Update Rate」格外有用。

    怎么读标准:FMI 9 是制造商的自白

    DTC 表列出部件、失效模式(FMI)与代码。多数失效模式描述的是一根线:开路、短路到 B+、电压过低。但 FMI 9 不一样。一个模块只有在「它期待某个信号周期性从别处来」的前提下,才可能抱怨这个信号来得太慢——在这台机器上,那个「别处」就是 CAN。所以每一条 FMI 9 都是制造商承认某信号被广播。整本手册里一共只有七条。

    SPN 信号 代码 本地状态
    84 Vehicle Speed Signal P160A 已发货 —— PGN 65265
    523 Gear Sensor Signal P1914 已发货 —— PGN 61445,也是档位突变日志的对象
    5582 Static Roll Angle P1062 已发货 —— 几乎可以确定就是 PGN 2304 的倾斜字节
    520300 Tire Pressure Sensor (Front) C1085 已发货 —— PGN 65268
    520302 Tire Pressure Sensor (Rear) C1090 已发货 —— PGN 65268
    520329 Operator Switch Status(pOSS1) P1063 部分回答:PGN 65381 的字节 1 位 2/4/6 是转向灯与取消,字节 2 位 0 是危险警告;2026-09-18 又发现字节 0 的两颗手把按键。但报文是专有的,无法证明它就是标准参数
    520330 Immobilizer P106A 已找到并发货 —— PGN 65386 SA 39 字节 0 位 6-7

    其中 SPN 5582 是一次安静的确认:倾斜值是先从 PGN 2304 里经验性地找到、并因看起来像而命名为「tilt」的,手册叫它 Static Roll Angle,来源是 SPN 520296「Accelerometer」。信号是真的,按设计就在总线上,我们读它这件事有了一个名字。

    手册还有两条限制要记住。其一,手册覆盖七款车而不是这一辆,DTC 表是七款的并集——SPN 520294/520295「Windshield Motor Driver / Switch」是 Chieftain 与 Roadmaster 的部件,Springfield 的挡风玻璃是快拆手动的;先确认车上有没有这个件再去追它的信号。其二,诊断码只能证明模块「知道」某个信号,不能证明它把它广播出来:前刹车开关是 SPN 520322、后刹车是 520323,两个都真实且有名有姓,但它们是一根根线进模块的,模块之后有没有把它们放上总线,是手册不回答的另一个问题。巡航那一节正是栽在这条上——出现在表里不等于出现在线上。

    常见问题

    这份计划有没有 DBC?

    没有。上游没有 DBC,这份材料是一份站得住的优先级清单加方法记录。它给出的是 PGN、源地址、字节位置、实测取值范围、已试过的动作和被推翻的假设,要落成 DBC 还得自己把每条信号按同样的受控动作再走一遍。

    42,365 帧能不能换算成报文速率?

    不能。固件只在某个 ID 的载荷与上一帧不同时才发布该帧,抓包记录的正是这条变化流。所以「帧数」是变化次数而不是发送次数:推导不出报文速率,也分不开周期性与事件驱动。唯一仍然成立的是「跨 N 条记录恒定」,但它不是关于 N 次发送的陈述。

    巡航「已接合」状态到底能不能读到?

    从 SA 39 读不到。2026-09-05 路试中巡航确实在保持(94、87、73 km/h,手离开手把),其 CCVS 字节 4 恒为 0xF7,位 0-1 始终是 11;设定车速字节在所有 SA 39 帧里恒为 0xFF。于是固件派生了一个 `cruise`:一次 SET 或 RESUME 按下配合摇臂开且不低于 35 km/h 进入待定,三秒内车速稳定在 3 km/h 以内确认;刹车、离合、摇臂关闭或偏离目标超过 6 km/h 持续两秒退出。取值写 HOLDING 而不是 ON,用一个词把「这是推断」标在数据里。

    SA 136 是什么?

    它声明了与组合仪表相同的功能(19)但不同的制造商代码(146,仪表是 340),而且在 42,365 帧里除了自己的地址声明之外什么都没发过;声明次数还是别人的两倍(四次骑行共 8 次)。最可能是边箱锁模块——Polaris 车身侧锁模块的描述正是「点火时声明地址,之后只在锁 / 解锁时发送」。前半句完全吻合,后半句被测量推翻:三次运行、每个字节都可见、执行器确实在动作,SA 136 一个字节都没发。要直接点名,需要查一下制造商代码 146。

    「不在总线上」和「未测」怎么区分?

    进入「不在总线上」需要该信号在采集时被实际操作过且仍未出现;仅仅在「它本来就不可能出现的数据里没出现」的,只能算未测。巡航条目就踩过这个坑:字节一直读 not available,但那四次骑行里巡航从来没接合过,所以那一节原本没有资格收录;直到 2026-09-05 的路试才把它坐实为 SA 39 一家的确认缺失,而不是整条总线的结论。

    延伸阅读

    参考资料

    • 项目 01 —— public-can-dbc-datasets/additional/prinsessen-indian-springfield-2017/docs/DECODE-PLAN.md(30 个 PGN 分组、地址声明、仍开放清单与优先级表)
    • 项目 01 —— public-can-dbc-datasets/additional/prinsessen-indian-springfield-2017/docs/UNEXPLORED-BYTES.md(逐字节实测取值范围、油门双静止值与请求墙说明)
    • 项目 01 —— public-can-dbc-datasets/additional/prinsessen-indian-springfield-2017/README.md(车辆与适用车型范围、不在总线上的确认清单与胎压换算方法)
    • 项目 01 —— public-can-dbc-datasets/additional/prinsessen-indian-springfield-2017/SOURCE.md(固定修订、许可条款与范围限制)

    免责声明

    本文所述信号定义均为社区逆向工程产物,不代表车辆制造商的官方数据,且全部来自一辆 2017 Indian Springfield。手册覆盖的 Chief、Dark Horse、Vintage、Chieftain、Roadmaster、Elite 六款未直接测量,跨车型推断的依据是车主对车系的了解而非实测;Scout 与 FTR 是另一台发动机,不在范围内。固件运行在硬件只听模式,不发送任何帧,因此 DM2、DM4 等按需应答的数据不可能出现在现有抓包里。文中代码路径与候选字段不构成厂商规范。涉及安全相关用途时请仅作参考。

    更新记录

    • 2026-10-15 初稿