In simulink, how can I make a parameter of a simulink block continuously updated during the simulation time by MATLAB function block?

30 views (last 30 days)
Hi, I'm building a simple electrical network that consists of sinusoidal voltage source + inductor-capacitor-resistor series network.
The sinusoidal voltage source has a parameterized frequency, 'freq', which is defined in my base workspace, and I want to update the value of the parameter 'freq' that is calculated in my MATLAB function block whenever some conditions are met.
So, I tried using the assignin() function in my MATLAB function block, as shown in the below code :
function [average_RF_phase_difference_time, array_buffer, phase_update_time_out, freq_tracking] = fcn(new_period_start, new_period_start_prev, RF_phase_difference_time, RF_phase_difference_time_array, time_simulation, phase_update_time, f_max, freq)
array_buffer = RF_phase_difference_time_array;
average_RF_phase_difference_time = mean(array_buffer);
phase_update_time_out = phase_update_time;
if (new_period_start_prev == false) && (new_period_start == true) && (phase_update_time_out + 1/(2*f_max) <= time_simulation)
phase_update_time_out = time_simulation;
RF_phase_difference_time_array_temp = circshift(RF_phase_difference_time_array, -1);
RF_phase_difference_time_array_temp(end) = RF_phase_difference_time;
array_buffer = RF_phase_difference_time_array_temp;
average_RF_phase_difference_time = mean(array_buffer);
new_freq = freq;
del_freq_clk = 1/(1/new_freq - 5e-9) - new_freq;
m = average_RF_phase_difference_time / (5e-9) / 4;
assignin('base','freq', new_freq - del_freq_clk * m );
freq_tracking = freq;
return
end
freq_tracking = freq;
end
The simulation ran without any error, but the result was different from my expectaion.
The frequency of the sinusoidal voltage source, 'freq', didn't get updated not during the simulation, but it changed after finishing the simulation as I checked from the base workspace. What I expected was the actual frequency of the sinusoidal voltage source is changed during the simulation run according to the calculation from the MATLAB function block.
So as the second step, I tried another way like below :
I tried to use the Data Store Memory block, but the variable defined in the Data Store Memory block cannot be recognized by the sinusoidal voltage source.
How can I realize as I intended? : making the actual frequency of the sinusoidal voltage source is changed "during the simulation run" according to the calculation from the MATLAB function block.
I really appreciate your helpful experiences in advance.

Accepted Answer

Paul
Paul on 20 Dec 2024 at 1:42
Edited: Paul on 23 Dec 2024 at 14:20
Hi Yeonghoon,
One option to try would be the Parameter Writer. Don't know if the particular block and block parameter in question are eligible for this approach.
If not, then I think you can try an Assertion Block that is fed by some other block that detects when the parameter in question changes. When the assertion is true, use the callback function with set_param commands to pause the simulation, update the diagram (having already assigned the new value of the variable in the base workspace in fcn), then restart the simulation.
TBH, I haven't ever tried either of these approaches, but I think I've seen an example of the latter in the doc, and there is blog post on the former that may be of interest.
Either approach will probably work better if your Matlab Function fcn is set to run with a discrete sample time, though a continuous sample time might be o.k., at least in principle.
Edit 23 Dec 2024: The callback code in the Assertion block does not need to pause, update, and restart. All that's needed is a block diagram update. At least that worked for me for a simple case, though using an assertion this way feels a bit kludgy.
  6 Comments
Yeonghoon
Yeonghoon on 28 Dec 2024 at 11:31
Hi Pual,
When I use 'update' instead of 'pause' and 'continue', now my simulink starts to update automatically..! I don't need to manually continue the simulation whenever it pauses.
However the parameter value for 'AC frequency', which is set to equal to base workspace variable 'freq', of my 'voltage source' block still doesn't update actually. I had the following warning from Diagnostic Viewer :
Failed to change the value of parameter 'ac_frequency' of block 'freqtracktest_4/Voltage_Source' during simulation as it is non-tunable. This might be because the value of 'ac_frequency' references a tunable variable whose value has changed. Restart the simulation or turn off fast restart to use the new value.
It seems the parameter 'ac_frequency' that I'm going to continuously update is not tunable. Maybe there are some parameters which are not allowed to be changed during simulation.
Thank you so much for your comments. It helped me a lot.
Paul
Paul on 28 Dec 2024 at 15:34
It appears that the waring in the Diagnostic Viewer arises because the "Configurability" parameter under "AC Voltage Frequency" is set to Compile-Time. The warning goes away if it's set to "Run-Time."
However, that doesn't really help because the masked parameter "ac frequency" has its Tunable attribute set to 'off', (right click on the Voltage Source block, then click Mask -> View Mask). If the Tunable attribute is 'off', then Simulink ignores changes to the mask parameter (freq_2 in the model in the question) on a diagram update while the simulation is running (even if paused).
I should've mentioned the tunability constraint in the original answer.
Just wanted to clarify what's happening.
The Controlled Voltage Source block is the far-superior solution.

Sign in to comment.

More Answers (0)

Categories

Find more on Test Model Components in Help Center and File Exchange

Products


Release

R2024b

Community Treasure Hunt

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

Start Hunting!