在 CAN 通信中使用相对和绝对时间戳
此示例说明如何使用 CAN 通道的 InitialTimestamp
属性来处理 CAN 报文的相对和绝对时间戳。它使用以环回配置形式连接的 MathWorks® 虚拟 CAN 通道。此示例说明 CAN 网络的工作流,但所展示的概念也适用于 CAN FD 网络。
打开 DBC 文件
打开 DBC 文件以访问数据库定义。
db = canDatabase("VehicleInfo.dbc")
db = Database with properties: Name: 'VehicleInfo' Path: '/tmp/Bdoc24a_2511836_3090053/tpeb21c448/vnt-ex13648766/VehicleInfo.dbc' UTF8_File: '/tmp/Bdoc24a_2511836_3090053/tpeb21c448/vnt-ex13648766/VehicleInfo.dbc' Nodes: {} NodeInfo: [0x0 struct] Messages: {'WheelSpeeds'} MessageInfo: [1x1 struct] Attributes: {'BusType'} AttributeInfo: [1x1 struct] UserData: []
创建 CAN 通道
创建可用于传输和接收报文的 CAN 通道。
txCh = canChannel("MathWorks", "Virtual 1", 1)
txCh = Channel with properties: Device Information DeviceVendor: 'MathWorks' Device: 'Virtual 1' DeviceChannelIndex: 1 DeviceSerialNumber: 0 ProtocolMode: 'CAN' Status Information Running: 0 MessagesAvailable: 0 MessagesReceived: 0 MessagesTransmitted: 0 InitializationAccess: 1 InitialTimestamp: [0x0 datetime] FilterHistory: 'Standard ID Filter: Allow All | Extended ID Filter: Allow All' Channel Information BusStatus: 'N/A' SilentMode: 0 TransceiverName: 'N/A' TransceiverState: 'N/A' ReceiveErrorCount: 0 TransmitErrorCount: 0 BusSpeed: 500000 SJW: [] TSEG1: [] TSEG2: [] NumOfSamples: [] Other Information Database: [] UserData: []
rxCh = canChannel("MathWorks", "Virtual 1", 2)
rxCh = Channel with properties: Device Information DeviceVendor: 'MathWorks' Device: 'Virtual 1' DeviceChannelIndex: 2 DeviceSerialNumber: 0 ProtocolMode: 'CAN' Status Information Running: 0 MessagesAvailable: 0 MessagesReceived: 0 MessagesTransmitted: 0 InitializationAccess: 1 InitialTimestamp: [0x0 datetime] FilterHistory: 'Standard ID Filter: Allow All | Extended ID Filter: Allow All' Channel Information BusStatus: 'N/A' SilentMode: 0 TransceiverName: 'N/A' TransceiverState: 'N/A' ReceiveErrorCount: 0 TransmitErrorCount: 0 BusSpeed: 500000 SJW: [] TSEG1: [] TSEG2: [] NumOfSamples: [] Other Information Database: [] UserData: []
将数据库直接连接到接收通道,以便自动将数据库定义应用于传入的报文。
rxCh.Database = db;
创建 CAN 报文
通过指定要应用数据库定义的数据库和报文名称 WheelSpeeds
来创建新 CAN 报文。
msg = canMessage(db, "WheelSpeeds")
msg = Message with properties: Message Identification ProtocolMode: 'CAN' ID: 1200 Extended: 0 Name: 'WheelSpeeds' Data Details Timestamp: 0 Data: [0 0 0 0 0 0 0 0] Signals: [1x1 struct] Length: 8 Protocol Flags Error: 0 Remote: 0 Other Information Database: [1x1 can.Database] UserData: []
启动 CAN 通道
启动通道以开始使用它们进行传输和接收。
start(rxCh) start(txCh)
传输 CAN 报文
transmit
函数将报文发送到网络上。使用 pause
增加传输操作之间的延迟。每次传输前更新 LF_WSpeed
信号值。
msg.Signals.LF_WSpeed = 10; transmit(txCh, msg) pause(1); msg.Signals.LF_WSpeed = 20; transmit(txCh, msg) pause(2); msg.Signals.LF_WSpeed = 30; transmit(txCh, msg) pause(3); msg.Signals.LF_WSpeed = 40; transmit(txCh, msg) pause(1); msg.Signals.LF_WSpeed = 50; transmit(txCh, msg)
接收 CAN 报文
receive
函数接收在网络上出现的 CAN 报文。
stop(rxCh) stop(txCh) msgRx = receive(rxCh, Inf, "OutputFormat", "timetable")
msgRx=5×8 timetable
Time ID Extended Name Data Length Signals Error Remote
____________ ____ ________ _______________ ______________________ ______ ____________ _____ ______
0.041708 sec 1200 false {'WheelSpeeds'} {[42 248 0 0 0 0 0 0]} 8 {1x1 struct} false false
1.1522 sec 1200 false {'WheelSpeeds'} {[46 224 0 0 0 0 0 0]} 8 {1x1 struct} false false
3.1872 sec 1200 false {'WheelSpeeds'} {[50 200 0 0 0 0 0 0]} 8 {1x1 struct} false false
6.2116 sec 1200 false {'WheelSpeeds'} {[54 176 0 0 0 0 0 0]} 8 {1x1 struct} false false
7.2406 sec 1200 false {'WheelSpeeds'} {[58 152 0 0 0 0 0 0]} 8 {1x1 struct} false false
检查信号数据
使用 canSignalTimetable
将接收到的报文中的信号数据重新打包为一个信号时间表。请注意,时间戳值表示从 CAN 通道启动以来经过的时间。
signalTimetable = canSignalTimetable(msgRx)
signalTimetable=5×4 timetable
Time LR_WSpeed RR_WSpeed RF_WSpeed LF_WSpeed
____________ _________ _________ _________ _________
0.041708 sec -100 -100 -100 10
1.1522 sec -100 -100 -100 20
3.1872 sec -100 -100 -100 30
6.2116 sec -100 -100 -100 40
7.2406 sec -100 -100 -100 50
plot(signalTimetable.Time, signalTimetable.LF_WSpeed, "x") title("Signal Data with Relative Time", "FontWeight", "bold") xlabel("Relative Timestamp") ylabel("Signal Value") ylim([0 60])
检查 InitialTimestamp
属性
查看 CAN 接收通道的 InitialTimestamp
属性。它是 datetime
值,表示通道启动的绝对时间。
rxCh.InitialTimestamp
ans = datetime
25-Jan-2024 21:02:16
使用绝对时间戳分析数据
结合每条报文的相对时间戳和 InitialTimestamp
属性,获得每条报文的绝对时间戳。将绝对时间戳以时间向量形式设置回报文时间表中。
msgRx.Time = msgRx.Time + rxCh.InitialTimestamp
msgRx=5×8 timetable
Time ID Extended Name Data Length Signals Error Remote
____________________ ____ ________ _______________ ______________________ ______ ____________ _____ ______
25-Jan-2024 21:02:16 1200 false {'WheelSpeeds'} {[42 248 0 0 0 0 0 0]} 8 {1x1 struct} false false
25-Jan-2024 21:02:17 1200 false {'WheelSpeeds'} {[46 224 0 0 0 0 0 0]} 8 {1x1 struct} false false
25-Jan-2024 21:02:19 1200 false {'WheelSpeeds'} {[50 200 0 0 0 0 0 0]} 8 {1x1 struct} false false
25-Jan-2024 21:02:22 1200 false {'WheelSpeeds'} {[54 176 0 0 0 0 0 0]} 8 {1x1 struct} false false
25-Jan-2024 21:02:23 1200 false {'WheelSpeeds'} {[58 152 0 0 0 0 0 0]} 8 {1x1 struct} false false
基于更新后的报文时间表创建的信号时间表现在也具有绝对时间戳。
signalTimetable = canSignalTimetable(msgRx)
signalTimetable=5×4 timetable
Time LR_WSpeed RR_WSpeed RF_WSpeed LF_WSpeed
____________________ _________ _________ _________ _________
25-Jan-2024 21:02:16 -100 -100 -100 10
25-Jan-2024 21:02:17 -100 -100 -100 20
25-Jan-2024 21:02:19 -100 -100 -100 30
25-Jan-2024 21:02:22 -100 -100 -100 40
25-Jan-2024 21:02:23 -100 -100 -100 50
figure plot(signalTimetable.Time, signalTimetable.LF_WSpeed, "x") title("Signal Data with Absolute Time", "FontWeight", "bold") xlabel("Absolute Timestamp") ylabel("Signal Value") ylim([0 60])
关闭通道和 DBC 文件
通过从工作区中清除 DBC 文件的变量,关闭对通道和 DBC 文件的访问。
clear rxCh txCh clear db