%% Periodic CAN Message Transmission
% This example shows you how to use the automated CAN message transmit
% features of Vehicle Network Toolbox(TM) to send periodic messages. It 
% uses MathWorks Virtual CAN channels connected in a loopback configuration.
% As this example is based on sending and receiving CAN messages
% on a virtual network, running Vehicle CAN Bus Monitor in conjunction may
% provide a more complete understanding of what the code is doing. To
% run Vehicle CAN Bus Monitor, open and configure it to use the same 
% interface as the receiving channel of the example. Make sure to start 
% Vehicle CAN Bus Monitor before beginning to run the example in order to 
% see all of the messages as they occur.
%
% Copyright 2010-2016 The MathWorks, Inc.

%% Create the CAN Channels
% Create CAN channels on which to use the automated message transmit
% commands.
txCh = canChannel('MathWorks', 'Virtual 1', 1);
rxCh = canChannel('MathWorks', 'Virtual 1', 2);

%%
% In this example, you will use a CAN database file to define and decode
% messages. Open the database and attach it to the CAN channels.
db = canDatabase('demoVNT_CANdbFiles.dbc');
txCh.Database = db;
rxCh.Database = db;

%% Create the CAN Messages
% You can create CAN messages to register for periodic transmit using the
% database information.
msgFast = canMessage(db, 'EngineMsg')
msgSlow = canMessage(db, 'TransmissionMsg')

%% Configure Messages for Periodic Transmit
% To configure a message for periodic transmit, use the |transmitPeriodic|
% command to specify the channel, the message to register on the channel,
% a mode value, and the periodic rate.
transmitPeriodic(txCh, msgFast, 'On', 0.100);
transmitPeriodic(txCh, msgSlow, 'On', 0.500);

%% Start the Periodic Message Transmit
% When you start a channel which has periodic messages registered,
% transmit begins immediately. Allow the channels run for a short time.
start(rxCh);
start(txCh);
pause(2);

%% Modify Transmitted Data
% To update the live message or signal data sent onto the CAN bus, write new
% values into the message you originally created using either the Data
% property or the signals interface.
msgFast.Signals.VehicleSpeed = 60;
pause(1);
msgFast.Signals.VehicleSpeed = 65;
pause(1);
msgFast.Signals.VehicleSpeed = 70;
pause(1);

%% Receive the Messages
% Stop the CAN channels and receive all periodically transmitted messages 
% for analysis.
stop(txCh);
stop(rxCh);
msgRx = receive(rxCh, Inf, 'OutputFormat', 'timetable');
msgRx(1:15, :)

%% Analyze the Periodic Transmit Behavior
% You can analyze the distribution of messages by plotting the 
% identifiers of each message against their timestamps. Notice the
% difference between how often the two messages appear according to their
% periodic rates.
plot(msgRx.Time, msgRx.ID, 'x')
ylim([0 400])
title('Message Distribution', 'FontWeight', 'bold')
xlabel('Timestamp')
ylabel('CAN Identifier')

%% 
% For further analysis, separate the two messages into individual timetables.
msgRxFast = msgRx(strcmpi('EngineMsg', msgRx.Name), :);
msgRxFast(1:10, :)
msgRxSlow = msgRx(strcmpi('TransmissionMsg', msgRx.Name), :);
msgRxSlow(1:10, :)

%%
% Analyze the timestamps of each set of messages to see how closely the 
% average of the differences corresponds to the configured periodic rates.
avgPeriodFast = mean(diff(msgRxFast.Time))
avgPeriodSlow = mean(diff(msgRxSlow.Time))

%%
% A plot of the received signal data reflects the updates in the message
% data sent on the CAN bus.
signalTimetable = canSignalTimetable(msgRx, 'EngineMsg');
signalTimetable(1:10, :)
plot(signalTimetable.Time, signalTimetable.VehicleSpeed)
title('Vehicle Speed from EngineMsg', 'FontWeight', 'bold')
xlabel('Timestamp')
ylabel('Vehicle Speed')
ylim([-5 75])

%% View Messages Configured for Periodic Transmit
% To see messages configured on a channel for periodic transmit, use the
% |transmitConfiguration| command.
transmitConfiguration(txCh)
