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_3222347_1501841/tp664f1e3f/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.23074 sec 1000 false {'EngineMsg' } {[ 0 3 0 0 0 0 0 0]} 8 {1×1 struct} false false
0.23075 sec 1001 true {'VehicleState'} {[ 0 0 0 0]} 4 {1×1 struct} false false
0.48041 sec 1000 false {'EngineMsg' } {[68 3 102 0 0 0 0 0]} 8 {1×1 struct} false false
0.73035 sec 1000 false {'EngineMsg' } {[ 66 3 90 0 0 0 0 0]} 8 {1×1 struct} false false
0.73035 sec 1001 true {'VehicleState'} {[ 1 0 0 0]} 4 {1×1 struct} false false
0.98036 sec 1000 false {'EngineMsg' } {[69 3 103 0 0 0 0 0]} 8 {1×1 struct} false false
1.2304 sec 1000 false {'EngineMsg' } {[ 69 3 96 0 0 0 0 0]} 8 {1×1 struct} false false
1.2304 sec 1001 true {'VehicleState'} {[ 1 0 0 0]} 4 {1×1 struct} false false
1.4804 sec 1000 false {'EngineMsg' } {[64 3 102 0 0 0 0 0]} 8 {1×1 struct} false false
1.7304 sec 1000 false {'EngineMsg' } {[ 66 3 89 0 0 0 0 0]} 8 {1×1 struct} false false
1.7304 sec 1001 true {'VehicleState'} {[ 1 0 0 0]} 4 {1×1 struct} false false
1.9804 sec 1000 false {'EngineMsg' } {[66 3 100 0 0 0 0 0]} 8 {1×1 struct} false false
2.2304 sec 1000 false {'EngineMsg' } {[ 66 3 91 0 0 0 0 0]} 8 {1×1 struct} false false
2.2304 sec 1001 true {'VehicleState'} {[ 1 0 0 0]} 4 {1×1 struct} false false
2.4805 sec 1000 false {'EngineMsg' } {[ 62 3 89 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.7304 sec 1000 false {'EngineMsg'} {[66 3 89 0 0 0 0 0]} 8 {1×1 struct} false false
rxMsg.Signals{10}ans = struct with fields:
VehicleSpeed: 66
TransmissionStatus: 'D'
GPSSpeed: 60
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.23074 sec 1000 false {'EngineMsg'} {[ 0 3 0 0 0 0 0 0]} 8 {1×1 struct} false false
0.48041 sec 1000 false {'EngineMsg'} {[68 3 102 0 0 0 0 0]} 8 {1×1 struct} false false
0.73035 sec 1000 false {'EngineMsg'} {[ 66 3 90 0 0 0 0 0]} 8 {1×1 struct} false false
0.98036 sec 1000 false {'EngineMsg'} {[69 3 103 0 0 0 0 0]} 8 {1×1 struct} false false
1.2304 sec 1000 false {'EngineMsg'} {[ 69 3 96 0 0 0 0 0]} 8 {1×1 struct} false false
1.4804 sec 1000 false {'EngineMsg'} {[64 3 102 0 0 0 0 0]} 8 {1×1 struct} false false
1.7304 sec 1000 false {'EngineMsg'} {[ 66 3 89 0 0 0 0 0]} 8 {1×1 struct} false false
1.9804 sec 1000 false {'EngineMsg'} {[66 3 100 0 0 0 0 0]} 8 {1×1 struct} false false
2.2304 sec 1000 false {'EngineMsg'} {[ 66 3 91 0 0 0 0 0]} 8 {1×1 struct} false false
2.4805 sec 1000 false {'EngineMsg'} {[ 62 3 89 0 0 0 0 0]} 8 {1×1 struct} false false
2.7304 sec 1000 false {'EngineMsg'} {[ 66 3 93 0 0 0 0 0]} 8 {1×1 struct} false false
2.9806 sec 1000 false {'EngineMsg'} {[ 64 3 94 0 0 0 0 0]} 8 {1×1 struct} false false
3.2304 sec 1000 false {'EngineMsg'} {[ 61 3 96 0 0 0 0 0]} 8 {1×1 struct} false false
3.4804 sec 1000 false {'EngineMsg'} {[ 64 3 98 0 0 0 0 0]} 8 {1×1 struct} false false
3.7304 sec 1000 false {'EngineMsg'} {[ 62 3 99 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.23074 sec 0 "D" 0
0.48041 sec 68 "D" 68.667
0.73035 sec 66 "D" 60.667
0.98036 sec 69 "D" 69.333
1.2304 sec 69 "D" 64.667
1.4804 sec 64 "D" 68.667
1.7304 sec 66 "D" 60
1.9804 sec 66 "D" 67.333
2.2304 sec 66 "D" 61.333
2.4805 sec 62 "D" 60
2.7304 sec 66 "D" 62.667
2.9806 sec 64 "D" 63.333
3.2304 sec 61 "D" 64.667
3.4804 sec 64 "D" 66
3.7304 sec 62 "D" 66.667
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