Import and Decode LIN Data in MDF Files
This example shows how to import and decode LIN data from an MDF file in MATLAB® for analysis. Another example showcased how to extract CAN and CAN FD bus data from an MDF file and decode them Customize Metadata When Writing Timetable Data to MDF Files. Here, you'll learn how to access LIN frames and decode them using an LDF file. The MDF file used in this example is generated using Vector CANoe™, and the decoding is facilitated by one of the LIN Description File (LDF) associated with the CAN-LIN network setup.
Identify LIN Data Frames
First, gather information about the MDF file:
mdfInfo("MDFFrameLogging.mf4")
ans = MDFInfo with properties: File Details Name: "MDFFrameLogging.mf4" Path: "/tmp/Bdoc25a_2864802_1974203/tp6f7be44e/vnt-ex95179185/MDFFrameLogging.mf4" Author: "" Department: "" Project: "" Subject: "" Comment: "" Version: "4.20" InitialTimestamp: 2025-01-16 19:44:41.936000000 Creator Details ProgramIdentifier: "MDF4Lib" CreatorVendorName: "Vector Informatik GmbH" CreatorToolName: "CANoe" CreatorToolVersion: "18.2.65" CreatorUserName: "hpatel" CreatorComment: "Created using MdfLog version 1.7.7.0 and Mdf4Lib version 1.9.0.0 X64 (2022-08-31)" File Contents Attachment: [10×7 table] ChannelGroupCount: 18 Event: [0×8 eventtable]
According to the ASAM MDF standard for bus logging, the event types for a LIN bus system include "LIN_Frame", "LIN_WakeUp", "LIN_TransmissionError", "LIN_SyncError", "LIN_ReceiveError", "LIN_Spike", or "LIN_LongDom". This example focuses on extracting the LIN data frames, using the "LIN_Frame" event type. A standard LIN data frame can have up to 8 bytes for its payload and is used to transfer signal values.
The standard specifies that channel names in the event structure should be prefixed by the event type name, such as "LIN_Frame
". Typically, a dot is used as a separator character to specify member channels, for example, "LIN_Frame.ID"
or "LIN_Frame.DataLength"
.
Use the mdfChannelInfo
function to locate channel names matching "LIN_Frame.*"
:
mdfChannelInfo("MDFFrameLogging.mf4", Channel="LIN_Frame.*")
ans=66×13 table
Name GroupNumber GroupNumSamples GroupAcquisitionName GroupComment GroupSourceName GroupSourcePath DisplayName Unit Comment ExtendedNamePrefix SourceName SourcePath
________________________________ ___________ _______________ ____________________ ____________ _______________ _______________ ______________________ ___________ __________________________________________________________ __________________ ___________ __________
"LIN_Frame.Baudrate" 11 285 LIN6 <undefined> <undefined> LIN_Frame "Baudrate" bit/second Baudrate in bits per second. LIN6 <undefined> LIN6
"LIN_Frame.Baudrate" 12 939 LIN4 <undefined> <undefined> LIN_Frame "Baudrate" bit/second Baudrate in bits per second. LIN4 <undefined> LIN4
"LIN_Frame.Baudrate" 13 1281 LIN3 <undefined> <undefined> LIN_Frame "Baudrate" bit/second Baudrate in bits per second. LIN3 <undefined> LIN3
"LIN_Frame.BreakDelimiterLength" 11 285 LIN6 <undefined> <undefined> LIN_Frame "BreakDelimiterLength" ns Length of the break delimiter in ns. LIN6 <undefined> LIN6
"LIN_Frame.BreakDelimiterLength" 12 939 LIN4 <undefined> <undefined> LIN_Frame "BreakDelimiterLength" ns Length of the break delimiter in ns. LIN4 <undefined> LIN4
"LIN_Frame.BreakDelimiterLength" 13 1281 LIN3 <undefined> <undefined> LIN_Frame "BreakDelimiterLength" ns Length of the break delimiter in ns. LIN3 <undefined> LIN3
"LIN_Frame.BreakLength" 11 285 LIN6 <undefined> <undefined> LIN_Frame "BreakLength" ns Length of the break in ns. LIN6 <undefined> LIN6
"LIN_Frame.BreakLength" 12 939 LIN4 <undefined> <undefined> LIN_Frame "BreakLength" ns Length of the break in ns. LIN4 <undefined> LIN4
"LIN_Frame.BreakLength" 13 1281 LIN3 <undefined> <undefined> LIN_Frame "BreakLength" ns Length of the break in ns. LIN3 <undefined> LIN3
"LIN_Frame.BusChannel" 11 285 LIN6 <undefined> <undefined> LIN_Frame "BusChannel" <undefined> Logical bus channel number the frame was sent or received. LIN6 <undefined> LIN6
"LIN_Frame.BusChannel" 12 939 LIN4 <undefined> <undefined> LIN_Frame "BusChannel" <undefined> Logical bus channel number the frame was sent or received. LIN4 <undefined> LIN4
"LIN_Frame.BusChannel" 13 1281 LIN3 <undefined> <undefined> LIN_Frame "BusChannel" <undefined> Logical bus channel number the frame was sent or received. LIN3 <undefined> LIN3
"LIN_Frame.Checksum" 11 285 LIN6 <undefined> <undefined> LIN_Frame "Checksum" <undefined> Checksum. LIN6 <undefined> LIN6
"LIN_Frame.Checksum" 12 939 LIN4 <undefined> <undefined> LIN_Frame "Checksum" <undefined> Checksum. LIN4 <undefined> LIN4
"LIN_Frame.Checksum" 13 1281 LIN3 <undefined> <undefined> LIN_Frame "Checksum" <undefined> Checksum. LIN3 <undefined> LIN3
"LIN_Frame.ChecksumModel" 11 285 LIN6 <undefined> <undefined> LIN_Frame "ChecksumModel" <undefined> ChecksumModel. LIN6 <undefined> LIN6
⋮
In this case, exterior light data of interest was logged from the LIN 4 network. The output above shows that the data from the LIN 4 network has been stored in channel group 12 of the MDF file.
Read LIN Data Frames from the MDF File
Read all data in channel group 12 into a timetable using the mdfRead
function. The timetable follows the ASAM MDF standard logging format, where each row represents one raw LIN frame from the bus, and each column represents a channel within the specified channel group.
data = mdfRead("MDFFrameLogging.mf4", GroupNumber = 12)
data = 1×1 cell array
{939×22 timetable}
linData = data{1}
linData=939×22 timetable
t LIN_Frame.BusChannel LIN_Frame.ID LIN_Frame.Dir LIN_Frame.ReceivedDataByteCount LIN_Frame.DataLength LIN_Frame.DataBytes LIN_Frame.Checksum LIN_Frame.ChecksumModel LIN_Frame.SOF LIN_Frame.Baudrate LIN_Frame.ResponseBaudrate LIN_Frame.ConfiguredBaudrate LIN_Frame.BreakLength LIN_Frame.BreakDelimiterLength LIN_Frame.IsSimulated LIN_Frame.SupplierID LIN_Frame.MessageID LIN_Frame.NAD LIN_Frame.EOH LIN_Frame.IsETF LIN_Frame.ETFAssocIndex LIN_Frame.ETFAssocETFId
___________ ____________________ ____________ _____________ _______________________________ ____________________ _________________________________ __________________ _______________________ _____________ __________________ __________________________ ____________________________ _____________________ ______________________________ _____________________ ____________________ ___________________ _____________ _____________ _______________ _______________________ _______________________
0.10573 sec 4 21 "Tx" 6 6 {[ 255 0 255 206 255 255]} 219 "Enhanced" 100000000 19200 0 0 937494 104166 1 0 0 0 102083320 0 0 255
0.1125 sec 4 22 "Tx" 8 8 {[254 0 255 255 255 255 161 255]} 136 "Enhanced" 105729130 19200 0 0 937494 104166 1 0 0 0 107812450 0 0 255
0.11875 sec 4 25 "Tx" 7 7 {[ 224 0 255 247 255 255 203]} 193 "Enhanced" 112499920 19200 0 0 937494 104166 1 0 0 0 114583240 0 0 255
0.12187 sec 4 26 "Tx" 1 1 {[ 244]} 240 "Enhanced" 118749880 19200 0 0 937494 104166 1 0 0 0 120833200 0 0 255
0.20625 sec 4 23 "Tx" 7 7 {[ 0 254 34 255 255 255 255]} 71 "Enhanced" 200000000 19200 0 0 937494 104166 1 0 0 0 202083320 0 0 255
0.21146 sec 4 24 "Tx" 5 5 {[ 16 254 55 255 255]} 224 "Enhanced" 206249960 19200 0 0 937494 104166 1 0 0 0 208333280 0 0 255
0.21562 sec 4 27 "Tx" 3 3 {[ 253 4 170]} 247 "Enhanced" 211458260 19200 0 0 937494 104166 1 0 0 0 213541580 0 0 255
0.22135 sec 4 21 "Tx" 6 6 {[ 255 0 255 235 255 255]} 190 "Enhanced" 215624900 19200 0 0 937494 104166 1 0 0 0 217708220 0 0 255
0.22812 sec 4 22 "Tx" 8 8 {[ 253 0 255 255 255 255 52 255]} 246 "Enhanced" 221354030 19200 0 0 937494 104166 1 0 0 0 223437350 0 0 255
0.23437 sec 4 25 "Tx" 7 7 {[ 224 0 255 247 255 255 122]} 19 "Enhanced" 228124820 19200 0 0 937494 104166 1 0 0 0 230208140 0 0 255
0.2375 sec 4 26 "Tx" 1 1 {[ 236]} 248 "Enhanced" 234374780 19200 0 0 937494 104166 1 0 0 0 236458100 0 0 255
0.30573 sec 4 21 "Tx" 6 6 {[ 252 0 255 36 255 255]} 137 "Enhanced" 300000000 19200 0 0 937494 104166 1 0 0 0 302083320 0 0 255
0.3125 sec 4 22 "Tx" 8 8 {[253 0 255 255 255 255 116 255]} 182 "Enhanced" 305729130 19200 0 0 937494 104166 1 0 0 0 307812450 0 0 255
0.31875 sec 4 25 "Tx" 7 7 {[ 224 0 255 247 255 255 108]} 33 "Enhanced" 312499920 19200 0 0 937494 104166 1 0 0 0 314583240 0 0 255
0.32187 sec 4 26 "Tx" 1 1 {[ 236]} 248 "Enhanced" 318749880 19200 0 0 937494 104166 1 0 0 0 320833200 0 0 255
0.40625 sec 4 23 "Tx" 7 7 {[ 0 254 128 255 255 255 255]} 232 "Enhanced" 400000000 19200 0 0 937494 104166 1 0 0 0 402083320 0 0 255
⋮
Decode LIN Messages using the LDF File
Open the LDF file using the linDatabase
function.
ldb = linDatabase("ExteriorLight_LIN_CH4.ldf")
ldb = Database with properties: File Information Name: "ExteriorLight_LIN_CH4.ldf" Path: "/tmp/Bdoc25a_2864802_1974203/tp6f7be44e/vnt-ex95179185/ExteriorLight_LIN_CH4.ldf" ProtocolVersion: 2.2000 LanguageVersion: 2.2000 BusSpeed: 19.2000 Network Information Nodes: [6×3 table] Frames: [7×5 table] Signals: [19×5 table]
The linMessageTimetable
function uses the LDF database to decode the message names and signals. Convert the ASAM standard logging format data into a Vehicle Network Toolbox™ LIN message timetable.
msgTimetable = linMessageTimetable(linData, ldb)
msgTimetable=939×8 timetable
Time ID Name Data Length Signals ErrorType ChecksumType Checksum
___________ __ ___________ ____________________________________________________ ______ ____________ _________ ____________ ________
0.10573 sec 21 DLFLeft_01 255 0 255 206 255 255 0 0 6 {1×1 struct} None Enhanced 219
0.1125 sec 22 DLFRight_01 254 0 255 255 255 255 161 255 8 {1×1 struct} None Enhanced 136
0.11875 sec 25 GWE_01 224 0 255 247 255 255 203 0 7 {1×1 struct} None Enhanced 193
0.12187 sec 26 GWE_02 244 0 0 0 0 0 0 0 1 {1×1 struct} None Enhanced 240
0.20625 sec 23 DLRLeft_01 0 254 34 255 255 255 255 0 7 {1×1 struct} None Enhanced 71
0.21146 sec 24 DLRRight_01 16 254 55 255 255 0 0 0 5 {1×1 struct} None Enhanced 224
0.21562 sec 27 WWS_01 253 4 170 0 0 0 0 0 3 {1×1 struct} None Enhanced 247
0.22135 sec 21 DLFLeft_01 255 0 255 235 255 255 0 0 6 {1×1 struct} None Enhanced 190
0.22812 sec 22 DLFRight_01 253 0 255 255 255 255 52 255 8 {1×1 struct} None Enhanced 246
0.23437 sec 25 GWE_01 224 0 255 247 255 255 122 0 7 {1×1 struct} None Enhanced 19
0.2375 sec 26 GWE_02 236 0 0 0 0 0 0 0 1 {1×1 struct} None Enhanced 248
0.30573 sec 21 DLFLeft_01 252 0 255 36 255 255 0 0 6 {1×1 struct} None Enhanced 137
0.3125 sec 22 DLFRight_01 253 0 255 255 255 255 116 255 8 {1×1 struct} None Enhanced 182
0.31875 sec 25 GWE_01 224 0 255 247 255 255 108 0 7 {1×1 struct} None Enhanced 33
0.32187 sec 26 GWE_02 236 0 0 0 0 0 0 0 1 {1×1 struct} None Enhanced 248
0.40625 sec 23 DLRLeft_01 0 254 128 255 255 255 255 0 7 {1×1 struct} None Enhanced 232
⋮
View the signals stored in the first "GWI_01
" message.
msgTimetable.Signals{3}
ans = struct with fields:
GWE_TurnIndicationLeft: 0
GWE_TurnIndicationRight: 0
GWE_WarningLight: 0
GWE_DrivingLight: 1
GWE_Reserved: 203
Repackage and Visualize Signal Values of Interest
To organize signal data from each unique message on the bus into a signal timetable, use the hLINSignalTimetable
helper function included with this example. This example demonstrates how to create signal timetables for the specific message of interest, "GWI_01
," from the LIN message timetable. The "GWI_01
" message includes the following signals: left turn, right turn, warning/hazard light, and driving light.
signalTimetable = hLINSignalTimetable(msgTimetable,'GWE_01')
signalTimetable=171×5 timetable
Time GWE_TurnIndicationLeft GWE_TurnIndicationRight GWE_WarningLight GWE_DrivingLight GWE_Reserved
___________ ______________________ _______________________ ________________ ________________ ____________
0.11875 sec 0 0 0 1 203
0.23437 sec 0 0 0 1 122
0.31875 sec 0 0 0 1 108
0.43437 sec 0 0 0 1 248
0.51875 sec 0 0 0 1 199
0.63437 sec 0 0 0 1 197
0.71875 sec 0 0 0 1 245
0.83437 sec 0 0 0 1 119
0.91875 sec 0 0 0 1 67
1.0344 sec 0 0 0 1 198
1.1187 sec 0 0 0 1 86
1.2344 sec 0 0 0 1 14
1.3187 sec 0 0 0 1 134
1.4344 sec 0 0 0 1 233
1.5187 sec 0 0 0 1 153
1.6344 sec 0 0 0 1 26
⋮
To visualize the signals of interest, columns from the signal timetables can be plotted over time for further analysis.
stackedplot(signalTimetable,{"GWE_TurnIndicationLeft","GWE_TurnIndicationRight","GWE_WarningLight","GWE_DrivingLight"},marker=".") title("Signals from 'GWE\_01' Message")