Use ARXML Files in CAN Communication
This example shows you how to create, receive, and process messages using information stored in ARXML files.
Open the ARXML File
Create a database in the workspace from the ARXML file. The database includes metadata and structure information about the ARXML file.
db = arxmlDatabase("demoFile.arxml")db =
Database with properties:
Name: "demoFile.arxml"
Path: "/tmp/Bdoc26a_3146167_47098/tp66b972e5/vnt-ex83636057/demoFile.arxml"
CAN: [1×1 vnt.arxml.protocol.CAN]
Examine the Frame property to see the names of all messages defined in this file.
db.CAN.Frame
ans=2×9 table
Name Path ID Extended StartBit Length ByteOrder PDU FrameTriggering
______________ _______________________________ ____ ________ ________ ______ _______________________ ________________________________ ___________________
"EngineMsg" "/MathWorks/FRAME/EngineMsg" 1000 false 0 8 mostSignificantByteLast /MathWorks/PDUS/Engine_PDU "FrameTriggering_1"
"VehicleState" "/MathWorks/FRAME/VehicleState" 1001 true 0 4 mostSignificantByteLast /MathWorks/PDUS/VehicleState_PDU "FrameTriggering_2"
View PDU Information
In the table, view the Protocol Data Unit (PDU) information for EngineMsg, including the PDU start bit, data length, and a signal list. Only ISignalIPDU is supported.
ISignalIPDUTable = db.CAN.PDU.ISignalIPDU;
EnginPDU = ISignalIPDUTable(ISignalIPDUTable.Name == "Engine_PDU", :)EnginPDU=1×6 table
Name Frame ISignal StartBit Length ByteOrder
____________ __________________________ ___________ ________ ______ _______________________
"Engine_PDU" /MathWorks/FRAME/EngineMsg {4×5 table} 0 8 mostSignificantByteLast
View Signal Metadata
There are two ways to view the Signal information. View basic mapping information of the signals of a specific PDU in the ISignalIPDU table.
EnginPDU.ISignal{1}ans=4×5 table
Name StartBit Length ByteOrder BaseType
____________________ ________ ______ _______________________ ____________
"VehicleSpeed" 0 8 mostSignificantByteLast {1×1 struct}
"TransmissionStatus" 8 8 mostSignificantByteLast {1×1 struct}
"GPSSpeed" 16 8 mostSignificantByteLast {1×1 struct}
"EngineSpeed" 24 32 mostSignificantByteLast {1×1 struct}
You can also view the signal information in the ISignal table, which provides more details including the unit, compuMethod, baseType, systemSignal reference, etc.
db.CAN.ISignal
ans=5×9 table
Name CompuMethod StartBit Length ByteOrder BaseType Unit PDU SystemSignal
____________________ _________________________ ________ ______ _______________________ ____________ ____ ________________________________ _____________________________________________________
"EngineSpeed" 1×1 vnt.arxml.CompuMethod 24 32 mostSignificantByteLast {1×1 struct} rpm /MathWorks/PDUS/Engine_PDU "/MathWorks/SYSTEM_SIGNALS/EngineSpeed_System"
"GPSSpeed" 1×1 vnt.arxml.CompuMethod 16 8 mostSignificantByteLast {1×1 struct} rpm /MathWorks/PDUS/Engine_PDU "/MathWorks/SYSTEM_SIGNALS/GPSSpeed_System"
"Ignition" 1×1 vnt.arxml.CompuMethod 0 2 mostSignificantByteLast {1×1 struct} rpm /MathWorks/PDUS/VehicleState_PDU "/MathWorks/SYSTEM_SIGNALS/Ignition_System"
"TransmissionStatus" 1×1 vnt.arxml.CompuMethod 8 8 mostSignificantByteLast {1×1 struct} mph /MathWorks/PDUS/Engine_PDU "/MathWorks/SYSTEM_SIGNALS/TransmissionStatus_System"
"VehicleSpeed" 1×1 vnt.arxml.CompuMethod 0 8 mostSignificantByteLast {1×1 struct} rpm /MathWorks/PDUS/Engine_PDU "/MathWorks/SYSTEM_SIGNALS/VehicleSpeed_System"
Create a Message Using Database Definitions
Create a new message by specifying the database and the message name EngineMsg to have the database definition applied.
msgEngine = canMessage(db, "EngineMsg")msgEngine =
Message with properties:
Message Identification
ProtocolMode: 'CAN'
ID: 1000
Extended: 0
Name: 'EngineMsg'
Data Details
Timestamp: 0
Data: [0 0 0 0 0 0 0 0]
Signals: [1×1 struct]
Length: 8
Protocol Flags
Error: 0
Remote: 0
Other Information
Database: [1×1 vnt.arxml.Database]
UserData: []
View Signal Value
View the Signals property to see signal values for this message. You can directly write to and read from these signals to pack and unpack data from the message. EngineMsg includes VehicleSpeed, TransmissionStatus, GPSSpeed, and EngineSpeed. VehicleSpeed, TransmissionStatus, and EngineSpeed are numeric values. TransmissionStatus is an enumeration type, which can have the value 'P', 'N', 'R', or 'D'. Enumeration values are output as text, converted from the raw CAN messages using text category CompuMethods, such as TEXTTABLE, defined in the ARXML file.
msgEngine.Signals
ans = struct with fields:
VehicleSpeed: 0
TransmissionStatus: 'P'
GPSSpeed: 0
EngineSpeed: 0
Change Signal Information
Change the signal TransmissionStatus value from 'P' (parking) to 'N' (neutral).
msgEngine.Signals.TransmissionStatus = 'N'; Read the signal values back to verify that TransmissionStatus has been updated with the new value.
msgEngine.Signals
ans = struct with fields:
VehicleSpeed: 0
TransmissionStatus: 'N'
GPSSpeed: 0
EngineSpeed: 0
When a value is written directly to the signal, it is translated, scaled, and packed into the message data using the database definition. Note the value change in the Data property after a new value is written to the EngineSpeed signal.
msgEngine.Signals.EngineSpeed = 5500; msgEngine.Signals
ans = struct with fields:
VehicleSpeed: 0
TransmissionStatus: 'N'
GPSSpeed: 0
EngineSpeed: 5500
Receive Messages with Database Information
To automatically apply database definitions to incoming messages, attach a database to a CAN channel that receives messages. The database decodes only those messages that are defined. All other messages are received in their raw form.
rxCh = canChannel("MathWorks", "Virtual 1", 2); rxCh.Database = db
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: [0×0 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: [1×1 vnt.arxml.Database]
UserData: []
Receive Messages
Start the channel, generate some message traffic, and receive messages with physical message decoding.
start(rxCh); generateCANMsgsARXML(); rxMsg = receive(rxCh, Inf, "OutputFormat", "timetable"); rxMsg(1:15, :)
ans=15×8 timetable
Time ID Extended Name Data Length Signals Error Remote
___________ ____ ________ ________________ ______________________ ______ ____________ _____ ______
0.13748 sec 1000 false {'EngineMsg' } {[ 0 3 0 0 0 0 0 0]} 8 {1×1 struct} false false
0.13749 sec 1001 true {'VehicleState'} {[ 0 0 0 0]} 4 {1×1 struct} false false
0.38752 sec 1000 false {'EngineMsg' } {[68 3 102 0 0 0 0 0]} 8 {1×1 struct} false false
0.63753 sec 1000 false {'EngineMsg' } {[ 66 3 90 0 0 0 0 0]} 8 {1×1 struct} false false
0.63753 sec 1001 true {'VehicleState'} {[ 1 0 0 0]} 4 {1×1 struct} false false
0.88753 sec 1000 false {'EngineMsg' } {[61 3 103 0 0 0 0 0]} 8 {1×1 struct} false false
1.1375 sec 1000 false {'EngineMsg' } {[ 68 3 91 0 0 0 0 0]} 8 {1×1 struct} false false
1.1375 sec 1001 true {'VehicleState'} {[ 1 0 0 0]} 4 {1×1 struct} false false
1.3875 sec 1000 false {'EngineMsg' } {[67 3 103 0 0 0 0 0]} 8 {1×1 struct} false false
1.6376 sec 1000 false {'EngineMsg' } {[68 3 103 0 0 0 0 0]} 8 {1×1 struct} false false
1.6376 sec 1001 true {'VehicleState'} {[ 1 0 0 0]} 4 {1×1 struct} false false
1.8876 sec 1000 false {'EngineMsg' } {[ 67 3 94 0 0 0 0 0]} 8 {1×1 struct} false false
2.1376 sec 1000 false {'EngineMsg' } {[ 62 3 89 0 0 0 0 0]} 8 {1×1 struct} false false
2.1376 sec 1001 true {'VehicleState'} {[ 1 0 0 0]} 4 {1×1 struct} false false
2.3876 sec 1000 false {'EngineMsg' } {[ 66 3 93 0 0 0 0 0]} 8 {1×1 struct} false false
Stop the receiving channel and clear it from the workspace.
stop(rxCh);
clear rxChExamine a Received Message
Inspect a received message to see the applied database decoding.
rxMsg(10, :)
ans=1×8 timetable
Time ID Extended Name Data Length Signals Error Remote
__________ ____ ________ _____________ ______________________ ______ ____________ _____ ______
1.6376 sec 1000 false {'EngineMsg'} {[68 3 103 0 0 0 0 0]} 8 {1×1 struct} false false
rxMsg.Signals{10}ans = struct with fields:
VehicleSpeed: 68
TransmissionStatus: 'D'
GPSSpeed: 69.3333
EngineSpeed: 0
Extract All Instances of a Specified Message
Extract all instances of message EngineMsg.
allmsgEngine = rxMsg("EngineMsg" == rxMsg.Name, :);
allmsgEngine(1:15, :)ans=15×8 timetable
Time ID Extended Name Data Length Signals Error Remote
___________ ____ ________ _____________ ______________________ ______ ____________ _____ ______
0.13748 sec 1000 false {'EngineMsg'} {[ 0 3 0 0 0 0 0 0]} 8 {1×1 struct} false false
0.38752 sec 1000 false {'EngineMsg'} {[68 3 102 0 0 0 0 0]} 8 {1×1 struct} false false
0.63753 sec 1000 false {'EngineMsg'} {[ 66 3 90 0 0 0 0 0]} 8 {1×1 struct} false false
0.88753 sec 1000 false {'EngineMsg'} {[61 3 103 0 0 0 0 0]} 8 {1×1 struct} false false
1.1375 sec 1000 false {'EngineMsg'} {[ 68 3 91 0 0 0 0 0]} 8 {1×1 struct} false false
1.3875 sec 1000 false {'EngineMsg'} {[67 3 103 0 0 0 0 0]} 8 {1×1 struct} false false
1.6376 sec 1000 false {'EngineMsg'} {[68 3 103 0 0 0 0 0]} 8 {1×1 struct} false false
1.8876 sec 1000 false {'EngineMsg'} {[ 67 3 94 0 0 0 0 0]} 8 {1×1 struct} false false
2.1376 sec 1000 false {'EngineMsg'} {[ 62 3 89 0 0 0 0 0]} 8 {1×1 struct} false false
2.3876 sec 1000 false {'EngineMsg'} {[ 66 3 93 0 0 0 0 0]} 8 {1×1 struct} false false
2.6376 sec 1000 false {'EngineMsg'} {[ 64 3 94 0 0 0 0 0]} 8 {1×1 struct} false false
2.8876 sec 1000 false {'EngineMsg'} {[ 61 3 96 0 0 0 0 0]} 8 {1×1 struct} false false
3.1376 sec 1000 false {'EngineMsg'} {[67 3 100 0 0 0 0 0]} 8 {1×1 struct} false false
3.3876 sec 1000 false {'EngineMsg'} {[ 61 3 96 0 0 0 0 0]} 8 {1×1 struct} false false
3.6376 sec 1000 false {'EngineMsg'} {[ 65 3 92 0 0 0 0 0]} 8 {1×1 struct} false false
Plot Physical Signal Values
Use canSignalTimetable to repackage signal data from message EngineMsg into a signal timetable.
signalTimetable = canSignalTimetable(rxMsg, "EngineMsg");
signalTimetable(1:15, 1:3)ans=15×3 timetable
Time VehicleSpeed TransmissionStatus GPSSpeed
___________ ____________ __________________ ________
0.13748 sec 0 "D" 0
0.38752 sec 68 "D" 68.667
0.63753 sec 66 "D" 60.667
0.88753 sec 61 "D" 69.333
1.1375 sec 68 "D" 61.333
1.3875 sec 67 "D" 69.333
1.6376 sec 68 "D" 69.333
1.8876 sec 67 "D" 63.333
2.1376 sec 62 "D" 60
2.3876 sec 66 "D" 62.667
2.6376 sec 64 "D" 63.333
2.8876 sec 61 "D" 64.667
3.1376 sec 67 "D" 67.333
3.3876 sec 61 "D" 64.667
3.6376 sec 65 "D" 62
Plot the values of signal VehicleSpeed over time.
plot(signalTimetable.Time, signalTimetable.VehicleSpeed) title("Vehicle Speed from EngineMsg", "FontWeight", "bold") xlabel("Timestamp") ylabel("Vehicle Speed")

Close the ARXML File
Close access to the ARXML file by clearing the database variable from the workspace.
clear db