%% Read XCP Measurements with Direct Acquisition
% This example shows how to use the XCP protocol capability to connect and acquire data from a Simulink model deployed to a Windows executable. The example reads measurement parameters of the model using TCP and direct memory access. XCP is a high-level protocol used for accessing and modifying internal parameters and variables of a model, algorithm, or ECU. For more information, refer to the ASAM standards.
%
%% Algorithm Overview
% The algorithm used in this example is a Simulink model built and deployed as an XCP server. The model has already been compiled and is available to run in the file XCPServerSineWaveGenerator.exe. Additionally, an A2L-file is provided in XCPServerSineWaveGenerator.a2l as an output of that build process. The model contains three measurements and two characteristics accessible via XCP. Because the model is already deployed, Simulink is not required to run this example. The following image illustrates the model.
%
% For details about how to build a Simulink model, including an XCP server and generating an A2L-file, see Export ASAP2 File for Data Measurement and Calibration.
%
%% Run the XCP Server Model
% To communicate with the XCP server, the deployed model must be run. By using the system function, you can execute the XCPServerSineWaveGenerator.exe from inside MATLAB. The function requires constructing an argument list pointing to the executable. A separate command window opens and shows running outputs from the server.

sysCommand = ['"', fullfile(pwd, 'XCPServerSineWaveGenerator.exe'),'"', ' &'];
system(sysCommand);

%
%% Open the A2L-File
% An A2L-file is required to establish a connection to the XCP server. The A2L-file describes all of the functionality and capability that the XCP server provides, as well as the details of how to connect to the server. Use the xcpA2L function to open the A2L-file that describes the server model.

a2lInfo = xcpA2L("XCPServerSineWaveGenerator.a2l")

% TCP is the transport protocol used to communicate with the XCP server. Details for the TCP connection, such as the IP address and port number, are contained in the TransportLayerTCPInfo property.

a2lInfo.TransportLayerTCPInfo

%
%% Create an XCP Channel
% To create an active XCP connection to the server, use the xcpChannel function. The function requires a reference to the server A2L-file and the type of transport protocol to use for messaging with the server.

xcpCh = xcpChannel(a2lInfo, "TCP")

%
%% Connect to the Server
% To activate communication with the server, use the connect function.

connect(xcpCh)

%
%% Directly Acquire Measurement Data
% A measurement in XCP represents a variable in the memory of the model. Measurements available from the server are defined in the A2L-file. One way to read measurement data is using direct memory access. The readMeasurement function acquires the current value for a given measurement from the server. It is a single read at this moment without buffering.

readMeasurement(xcpCh, "Sine") 
readMeasurement(xcpCh, "SineAfterGain")
readMeasurement(xcpCh, "SineAfterTable")

%
%% Continuously Acquire Measurement Data
% It might be necessary to read a measurement continuously at some regular interval, such as for visualizing a value in a custom UI or using the value as input to some processing code. In such cases, readMeasurement is callable at any type of interval driven by a timer or loop. Below, readMeasurement is called in a fixed loop with no delay to accumulate and plot the values read. The value of the measurement is continuously changing in the memory of model, so not every data change is reflected in the plot as the values are relative to the rate of the read call itself. Reading measurements this way is best suited for asynchronous or low frequency purposes.

allSamples = zeros(30,1);
for ii = 1:30
    allSamples(ii) = readMeasurement(xcpCh, "Sine"); 
end
plot(allSamples, "o-")
title("Sine Measurement Data")
xlabel("Data Point")
ylabel("Data Value")

%
%% Disconnect from the Server
% To deactivate communication with the server, use the disconnect function. The XCP server can be safely closed after disconnecting.

disconnect(xcpCh)

%
%% Clean Up

clear a2lInfo

%
% Copyright 2021 The MathWorks, Inc.
%