The Display block in Simulink dynamically changes its icon during a simulation depending on the input signal (it displays the input signal value). I would like to create an own block which does the same. Sufficient would be to switch from a red to a green background when the input signal becomes non-zero. Programming the icon is trivial, the question is how to force a repaint of the icon, say, every 0.1s or when the input changes.
I tried...
Best would be to know how this was done in Display, since this block (and thus the feature) will probably persist forever.
The MultiStateImage block indicated in the comment does not have the flexibility to do whatever you want with the block icon.
I am not aware of a MATLAB command to trigger the repaint of Simulink interface, including icons. However, there is a trick that allows you to achieve what you want: create a MATLAB Function that sets the name of your block to its current name. You'd probably need coder.extrinsic('set_param');
and coder.extrinsic('get_param');
. Moreover you need to know the block ID (something as MyModel/MyBlock
. From my experience, changing the name of the function triggers a repaint of the icon, so doing that at each timestamp/sample time allows you to refresh the shown icon. I tested this approach on Simulink 2023b.
function updateBlocks()
coder.extrinsic('set_param');
coder.extrinsic('get_param');
blocks = {'untitled/Sin'};
for j=1:numel(blocks)
set_param(blocks{j}, 'Name', get_param(blocks{j}, 'Name'));
end
In order to actually change the icon according to the input signal(s) however, you should set the code of the icon to something like this:
rto = get_param(gcb, 'RunTimeObject');
if numel(rto)>0
inputPort = rto.InputPort(1);
inputValue = inputPort.Data;
fprintf("Block value is %d", inputValue);
else
fprintf("Block uninitialized");
end
Basically, you get the simulation object, its input port, and retrieve the value. The if condition avoids warnings when the simulation is not running (because no runtime object is associated to the block yet).
Here is a GIF showing the result. I used a sine block camouflaged with a mask icon. At the beginning I step through the simulation, then I let it run and the icon is updating. I suspect that the update rate is bounded to a certain limit, because the current simulation was run for about 1000 steps but I only got a bunch of values displayed. With slower simulation, this is not a problem, but I don't think that you could achieve fast FPS on the update in any way.
Hint: if you just want to display, your MATLABFunction can be masked as well so you avoid unnecessary blocks.
I also remember the possibility to add a Callback at each simulation step; this could avoid the need of having the MATLABFunction. However, I couldn't find the Callback in the new version, so either they removed it or I remember wrong.