Этот пример показывает вам, как создать, получить и обработать сообщения с помощью информации, хранившей в файлах базы данных CAN. Этот пример использует файл базы данных CAN, demoVNT_CANdbFiles.dbc.
Откройте файл базы данных и исследуйте свойство Messages видеть имена всего сообщения, заданного в этой базе данных.
db = canDatabase('demoVNT_CANdbFiles.dbc')
db.Messages
db =
Database with properties:
Name: 'demoVNT_CANdbFiles'
Path: '/tmp/BR2019ad_1035872_198992/publish_examples0/tpebbfa76f/ex80654288/demoVNT_CANdbFiles.dbc'
Nodes: {}
NodeInfo: [0x0 struct]
Messages: {5x1 cell}
MessageInfo: [5x1 struct]
Attributes: {}
AttributeInfo: [0x0 struct]
UserData: []
ans =
5x1 cell array
{'DoorControlMsg' }
{'EngineMsg' }
{'SunroofControlMsg'}
{'TransmissionMsg' }
{'WindowControlMsg' }
Используйте messageInfo, чтобы просмотреть информацию о сообщении, включая идентификатор, длину данных и список сигнала.
messageInfo(db, 'EngineMsg')
ans =
struct with fields:
Name: 'EngineMsg'
ProtocolMode: 'CAN'
Comment: ''
ID: 100
Extended: 0
J1939: []
Length: 8
DLC: 8
BRS: 0
Signals: {2x1 cell}
SignalInfo: [2x1 struct]
TxNodes: {0x1 cell}
Attributes: {}
AttributeInfo: [0x0 struct]
Можно также запросить для получения информации обо всех сообщениях целиком.
messageInfo(db)
ans =
5x1 struct array with fields:
Name
ProtocolMode
Comment
ID
Extended
J1939
Length
DLC
BRS
Signals
SignalInfo
TxNodes
Attributes
AttributeInfo
Используйте signalInfo, чтобы просмотреть информацию об определении сигнала, включая тип, порядок байтов, размер и масштабирующиеся значения, которые переводят необработанные сигналы в физические значения.
signalInfo(db, 'EngineMsg', 'EngineRPM')
ans =
struct with fields:
Name: 'EngineRPM'
Comment: ''
StartBit: 0
SignalSize: 32
ByteOrder: 'LittleEndian'
Signed: 0
ValueType: 'Integer'
Class: 'uint32'
Factor: 0.1000
Offset: 250
Minimum: 250
Maximum: 9500
Units: 'rpm'
ValueTable: [0x1 struct]
Multiplexor: 0
Multiplexed: 0
MultiplexMode: 0
RxNodes: {0x1 cell}
Attributes: {}
AttributeInfo: [0x0 struct]
Можно также запросить для получения информации обо всех сигналах в сообщении целиком.
signalInfo(db, 'EngineMsg')
ans =
2x1 struct array with fields:
Name
Comment
StartBit
SignalSize
ByteOrder
Signed
ValueType
Class
Factor
Offset
Minimum
Maximum
Units
ValueTable
Multiplexor
Multiplexed
MultiplexMode
RxNodes
Attributes
AttributeInfo
Задайте имя сообщения, когда вы создадите новое сообщение, чтобы применить определение базы данных. Сигналы CAN в этом обмениваются сообщениями, представлены в технических модулях в дополнение к байтам необработанных данных.
msgEngineInfo = canMessage(db, 'EngineMsg')
msgEngineInfo =
Message with properties:
Message Identification
ProtocolMode: 'CAN'
ID: 100
Extended: 0
Name: 'EngineMsg'
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: []
Используйте свойство Signals видеть значения сигналов для этого сообщения. Можно непосредственно записать в и читать из этих сигналов упаковать или распаковать данные из сообщения.
msgEngineInfo.Signals
ans =
struct with fields:
VehicleSpeed: 0
EngineRPM: 250
Запишите непосредственно в сигнал изменить значение и считать его текущее значение назад.
msgEngineInfo.Signals.EngineRPM = 5500.25 msgEngineInfo.Signals
msgEngineInfo =
Message with properties:
Message Identification
ProtocolMode: 'CAN'
ID: 100
Extended: 0
Name: 'EngineMsg'
Data Details
Timestamp: 0
Data: [23 205 0 0 0 0 0 0]
Signals: [1x1 struct]
Length: 8
Protocol Flags
Error: 0
Remote: 0
Other Information
Database: [1x1 can.Database]
UserData: []
ans =
struct with fields:
VehicleSpeed: 0
EngineRPM: 5.5003e+03
Когда вы пишете непосредственно в сигнал, значение переводится, масштабируется и упаковывается в данные о сообщении с помощью определения базы данных.
msgEngineInfo.Signals.VehicleSpeed = 70.81 msgEngineInfo.Signals
msgEngineInfo =
Message with properties:
Message Identification
ProtocolMode: 'CAN'
ID: 100
Extended: 0
Name: 'EngineMsg'
Data Details
Timestamp: 0
Data: [23 205 0 0 71 0 0 0]
Signals: [1x1 struct]
Length: 8
Protocol Flags
Error: 0
Remote: 0
Other Information
Database: [1x1 can.Database]
UserData: []
ans =
struct with fields:
VehicleSpeed: 71
EngineRPM: 5.5003e+03
Присоедините базу данных к каналу CAN, который получает сообщения, чтобы применить определения базы данных входящим сообщениям автоматически. База данных декодирует только сообщения, которые заданы. Все другие сообщения получены в их необработанной форме.
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: [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: [1x1 can.Database]
UserData: []
Запустите канал, генерируйте некоторый трафик сообщения и получите сообщения с физическим декодированием сообщений.
start(rxCh); generateMsgsDb(); rxMsg = receive(rxCh, Inf, 'OutputFormat', 'timetable'); rxMsg(1:15, :)
ans =
15x8 timetable
Time ID Extended Name Data Length Signals Error Remote
_____________ ___ ________ ___________________ ___________ ______ ____________ _____ ______
0.0023549 sec 100 false 'EngineMsg' [1x8 uint8] 8 [1x1 struct] false false
0.0023609 sec 200 false 'TransmissionMsg' [1x8 uint8] 8 [1x1 struct] false false
0.0023634 sec 400 false 'DoorControlMsg' [1x8 uint8] 8 [1x1 struct] false false
0.0023663 sec 600 false 'WindowControlMsg' [1x4 uint8] 4 [1x1 struct] false false
0.0023673 sec 800 false 'SunroofControlMsg' [1x2 uint8] 2 [1x1 struct] false false
0.027356 sec 100 false 'EngineMsg' [1x8 uint8] 8 [1x1 struct] false false
0.052356 sec 100 false 'EngineMsg' [1x8 uint8] 8 [1x1 struct] false false
0.052357 sec 200 false 'TransmissionMsg' [1x8 uint8] 8 [1x1 struct] false false
0.077356 sec 100 false 'EngineMsg' [1x8 uint8] 8 [1x1 struct] false false
0.10236 sec 100 false 'EngineMsg' [1x8 uint8] 8 [1x1 struct] false false
0.10236 sec 200 false 'TransmissionMsg' [1x8 uint8] 8 [1x1 struct] false false
0.12736 sec 100 false 'EngineMsg' [1x8 uint8] 8 [1x1 struct] false false
0.12737 sec 400 false 'DoorControlMsg' [1x8 uint8] 8 [1x1 struct] false false
0.15236 sec 100 false 'EngineMsg' [1x8 uint8] 8 [1x1 struct] false false
0.15236 sec 200 false 'TransmissionMsg' [1x8 uint8] 8 [1x1 struct] false false
Остановите канал и очистите его от рабочей области.
stop(rxCh);
clear rxCh
Осмотрите полученное сообщение, чтобы видеть, что прикладная база данных декодирует.
rxMsg(10, :)
rxMsg.Signals{10}
ans =
1x8 timetable
Time ID Extended Name Data Length Signals Error Remote
___________ ___ ________ ___________ ___________ ______ ____________ _____ ______
0.10236 sec 100 false 'EngineMsg' [1x8 uint8] 8 [1x1 struct] false false
ans =
struct with fields:
VehicleSpeed: 50
EngineRPM: 3.5696e+03
Используйте обозначение MATLAB, чтобы извлечь все экземпляры заданного сообщения по наименованию.
allMsgEngine = rxMsg(strcmpi('EngineMsg', rxMsg.Name), :);
allMsgEngine(1:15, :)
ans =
15x8 timetable
Time ID Extended Name Data Length Signals Error Remote
_____________ ___ ________ ___________ ___________ ______ ____________ _____ ______
0.0023549 sec 100 false 'EngineMsg' [1x8 uint8] 8 [1x1 struct] false false
0.027356 sec 100 false 'EngineMsg' [1x8 uint8] 8 [1x1 struct] false false
0.052356 sec 100 false 'EngineMsg' [1x8 uint8] 8 [1x1 struct] false false
0.077356 sec 100 false 'EngineMsg' [1x8 uint8] 8 [1x1 struct] false false
0.10236 sec 100 false 'EngineMsg' [1x8 uint8] 8 [1x1 struct] false false
0.12736 sec 100 false 'EngineMsg' [1x8 uint8] 8 [1x1 struct] false false
0.15236 sec 100 false 'EngineMsg' [1x8 uint8] 8 [1x1 struct] false false
0.17736 sec 100 false 'EngineMsg' [1x8 uint8] 8 [1x1 struct] false false
0.20237 sec 100 false 'EngineMsg' [1x8 uint8] 8 [1x1 struct] false false
0.22737 sec 100 false 'EngineMsg' [1x8 uint8] 8 [1x1 struct] false false
0.25237 sec 100 false 'EngineMsg' [1x8 uint8] 8 [1x1 struct] false false
0.27736 sec 100 false 'EngineMsg' [1x8 uint8] 8 [1x1 struct] false false
0.30237 sec 100 false 'EngineMsg' [1x8 uint8] 8 [1x1 struct] false false
0.32737 sec 100 false 'EngineMsg' [1x8 uint8] 8 [1x1 struct] false false
0.35237 sec 100 false 'EngineMsg' [1x8 uint8] 8 [1x1 struct] false false
Постройте значения декодируемых сигналов базы данных в зависимости от времени. Сошлитесь на метки времени сообщения и значения сигналов в переменных.
signalTimetable = canSignalTimetable(rxMsg, 'EngineMsg'); signalTimetable(1:15, :) plot(signalTimetable.Time, signalTimetable.VehicleSpeed) title('Vehicle Speed from EngineMsg', 'FontWeight', 'bold') xlabel('Timestamp') ylabel('Vehicle Speed')
ans =
15x2 timetable
Time VehicleSpeed EngineRPM
_____________ ____________ _________
0.0023549 sec 0 250
0.027356 sec 50 3569.6
0.052356 sec 50 3569.6
0.077356 sec 50 3569.6
0.10236 sec 50 3569.6
0.12736 sec 50 3569.6
0.15236 sec 55 3621.3
0.17736 sec 55 3621.3
0.20237 sec 55 3621.3
0.22737 sec 55 3621.3
0.25237 sec 55 3663.9
0.27736 sec 55 3663.9
0.30237 sec 55 3663.9
0.32737 sec 55 3663.9
0.35237 sec 54 3598.1
