Execute Matlab function in Simulink

2 views (last 30 days)
Askic V
Askic V on 13 Feb 2024
Commented: Paul on 13 Feb 2024
Hello to all,
I have this Matlab function, i would like to execute in Simulink using "User-Defined->Matlab Function" from the Library.
This is the function I want to execute:
function y = moving_average2(u, Tf, Ts)
% Check if the input data is long enough
N = ceil(Tf/Ts);
if numel(u) < N
N = numel(u);
end
% Initialize the result array
y = zeros(size(u));
disp(N)
% Calculate the moving average
for i = N:numel(u)
y(i) = mean(u(i-N+1:i));
end
end
and when tested, I have called this function from the following simple script:
clear; clc; close all
t = 0:0.1:10;
u = sin(t);
Tf = 2; T = 0.1;
y = moving_average(u, Tf, T);
plot(t, u);hold on; grid on;
plot(t, y, 'r');
legend("Input", "Output");
The above script when executed produce the following result:
However, when this very same function is called from the Simulink as shown in picture:
The result is very different, as if averaging is not applied at all. Input and output signals are matching perfectly (Simulation s 10 sec, auto, fixed size (auto).
Can you please suggest what I'm doing wrong?
My guess it is because Simulink executes this function for each input sample, and that is the difference comparing with the script, so basically I would need to modife the function as it would be called in an infinite loop in cyclic manner.
Thank you!

Accepted Answer

Paul
Paul on 13 Feb 2024
You are correct. In Matlab, the code looks like this (actually making the call to moving_average2)
t = 0:0.1:10;
u = sin(t);
Tf = 2; T = 0.1;
%y = moving_average(u, Tf, T);
y = moving_average2(u, Tf, T);
figure
plot(t, u);hold on; grid on;
plot(t, y, 'r');
legend("Input", "Output");
In Simulink, the implementation is essentially a loop on scalar values of u, one for each value of t (assuming the simulink step size is 0.1 for illustration). As the disp command would show (I commented it out), in Simulink it's just a one point moving average.
figure
for tval = t
u = sin(tval);
Tf = 2; T = 0.1;
%y = moving_average(u, Tf, T);
y = moving_average2(u, Tf, T);
plot(tval, u,'o');hold on; grid on;
plot(tval, y, 'or');
legend("Input", "Output");
end
Is there a reason you want to use this function in Simulink instead of just computing the moving average wtih a simplle transfer function block (though some extra work would be required if you really want the output to be zero for the first N-1 samples.
function y = moving_average2(u, Tf, Ts)
% Check if the input data is long enough
N = ceil(Tf/Ts);
if numel(u) < N
N = numel(u);
end
% Initialize the result array
y = zeros(size(u));
%disp(N)
% Calculate the moving average
for i = N:numel(u)
y(i) = mean(u(i-N+1:i));
end
end
  2 Comments
Askic V
Askic V on 13 Feb 2024
Hi Paul and thank you for your answer.
Of course, this is not the actual example I'm working on, but something I prepared just to confirm my assumption.
Actually, I need to simulate in Simulink a Matlab function (among other things and blocks from the standard library) that simulates behaviour of a PLC block. In PLC programming there are functions but also function blocks that has static memory and remember values between calls.
Matlab doesn't have a function block so I need to use a function. This function will calculate some dynamics, like first and second order system, but will have also a number of binary signals that represent various status values with a lot of if/else statements and even boolean operations such as AND, OR, XOR etc.
The easiest way to combine all would be to write function and execute this as a separate "block" in Simulink.
I have managed to make this function with using global and persistent variables, but I experienced some problems build a model that are perhaps for another question.
Paul
Paul on 13 Feb 2024
Persistent variables inside a Matlab Function block is certainly one option to model static memory. Another option would be to take outputs from the Matlab Function block and route them through one of the delay blocks, like Dleay or Tapped Delay as needed, and feed the output of the delay block back around as input to the Matlab Function. In your example of the moving average (which I realize was just for illustration) you could add a Tapped Delay block on the sine wave to send into the Matlab Function the current value and N-1 most recent values of that sin as a vetor input with N elements.

Sign in to comment.

More Answers (0)

Categories

Find more on Simulink Functions in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!