%% Use Relative and Absolute Timestamps in CAN Communication
% This example shows you how to use the InitialTimestamp property of a CAN channel to work with relative and absolute timestamps for CAN messages. It uses MathWorks virtual CAN channels connected in a loopback configuration. This example describes the workflow for a CAN network, but the concept demonstrated also applies to a CAN FD network.
%
%% Open the DBC-File
% Open the DBC-file to access the database definitions.

db = canDatabase("VehicleInfo.dbc")

%
%% Create the CAN Channels
% Create CAN channels on which you can transmit and receive messages.

txCh = canChannel("MathWorks", "Virtual 1", 1)
rxCh = canChannel("MathWorks", "Virtual 1", 2)

% Attach the database directly to the receiving channel to apply database definitions to incoming messages automatically.

rxCh.Database = db;

%
%% Create the CAN Message
% Create a new CAN message by specifying the database and the message name WheelSpeeds to have the database definition applied.

msg = canMessage(db, "WheelSpeeds")

%
%% Start the CAN Channels
% Start the channels to begin using them for transmission and reception.

start(rxCh)
start(txCh)

%
%% Transmit CAN Messages
% The transmit function sends messages onto the network. Use pause to add delays between the transmit operations. Update the LF_WSpeed signal value before each transmission.

msg.Signals.LF_WSpeed = 10;
transmit(txCh, msg)
pause(1);
msg.Signals.LF_WSpeed = 20;
transmit(txCh, msg)
pause(2);
msg.Signals.LF_WSpeed = 30;
transmit(txCh, msg)
pause(3);
msg.Signals.LF_WSpeed = 40;
transmit(txCh, msg)
pause(1);
msg.Signals.LF_WSpeed = 50;
transmit(txCh, msg)

%
%% Receive the CAN Messages
% The receive function receives CAN messages that occurred on the network.

stop(rxCh)
stop(txCh)
msgRx = receive(rxCh, Inf, "OutputFormat", "timetable")

%
%% Inspect Signal Data
% Use canSignalTimetable to repackage signal data from the received messages into a signal timetable. Note that timestamp values represent time elapsed from the start of the CAN channel.

signalTimetable = canSignalTimetable(msgRx)
plot(signalTimetable.Time, signalTimetable.LF_WSpeed, "x")
title("Signal Data with Relative Time", "FontWeight", "bold")
xlabel("Relative Timestamp")
ylabel("Signal Value")
ylim([0 60])

%
%% Inspect InitialTimestamp Property
% View the InitialTimestamp property of the receiving CAN channel. It is a datetime value that represents the absolute time of when the channel is started.

rxCh.InitialTimestamp

%
%% Analyze Data with Absolute Timestamps
% Combine the relative timestamp of each message and the InitialTimestamp property to obtain the absolute timestamp of each message. Set the absolute timestamps back into the message timetable as the time vector.

msgRx.Time = msgRx.Time + rxCh.InitialTimestamp

% The signal timetable created from the updated message timetable now also has absolute timestamps.

signalTimetable = canSignalTimetable(msgRx)
figure
plot(signalTimetable.Time, signalTimetable.LF_WSpeed, "x")
title("Signal Data with Absolute Time", "FontWeight", "bold")
xlabel("Absolute Timestamp")
ylabel("Signal Value")
ylim([0 60])

%
%% Close the Channels and DBC-File
% Close access to the channels and the DBC-file by clearing their variables from the workspace.

clear rxCh txCh
clear db

%
% Copyright 2015-2021 The MathWorks, Inc.