Beckhoff - Ramp that can be interrupted/updated while ramping operation is in progress - plc

I am looking for a way to ramp lights properly. This function block looked like a good candidate :
https://infosys.beckhoff.com/english.php?content=../content/1033/tcplclibbabasic/11640060811.html&id=
Unfortunately, it will ignore any subsequent nEndLevel updates. So while ramp is in progress any new values of nEndLevel
Are ignored where what is usually needed from this type of ramp is to stop the current ramping operation and start a new one as soon as new nEndLevel value is received.
Is there any other ramp function block in the Beckhoff library that can do that ?
I need a ramp that can be interrupted/updated while ramping operation is in progress basically.

I don't think you need another function block...
A rising-edge at bStart starts dimming the light from the actual to the end-level (nEndLevel)
bStart: This input starts the dim-ramp from the actual value to nEndLevel within the time defined as tRampTime. This can be interrupted by bOn, bOff or bToggle at any time.
As I understand it, a rising edge on bStart starts a new ramp.
You could try to detect the change in the value of nEndLevel and generate a rising edge on bStart, which should make it generate a new ramp. For example, using a temporary variable nEndLevel_old that retain the old value for comparison in the next cycle.

Related

How do you schedule a fade-out using setTargetAtTime

I am having problems with the 'windowing', as it's called, of pitch-shifted grains of sounds using the Web Audio API. When I play the sound, I successfully set the initial gain to 0, using setValueAtTime, and successfully fade the sound in using linearRampToValueAtTime. However, I am not successful in scheduling a fade-out to occur slightly before the sound ends. It may be because the sound is pitch-shifted, although in the code below, I believe I have set the parameters correctly. Though maybe the final parameter in setTargetAtTime is not suitable because I don't fully understand that parameter, despite having read Chris's remarks on the matter. How does one successfully schedule a fade-out when the sound is pitch-shifted, using setTargetAtTime? Below is my code. You can see the piece itself at https://vispo.com/animisms/enigman2/2022
source.buffer = audioBuffer;
source.connect(this.GrainObjectGain);
this.GrainObjectGain.connect(app.mainGain);
source.addEventListener('ended', this.soundEnded);
//------------------------------------------------------------------------
// Now we do the 'windowing', ie, when we play it, we fade it in,
// and we set it to fade out at the end of play. The fade duration
// in seconds is a maximum of 10 milliseconds and
// a minimum of 10% of the duration of the sound. This helps
// eliminate pops.
source.playbackRate.value = this.playbackRate;
var fadeDurationInSeconds = Math.min(0.01,0.1*duration*this.playbackRate);
this.GrainObjectGain.gain.setValueAtTime(0, app.audioContext.currentTime);
this.GrainObjectGain.gain.linearRampToValueAtTime(app.constantGrainGain, app.audioContext.currentTime+fadeDurationInSeconds);
this.GrainObjectGain.gain.setTargetAtTime(0, app.audioContext.currentTime+duration*this.playbackRate-fadeDurationInSeconds, fadeDurationInSeconds);
source.start(when, offset, duration);
Given your comment below I guess you want to schedule the fade out fadeDurationInSeconds before the sound ends.
Since you change playbackRate you need to divide the original duration by that playbackRate to get the actual duration.
Changing your setTargetAtTime() call as follows should schedule the fade out at the desired point in time.
this.GrainObjectGain.gain.setTargetAtTime(
0,
app.audioContext.currentTime + duration / this.playbackRate - fadeDurationInSeconds,
fadeDurationInSeconds
);
Please not that setTargetAtTime() actually never reaches the target. At least in theory. It comes reasonably close though after some time. But that time is longer as the timeConstant.
The relevant text from the spec can be found here: https://webaudio.github.io/web-audio-api/#dom-audioparam-settargetattime
Start exponentially approaching the target value at the given time with a rate having the given time constant. Among other uses, this is useful for implementing the "decay" and "release" portions of an ADSR envelope. Please note that the parameter value does not immediately change to the target value at the given time, but instead gradually changes to the target value.
The timeConstant parameter roughly defines the time it takes to reach 2/3 of the desired signal attenuation.
It's mentioned here: https://webaudio.github.io/web-audio-api/#dom-audioparam-settargetattime-timeconstant
More precisely, timeConstant is the time it takes a first-order linear continuous time-invariant system to reach the value 1−1/𝑒 (around 63.2%) given a step input response (transition from 0 to 1 value).

How to pause a for loop in MATLAB to create snapshots?

So I'm sunning a code which solves an equation over a given period of time. As one would expect, the solution will change as time evolves so I wanted to create some sort of for loop which has the effect of creating "snapshots", which is to say I intend to pause the output at set intervals.
How might I go about implementing such a function?
I was hoping to implement something which pauses the code at defined intervals and then resumes execution on a button press.

How to store a specific time that a signal value is changed in another parameter in Matlab simulink?

I have two Matlab function blocks that one is producing zero signal for the other. I want to store the exact time that signal changes to one in another parameter in order to use it elsewhere.
How can I do it?
This type of functinality is achieved using a Triggered Subsystem, as per the image below,
The output of the trigger block will take on value of the input (which in this case is the simulation time) every time the trigger signal rises. Look at the parameters of the Trigger block inside the subsystem for other options such as falling edge, or both edge, triggering.

Matlab Stateflow - after() function on transition not working

In my Stateflow model the after() function is not working. If i put for examle after(10,sec) there is no delay in the states, it switches directly from on to the next. I use a Pulse Generator as an eternal clock for Stateflow with following values:
Could this be a reason for that behavior? Are there other related setting?
The after condition says to do something after you have been in a given state for the specified period of time (in your case 10 seconds). The pulse generator you show is set to have rising and falling signals every 1 second. So, without seeing more information about your model, the suspicion would be that you are never in a state long enough for the after condition to become true.
It would help if you showed more of your model.

Is it possible to stop a Simulink simulation when a certain condition is met?

Assume that you have a Simulink simulation where a certain signal is first positive and after some time t in a given interval, it becomes negative. Your goal is to find the zero-crossing.
A first approach would be to plot the signal over the given interval, save it and calculate the zero-crossing.
When repeating this simulation numerous times for varying parameters, it would be beneficial to be able to stop the simulation after the signal has become negative. Then there is already enough information for the calculation of the zero-crossing in Matlab. How could you do that?
Yes, use the Stop Simulation block with the appropriate logical input to the block:
You can use an if / else block to control the flow in the Simulink model. In the if / else block, you can choose the condition if u > 0, continue as normal if it's true, and use the else-option to bypass the rest of the flow you would otherwise run. For instance jump directly to the scope.
Another ways:
You can use Hit Crossing Block in Simulink to find time at the moment of hitting zero.
Another way - use any Trigger or Resettable system. It detects the zero crossing too. For example: this question at SO.
Of course you can also use User Defined function to detect zero crossing by your hand and do whatever you want with the signal at the same time.
About making a lot of simulations and then stops:
you can use Check Upper Static Bound for automatically stops simulation at the moment when zero will be crossed in nth time. For example:
I set upper bound = 10 for this block and this stops at 10th crossing.
There are a lot of ways to save function values in this points or just array of times but this is an another question :)