车联网 CAN Bus 协议介绍与数据实时流处理
什么是 CAN Bus?
CAN(Control Area Network)Bus 是一种串行通信协议,能够让设备之间可靠而高效地传输数据。它广泛应用于车辆领域,像神经系统一样连接车辆内部的各个电子控制单元。
CAN Bus 最初由博世公司在 20 世纪 80 年代为汽车应用而设计。它是一种多主、多从、半双工、具有容错能力的协议,非常适合汽车领域的需求。它简单、低成本、可靠,能够在恶劣的环境中工作。CAN Bus 为车辆中所有电子控制单元提供了一个统一的接入点,方便进行连接和诊断。
CAN Bus 数据能够反映连接设备的性能和状态。然而,由于数据量大、带宽有限以及网络不稳定等因素,收集和处理 CAN Bus 数据可能面临一些挑战。
为了应对这些挑战,可以利用 MQTT 协议,确保在网络状况不佳的情况下及时将车辆数据传输到云端。EMQX 是一款开源的 MQTT Broker,能够搭建可靠且可扩展的 MQTT 基础设施,用来收集 CAN Bus 数据。
CAN Bus 的发展简史
CAN Bus 由德国跨国工程技术巨头博世在 20 世纪 80 年代初开发,旨在为汽车应用提供一种高效的通信系统,主要目的是简化车辆内部线束的复杂程度。
1986 年,博世发布了首个 CAN 协议,由于其可靠性和健壮性,很快受到了汽车制造商的青睐。1993 年,它成为 ISO-11898 国际标准。该协议演进过程大致如下:
- 1991 年:梅赛德斯-奔驰在其 W140 S 级车型中采用了 CAN Bus ,成为最早采用 CAN Bus 的汽车制造商之一。
- 2004 年:推出了 CAN FD,相比传统 CAN 网络,提供了更高的数据速率和更大的有效载荷。
- 2015 年:使用 ISO-16845:2015 作为一致性测试的测试方案,用于对实现了经典 CAN 以及 CAN FD 协议的设备进行一致性测试。
除了汽车领域外,CAN Bus 协议还逐渐应用于其它行业,例如工业自动化系统(CANopen)和船用电子设备(NMEA 2000)。它的广泛应用主要得益于它能够在恶劣的条件下稳定运行,并且实施成本较低。
CAN Bus 的工作原理
CAN Bus 是一种分布式的通信协议。它的分布式特点使它非常适合对可靠性和实时性有较高要求的应用,如汽车和工业系统。
在 CAN 网络中,所有的节点都通过双绞线或光纤相连。每个节点都有自己的微控制器,负责处理收到的消息和发送的消息。数据由节点在共享总线上广播,所有其它节点都能收到。通信过程的几个关键阶段包括:
- 仲裁:为了避免多个节点同时发送数据产生冲突,CAN 采用了一种基于消息优先级的仲裁过程。消息的标识符值越小,优先级越高。
- 错误检测:内置的错误检测机制保证了 CAN 网络中数据的完整性。这些机制包括循环冗余校验(CRC)、帧校验序列(FCS)以及接收节点确认位。
- 故障界定:如果节点在传输过程中检测到错误或故障,它会进入“被动错误”状态,直到问题解决。这种机制可以防止故障对整个系统功能造成干扰。
这些特性相互配合,使得 CAN Bus 能够高效运行,确保车辆或工厂自动化设备等复杂系统中各个组件之间的可靠通信。
CAN 协议的消息结构
在 CAN Bus 系统中,消息结构对于设备间的高效通信非常重要。该协议的数据帧格式由以下几个字段组成:标识符、控制字段、数据字段和错误检测机制。
- 标识符 (CAN ID):这是一个唯一的值,用于确定网络上每条消息的优先级。标准的 11 位标识符(CAN 2.0A)提供了多达 2048 种不同的优先级。扩展的 29 位标识符(CAN 2.0B)提供了更多的选择,有超过五亿个优先级。
- 数据长度码(DLC):位于控制字段中,用于指定数据字段所包含的字节数,取值范围 0 - 8 个字节。
- 数据字段:包含了实际要在节点间传输的信息,以字节为单位。
- 循环冗余校验(CRC):一种内置的错误检测机制,通过检测传输错误并在必要时请求重传来保证通信的可靠性。
- 确认槽:一个单独的位,用于接收节点向发送节点发送确认信息,表示成功接收消息或需要进行错误重传。
- 错误帧:CAN 消息的一个可选部分,用于节点在检测到自己发送或者接收到的消息有问题时发出信号。
CAN 的种类
CAN 主要包括三种类型:
低速 CAN
低速 CAN,也叫做容错 CAN 或 ISO 11898-3,最高传输速度为 125 kbps。它适用于像车身控制模块、门锁、窗户控制等不太重要的系统,这些系统对数据传输速度的要求不高。它的主要特点是即使总线中的一根线断了,也能继续正常工作。
高速 CAN
高速 CAN,或 ISO 11898-2,传输速度最高可达 1 Mbps。因为它比低速网络有更快的数据传输速度,因此适合需要及时响应的应用,如发动机管理系统和电子制动系统。但是,它没有低速网络的容错能力。
CAN FD
CAN FD 由博世在 2012 年推出,是高速网络的扩展版,具有更高的数据传输速度,最高可达 5 Mbps,同时向后兼容现有高速设备。这项技术的主要优势在于它比传统的 CAN 能更有效地传输更大的载荷,使其非常适合现代车辆日益复杂的电子系统。
CAN Bus 的优势和挑战
CAN Bus 有哪些主要优势?
CAN Bus 数据可以反映车辆的性能、健康状况和行为特征。把 CAN Bus 数据收集到云端是一种利用车辆数据潜力的有效方法,可以通过大数据分析来发现数据价值。通过将机器学习、人工智能或其它分析工具应用于从车辆收集的大量数据,车辆制造商可以获得有价值的信息,并利用它们优化车辆性能。
- 检测、消除、预测故障:通过分析 CAN Bus 数据,可以识别设备和传感器发出的异常或错误信号。这有助于诊断问题的根本原因,并在它导致更大损失或带来安全问题之前修复它。制造商还可以利用收集的数据来训练机器学习模型,从而实现故障的预测。
- 可视化车辆数据:用户可以利用收集的数据构建一个系统,将综合数据展示在仪表板上,实现对不同车辆和指标的过滤、排序和比较。该仪表板还能基于数据分析提供警报和建议,帮助用户全面了解性能情况。
- 车路协同:将收集的数据与道路基础设施数据结合,可以建立车路协同系统。
在人工智能时代,数据是最有价值的资产。通过将车辆的数据收集到云端,然后将其分发到各种数据基础设施,如数据库和数据湖,用户可以利用数据实现各种类型的应用。
实时数据收集面临哪些挑战?
尽管在车辆本地收集 CAN Bus 数据已经相当成熟,但由于高数据速率、低带宽和不稳定的网络环境,导致收集、处理和实时传输 CAN Bus 数据到云端面临着巨大的挑战。将所有 CAN Bus 数据都传输到云端进行处理是不切实际的。所以,可以在边缘端本地收集和处理 CAN Bus 数据,以减少数据量,然后将处理结果实时传输到云端。
我们至少需要两个组件来构建这样的解决方案:
- 边缘计算引擎:边缘计算引擎可以只收集所需的 CAN Bus 信号,灵活地处理它们,并实时触发 MQTT 传输动作。LF Edge eKuiper 是一款开源的边缘计算引擎,可以帮助您实时处理和分析 CAN Bus 数据。
- 云端的 MQTT Broker:利用 MQTT Broker,可以实现将处理过的 CAN Bus 数据实时传输到云端。EMQX 是一款开源的 MQTT Broker,能够搭建可靠且可扩展的 MQTT 基础设施,用来收集 CAN Bus 数据。
接下来,我们将详细介绍结合 EMQX 和 eKuiper 的整体解决方案。
解决 CAN Bus 数据本地处理挑战
eKuiper 是一款开源的边缘计算引擎,可以帮助您实时处理和分析 CAN Bus 数据。eKuiper 是为边缘流处理而设计的,适合对 CAN Bus 产生的典型流数据进行实时处理。eKuiper 可以应对以下挑战:
- 具备高效实时处理 CAN Bus 大容量、高速度数据的能力。能够灵活过滤、处理和选择感兴趣的信号,从而降低传输数据所需的带宽。
- 能够将二进制的 CAN 帧解析为有意义的信号,以进行规则处理和触发动作。它支持动态加载 DBC 文件,使用户能够灵活地更改 DBC 文件,无需重启引擎即可适配不同的 CAN Bus 设备。同时,它还确保 DBC 文件的私密性和安全性,无需暴露给开发团队。
- 能够灵活地组合来自不同 CAN 帧的信号,可以通过规则构建完整的消息供应用程序使用。用户还可以自由地修改规则,以适应不同的用户场景或需求变化,并支持热加载。
教程:使用 eKuiper 实现 CAN Bus 数据本地处理
第 1 步:连接到 CAN Bus
eKuiper 使用 CAN 源插件来连接 CAN Bus 并接收 CAN 帧。它支持两种连接 CAN Bus 的模式,如下图所示。
- 通过 socketCan 直接连接到 CAN Bus 。SocketCAN 使用 Berkeley socket API、Linux 网络协议栈,并将 CAN 设备驱动程序实现为网络接口。一旦将 CAN Bus 连接到 Linux 系统,用户就可以获得 CAN 网络接口。在 eKuiper 中,用户可以通过指定 CAN 网络接口和 DBC 文件路径来创建 CAN 流。然后,可以对 CAN 流应用任何规则来处理 CAN Bus 数据。
- 利用 TCP/UDP 通过网关连接到 CAN Bus 。网关可以是一个 CAN 适配器,它将多个 CAN 帧组合成一个数据包,并通过 TCP 或 UDP 批量发送出去。注意,网关发送的数据包格式没有标准化,因此可能需要修改插件来适应它。在 eKuiper 中,用户可以通过指定 TCP/UDP 地址和 DBC 文件路径来创建 CAN 流。然后,可以对 CAN 流应用任何规则来处理 CAN Bus 数据。
第 2 步:解码 CAN Bus 数据
CAN Bus 数据是二进制数据并且以帧为单位,CAN 帧由多个字段组成。CAN 协议有多个版本,包括 CAN 2.0A、CAN 2.0B 和 CAN FD。不同版本的 CAN 帧格式略有不同。下图显示了 CAN 2.0A 的帧格式。
其中,有两个字段对解码 CAN Bus 数据很重要:
- ID 字段:ID 字段用于标识 CAN 帧。CAN 2.0A 的 ID 字段是 11 位,CAN 2.0B 和 CANFD 是 29 位。
- 数据字段:数据字段是有效载荷,用于携带实际数据。CAN 2.0A 和 CAN 2.0B 是 0-8 字节,CAN FD 是 0-64 字节。
在有效载荷中,数据由一系列的信号组成,每个信号都有自己的名称、长度和位置。DBC 文件是一个文本文件,其中包含将原始 CAN Bus 数据解码为“物理值”的相关信息。该文件定义了信号的名称、长度、位置以及将原始数据转换为物理值所使用的转换公式。
在 eKuiper 中,用户可以在解析 CAN Bus 数据时指定要使用的 DBC 文件路径。在 eKuiper 中配置 DBC 非常灵活和安全。
- 多个 DBC 文件:用户可以选择一个目录作为 DBC 路径,目录中的 DBC 文件将按字母顺序逐个加载并生效。这种方式可以让用户通过单独的 DBC 文件来增量添加或还原信号。
- 动态 DBC 文件加载:DBC 文件在运行时加载,无需在开发时部署。这可以帮助用户保持 DBC 文件的私密性和安全性。
- 热加载:用户无需重新启动引擎即可随时更改 DBC 文件,以适应不同的 CAN Bus 设备。
配置完 eKuiper CAN 源后,用户可以创建一个流来接收并解析 CAN Bus 数据,从中提取有意义的物理信号。例如,CAN 有效载荷 0x0000000000000000
可以解析为以下信号:
{
"signal1": 0,
"signal2": 0,
"signal3": 0,
"signal4": 0,
"signal5": 0,
"signal6": 0,
"signal7": 0,
"signal8": 0
}
接下来,用户可以像从 MQTT 接收数据一样,利用 eKuiper 强大的流处理能力,对解析后的数据进行灵活处理。
第 3 步:处理 CAN Bus 数据
在得到解析过的数据后,我们可以利用 eKuiper 对它进行各种操作。为了节省传输数据的带宽,我们可以只挑选感兴趣的信号。比如,可以仅选择 signal1
和 signal2
这两个信号。
{
"signal1": 0,
"signal2": 0
}
用 eKuiper SQL 语句可以很容易实现这一点:
SELECT signal1, signal2 FROM canStream
由于 CAN 帧的大小有限,我们可能需要从多个 CAN 帧中提取所需的信号。因此,我们可以根据需要使用算法灵活地组合不同 CAN 帧中的信号,以构建完整的消息供应用程序使用。您可以在数据合并的示例中了解更多详细信息。这里,我们用 signal1 作为主要条件来筛选数据。
SELECT signal1, latest(signal2) as signal2 FROM canStream WHERE isNull(signal1) = false
另一个示例是只在特定事件发生时才收集数据,这样可以显著减少带宽的消耗。举个例子,我们可以只在 signal1 超过 100 时才进行数据收集。
SELECT signal1, signal2 FROM canStream WHERE signal1 > 100
此外,这些处理规则非常灵活,可以随时进行修改。即使在最初阶段没有确定所需的信号,也无需担心,您可以根据需求的变化随时调整规则,并实现热加载。
除了数据采集这一常见用途,eKuiper 还可以应用于其它场景,例如:
- 车载端实时灵活的规则引擎:可以根据特定条件触发相应动作。比如,当车速超过 70 英里/小时时,自动关闭车窗。
- 灵活的智能分析:可以在零编码或不连接云端的情况下,对数据和 AI 模型(目前是 TF Lite)进行组合。这个功能可以实现实时数据分析,比如根据速度、轮胎压力等数据预测和建议驾驶模式(即使没有网络连接)。
- 边缘计算:可以减少传输带宽,降低云端计算压力,还能解析、重组和转换数据,比如计算一段时间内的平均速度并保存。
- 异构数据整合:可以解析来自不同协议(TCP、UDP、HTTP、MQTT)和不同格式(CAN、JSON、CSV 等)的数据,并通过灵活的规则进行合并。
- 消息路由:可以决定哪些数据发送到云端,哪些数据保存在本地供其它车载应用使用。比如,根据 GDPR 或某些白名单来确定路由。
利用 MQTT 采集 CAN Bus 数据
使用 EMQX 这类 MQTT Broker 收集 CAN Bus 数据有以下几个优势:
- 降低网络开销:MQTT 采用二进制格式和极简的头部对消息进行编码,可以节省网络带宽,提升数据传输效率。
- 提升扩展性:单个 MQTT Broker 能够支持上千个并发连接和每秒上百万条消息。这使得可以从多个 CAN Bus 设备进行大规模数据收集,而不会影响性能或可靠性。
- 增强安全性:MQTT 支持多种安全机制,比如 TLS/SSL 加密、用户名/密码认证、访问控制列表(ACL),以防止未经授权的数据访问或篡改。
- 改善互操作性:MQTT 基于开放标准,被各种平台和语言广泛支持。这有利于将 CAN Bus 数据与其它系统或应用进行集成。
除此之外,EMQX 还提供了许多其它功能,并能够与 eKuiper 协同工作,从而帮助用户在传输 CAN Bus 数据时节省带宽、减少延迟、提高可靠性。
节省带宽
在通过 MQTT 传输 CAN Bus 数据时,我们通常需要在带宽受限的弱网络环境下进行传输。因此,我们需要尽量减小数据的大小。
在 eKuiper sink 中,我们可以使用 format
选项来指定数据格式。默认格式是 JSON
。我们可以将其改为 protobuf
,将数据序列化为二进制格式,以显著减少数据大小。另外,我们可以使用 compress
选项来通过 gzip
或其它压缩方法来压缩数据。通过这些方式我们可以让数据的大小比原来的 JSON 数据小很多。在我们的一个测试用例中,在批量发送数据时数据的大小可以减少 90% 以上。
实时数据
对于云端应用而言,某些数据具有时间敏感性,例如用于车辆事故诊断的数据。在这种情况下,降低延迟非常重要。在 eKuiper 规则中,我们可以用 MQTT sink 把数据快速发送到 EMQX,以满足高效的数据传输需求。
为了在实时场景中节省带宽,我们可以像前文介绍的那样,在 eKuiper MQTT sink 中设置序列化格式和压缩方法。EMQX 提供了规则引擎,可以解压缩和反序列化数据,这样云端应用不用编写代码就可以实时地处理数据。
将数据批量存入文件
对于不急于处理的数据,我们可以保存在文件或本地数据库里,然后批量发送到云端。这样可以达到更高的压缩比,进而节省更多的带宽。在 eKuiper 规则中,我们可以使用文件 sink 来本地保存和压缩数据。文件 sink 支持设置文件滚动策略,例如每 10 分钟滚动一次,这样我们可以将数据批量保存在文件中。EMQX 正在开发一个新功能,实现用 MQTT 传输文件。等这个功能完成后,保存的文件就可以用 MQTT 传输了。目前,用户可以用其它工具把文件传输到云端。
结语
本文介绍了如何利用 eKuiper 和 EMQX 从车辆收集、处理、传输 CAN Bus 数据到云端。在接下来的文章中,我们将对每个步骤进行更详细地讲解。
版权声明: 本文为 EMQ 原创,转载请注明出处。
原文链接:https://www.emqx.com/zh/blog/can-bus-how-it-works-pros-and-cons