Finding the sample time of a Simulink signal/line programmatically with Simulink.Block.getSampleTimes
Show older comments
I am trying to find the actual sample time of a signal/line in a Simulink model, programmatically, using Matlab commands.
So far I can't do it, although the information must be there, because Simulink can create the "Sample Time Color" overlay.
A simple demo model is attached, "FindSignalSampleTime.slx".

Clearly Simulink knows that the signal/line "Signal_1ms" has a discrete sample rate of 1e-3 s (1ms).
Now the challenge is to determine the sample time of that signal/line, called "Signal_1ms" programmatically. In this example I KNOW that the answer is 1e-3 s. But, so far, I cannot find a way to find it using code. How can it be done?
The handle of the signal can be found by:
loggedSignalName = 'Signal_1ms';
loggedSignalWire.Handle = find_system(modelName, ...
'FollowLinks','on', ...
'FindAll', 'on', ...
'LookUnderMasks','all',...
'type', 'line', ...
'Name', loggedSignalName);
fprintf('loggedSignalWire.Handle = %g\n', loggedSignalWire.Handle);
which produces
loggedSignalWire.Handle = 11.0004
I would like to now do:
ts = Simulink.Block.getSampleTimes(loggedSignalWire.Handle);
but that throws an error "The first argument to Simulink.Block.getSampleTimes must be a block".
Next I can find the "Source Port" that the line/signal is created by:
loggedSignalWireSrcPort.Handle = get_param(loggedSignalWire.Handle,'SrcPortHandle');
fprintf('loggedSignalWireSrcPortHandle = %g\n', loggedSignalWireSrcPort.Handle);
which produces
loggedSignalWireSrcPortHandle = 14.0004
Again, I would like to try:
ts = Simulink.Block.getSampleTimes(loggedSignalWireSrcPortHandle);
but again that throws an error "The first argument to Simulink.Block.getSampleTimes must be a block".
So finally I can find the block that contains that source port, and feeds the signal/line:
loggedSignalWireSrcPort.DataLoggingSampleTime = get_param(loggedSignalWireSrcPort.Handle, 'DataLoggingSampleTime');
loggedSignalWireSrcPort.ParentBlockName = get_param(loggedSignalWireSrcPort.Handle, 'Parent');
loggedSignalWireSrcPort.ParentBlockHandle = getSimulinkBlockHandle(loggedSignalWireSrcPort.ParentBlockName);
loggedSignalWireSrcPort.PortNumber = get_param(loggedSignalWireSrcPort.Handle, 'PortNumber');
fprintf('loggedSignalWireSrcPort.DataLoggingSampleTime = %s\n', loggedSignalWireSrcPort.DataLoggingSampleTime); % -1. Not much help.
fprintf('loggedSignalWireSrcPort.ParentBlockName = %s\n', loggedSignalWireSrcPort.ParentBlockName); % 'FindSignalSampleTime/SignalGeneration'
fprintf('loggedSignalWireSrcPort.ParentBlockHandle = %g\n', loggedSignalWireSrcPort.ParentBlockHandle); % 'slexVariableTransportDelayR2021bWithSimPowerSystems/vGain Library Variant Subsystem'
fprintf('loggedSignalWireSrcPort.PortNumber = %d\n', loggedSignalWireSrcPort.PortNumber); % 2
fprintf('Signal "%s" comes from output port %d of block handle %g with name "%s".\n', loggedSignalName, loggedSignalWireSrcPort.PortNumber, loggedSignalWireSrcPort.ParentBlockHandle, loggedSignalWireSrcPort.ParentBlockName);
which produces:
Signal "Signal_1ms" comes from output port 1 of block handle 4.00037 with name "FindSignalSampleTime/SignalGeneration".
Now finally a call to Simulink.Block.getSampleTimes() can return without error, using the handle for that whole block:
ts = Simulink.Block.getSampleTimes(loggedSignalWireSrcPort.ParentBlockHandle);
but the information I need is not there. The information only contains:
ts.Description = "Multirate"
ts.Value = ""
I would like the information in ts to tell me the sample rates for each output port, but it doesn't, it just says that the block is "Multirate", and that's not much help in this instance.
So I am still stuck with my problem. How can I determine the sample time of the signal/line? Simulink must know, but I can't find any valid commands/syntax that will tell me.
Answers (2)
Sumukh
on 30 Oct 2024
Hi Andrew,
The sample time is defined for a block, not a signal line. The sample time of the data on a signal line depends on the block it is connected to. The sample time of a particular block in a Simulink model can be obtained using the following command:
ts = Simulink.Block.getSampleTimes(block)
The “block” input argument must be a block handle and not a port handle. The output "ts" of this command is a “Simulink.SampleTime” object. You can refer to the following documentation to understand more about the command:
You can refer to the following documentation to understand more about the “Simulink.SampleTime” object returned as an output:
I hope this answers your query.
1 Comment
Andrew Roscoe
on 30 Oct 2024
Paul
on 30 Oct 2024
Hi Andrew,
If the block has multiple outputs, like in your case, check out
ts.ComponentSampleTimes
which should be an array of SampleTime obejcts, one for each output of the block.
Also, check out CompiledSampleTime at this doc page. Not sure if/how it differs from Simulink.Block.getSampleTimes.
8 Comments
Andrew Roscoe
on 31 Oct 2024
Edited: Andrew Roscoe
on 31 Oct 2024
Not sure why things aren't working with your model. Works here with a simple model.
% Build a simple model, with two Sine Wave blocks passing through a
% subsystem and feeding two scopes. Use differnt sample times for the Sine
% Wave blocks
bdclose('all');
hsys = new_system('andrew');
% uncomment this line to open the model in a Simulink canvas
%open_system(hsys);
hsin1 = add_block('simulink/Sources/Sine Wave','andrew/Sine1','SampleTime','0.1');
hsin2 = add_block('simulink/Sources/Sine Wave','andrew/Sine2','SampleTime','0.5');
hsub = add_block('simulink/Ports & Subsystems/Subsystem','andrew/subsys');
hin2 = add_block('andrew/subsys/In1','andrew/subsys/In2');
hout2 = add_block('andrew/subsys/Out1','andrew/subsys/Out2');
hscope1 = add_block('simulink/Sinks/Scope','andrew/scope1');
hscope2 = add_block('simulink/Sinks/Scope','andrew/scope2');
PH = 'PortHandles';
add_line(hsys, ...
get_param(hsin1,PH).Outport,...
get_param(hsub,PH).Inport(1));
add_line(hsys, ...
get_param(hsin2,PH).Outport,...
get_param(hsub,PH).Inport(2));
add_line(hsys, ...
get_param(hsub,PH).Outport(1),...
get_param(hscope1,PH).Inport);
add_line(hsys, ...
get_param(hsub,PH).Outport(2),...
get_param(hscope2,PH).Inport);
add_line(hsub, ...
get_param(hin2,PH).Outport,...
get_param(hout2,PH).Inport);
% get the sample times of the outputs of the subsystem block using
% getSampleTimes
ts = Simulink.Block.getSampleTimes('andrew/subsys')
ts.ComponentSampleTimes
ts.ComponentSampleTimes(1)
ts.ComponentSampleTimes(2)
% get the sample times of the output of the subsystem block using
% get_param. I think, but am not positive, that the feval calls are
% required.
feval('andrew',[],[],[],"compile");
dt = get_param(hsub,"CompiledSampleTime");
feval('andrew',[],[],[],"term");
dt
Not sure why neither of these approaches work with your model.
Are all three outputs of the SignalGeneration block scalar signals?
Checking the model posted in this comment there certainly seems to be something strange. Is there a chance that the screen cap in that comment is not from the model you attached? But even if that's the case, there is still strange behavior.
load_system('FindSignalSampleTime');
The SignalGeneration block has three output signals
ph = get_param('FindSignalSampleTime/SignalGeneration','PortHandles').Outport
Each output is a scalar signal
feval('FindSignalSampleTime',[],[],[],"compile");
portdim = get_param(ph,"CompiledPortDimensions");
feval('FindSignalSampleTime',[],[],[],"term");
portdim
But the names aren't what's shown in the screen cap, checked two different ways
get_param(ph,'Name')
get_param('FindSignalSampleTime/SignalGeneration','OutputSignalNames')
I really don't understand why ts has four elements
ts = Simulink.Block.getSampleTimes('FindSignalSampleTime/SignalGeneration')
ts.ComponentSampleTimes(1)
ts.ComponentSampleTimes(2)
ts.ComponentSampleTimes(3)
ts.ComponentSampleTimes(4)
And I don't understand why the CompiledSampleTime doesn't match the getSampleTimes.
EDIT (4 Nov 2024): This block of code calls get_param on the porthandles to get the CompiledSampleTime, which AFAICT is not documented behavior, even though it returns a result, though I'm not sure the result is correct.
feval('FindSignalSampleTime',[],[],[],"compile");
dt = get_param(ph,"CompiledSampleTime");
feval('FindSignalSampleTime',[],[],[],"term");
dt
The documented behavior is to get the CompliledSampleTime using the block as the input to get_param.
feval('FindSignalSampleTime',[],[],[],"compile");
dt = get_param('FindSignalSampleTime/SignalGeneration',"CompiledSampleTime");
feval('FindSignalSampleTime',[],[],[],"term");
dt
And now we are back to four outputs, which I think match the output of getSampleTimes.
Nothing makes senses.
Andrew Roscoe
on 4 Nov 2024
Andrew Roscoe
on 4 Nov 2024
I don't understand why your 2024b results are different than your 2021b results. I can only run 2024b here on Answers, and now I gather I was running it on a model built in 2021b (not that that should make a difference, but still). Maybe someone else will see this thread and try to work with an ealier version. I also don't understand why when I ran with with 2024b here on Answers (with th 2021b model) I got two warnings about unconnected ports, but you didn't when you ran it on your local installation. That is very odd if we were both working with the same model.
CompiledSampleTimes is not undocumented. It is shown on at Programmatically Specify Block Parameters and Properties in the Common Block Properties section, and according to that doc page requires the feval statements before and after the call to get_param to access that property. Now I realize that in working with your model above (but not with my toy model called 'andrew') I was calling get_param(ph,"CompiledSampleTime"). That is incorrect (even if it worked); the first argument is supposed to be a block, not a vector of port handles (at least as far as I can tell). I edited that comment to call get_param the correct way and got strange results.
There certainly seem to be lots of odd happenings in this thread, particularly, but not only, with getSampleTimes. Maybe open a case with TechSupport?
Paul
on 5 Nov 2024
I think, as in I'm pretty sure, that I misunderstood the intended functionality of Simulink.Block.getSampleTimes. I'm now pretty sure that's not the function to use.
I also agree with you that CompiledSampleTime is not a shown property of a port handle (I can't find any documenation on port handle properties at all).
There has to be a way to do what you want w/o resorting to using undocumented features and unshown object parameters ....
Andrew Roscoe
on 5 Nov 2024
Categories
Find more on MATLAB Compiler 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!

