Yesterday, I was giving a training to new hires at MathWorks and one of the attendees asked me how to hold a value in Simulink.
Of course, my answer was that there are many ways to hold a value in Simulink. I made him a few examples that I am sharing today in this post.
The Desired Behavior
I want to create a subsystem with two inputs, u and hold, and one output y. When hold is true, the output y is equal to the input u. When hold is zero, the output y remains constant, holding the last output value.
Here are example input and output signals:
Let's see a few ways to obtain such behavior
Method 1: Switch and Delay
Nice, clean and simple!
Method 2: Enabled Subsystem
I like this method because it takes virtually no blocks.
Method 3: If Action Subsystems and Delay
Personally, I don't use this syntax very often, mostly because it requires more blocks.
Method 4: Stateflow
Another easy way to obtain the behavior we are looking for is using Stateflow
What about the generated code?
When choosing an implementation, many factors need to be taken into account. One of my favorite guidelines for was suggested by a reader of this blog: Clearly show the intended functionality. I will let you judge by yourself which implementation most clearly shows the intention of holding a signal.
Another concern that many users have is: What does the code look like?
In this case, all the methods generate similar code. to make the code easier to read for this post, I set the storage class of the three signals or interest (hold, u, y) to ExportedGlobal.
Switch and Delay:
***Note: To obtain the above code, I enabled inline parameters from the model configuration. Otherwise the threshold of the switch is a tunable parameter.
If Action Subsystem:
***Note: To obtain the above code, I manually set the Function Packaging option of the If Action Subsystem to Inline. Otherwise, since the two subsystems are identical, the coder generates a reusable function.
Now it's your turn
What is your preferred method to hold the value of a signal? Are there other functionalities for which you consider multiple implementations? Let us know by leaving a comment here.
13 CommentsOldest to Newest
Using a MATLAB Function with a persistent variable is another good way, I think. An advantage is, that all comments within this function also appear in the generated code.
@alex: Thank you for mentioning the MATLAB function block. One thing to be careful when using persistent variables in the MATLAB Function block is the sample time. With a discrete sample time, everything works perfectly. If the block takes a continuous sample time, you might see surprising results, or cause a variable-step solver to hang.
I’ve used the Unit Delay Enabled block with the input signal connected to “u”, and the hold signal connected to “E”. It is compatible with HDL coder.
@Mark Brown: That’s interesting, but with only the Unit Delay block, the result will be different. When enabled, there is a delay of one sample between the input and output. I would need to verify, but I think all the methods above are compatible with HDL Coder. I am sure the firs method above is compatible.
Thank you sir, for your post
What would be your recommendation for holding the value of a vector of unknown dimensions, where each dimension may have different reset triggers?
@Jeremy Weirich: My first bet would be to put any of the above in a For Each subsystem. That way each component of the vector can be held or not independently, based on different triggers.
Let me know if that does not do what you are looking for.
You can simply use the “Sample and Hold” block to do the job.
@Joel: Good point. The “Sample and Hold” block is included with the DSP System toolbox. If you look under the mask, you will see that it is infact a Triggered Subsystem. This is a solution very similar to the Enabled Subsystem approach mentioned in this post.
In method 1 , 2 ,3 ….can i insert a sine wave as an input and a clock signal as the hold …. i tried that but didnt work …can anyone help ,plz ?
Exactly what I was looking for! Many thanks mate :)
Thanks a lot for your examples. What about the following case: when the hold is true we hold u value, but when the hold is zero we hold the next u value
Thank you. This is very very useful post for me.