Wednesday, October 14, 2020

[Example] Creating a rising edge, falling edge and either change detector (Block diagram approach)

Quite often, we need to trigger a specific action when a change in an input's behavior is detected. Maybe we would like count how many times a certain action takes place (for example, the number of particulate filter regeneration attempts during the same driving cycle). Adding 1 while the regeneration process is active would only increase the counter during the entire process, which would result in a bad count. Consider the example below.



Our counter should have reached 3 when the 3rd regen started, but we can see that we are continuously increasing it throughout the regeneration process. To correct this unwanted behavior, our switch should only receive a 1dt (1 simulation step) impulse when the regeneration process starts, in order to count properly. Let's get started.

1) Objective:

Create a rising edge, falling edge or change detector.

2) Model configuration

Solver -> discrete, fixed simulation step. Step-size -> 0.01s.

3) Principle of operation

Let's consider the following sequence: 0,0,0,0,0,x,x,x,x,x,x, where x is a positive number (let's consider it an integer). We want to distinguish the moment when the transition from 0 to x takes place. Therefore, we will model a condition indicating that x(t) is non null and x(t-1) is null. This will be our rising edge detector.

For our falling edge, consider x,x,x,x,x,x,0,0,0,0. We need to detect the moment when x(t) is null and x(t-1) is non null.

The either edge detector will be a mix between the two (rising-edge OR falling-edge). However, we will just simplify it as x(t)~=x(t-1).

4) Solutions

a) Rising edge detector

The blocks with blue foreground are used for the rising edge detection. We can now see that the counter works appropriately.

NOTE: Simulink offers some blocks that have a similar, yet not identical function with respect to ours. Under Logic and Bit Operations, you may find Detect Increase, Detect Decrease and Detect Change. In the above context, Detect Increase will work, but there are some pitfalls.

For example, what if we used a a datatype that may present rounding errors (instead of 0, we get 0.00..01)? Or what if our signal comes from a specific sensor and is subject to noise? Detect increase would send an impulse whenever a sample subject to noise has a higher value than its preceding one. If we want our impulse sent only when exceeding a unitary value (or maybe even a different threshold), we can't really use these built-in functions. I've added some white noise to our previous signal so that I could illustrate an example below.


That really doesn't look well. We could fix this in numerous ways. One of them would be to pass this signal through a switch (with a threshold of 0.5), and then apply the former solution.


That works perfectly. Another solution would be to directly compare the signal with our threshold (using a relational operator) and apply the rising edge (or even the Detect Increase) afterwards.



There are numerous ways to treat such problems, they depend on the engineer's creativity, input data type, range, behavior etc. What matters the most is our ability to identify the various pitfalls that we may encounter when implementing a functionality (in our case, the fact that a detect increase would send an impulse even when changing from 0 to 0.x).

b) Falling edge detector

I am not going to insist too much on the topic, I am just going to present the generic solution. The same pitfall remains: a detect decrease may trigger even if switching from 1 to 0.x, where x>0.
Here's the result, if we were to count every time our regeneration process ended:




c) Change detector

One may suppose that what we have to do is to create rising edge detector, a falling edge detector and tie them to an OR block (logical operator). However, this is unnecessarily complicated and does not treat the previous issue. the easy way (which is exactly the way the Detect Change block works, by looking under its mask) would be to check if x(t) ~= x(t-1). However. if the signal is noisy, it should be treated beforehand, or else false detections will occur.




Again, we must pay particular attention to floating-type variables (as, due to rounding errors, a quasi-constant value may result in a false positive). If we find ourselves in such a situation, I would rather check if the gradient of our signal exceeds a tolerance.

NOTE: I would like to once again stress the fact that there is no universal solution, what we implement is largely dependent of the context. When I will (hopefully) get more traffic on the blog, I intend to add some sort of Q&A where I provide specific solutions for suggested problems.

No comments:

Post a Comment