-
Notifications
You must be signed in to change notification settings - Fork 27
Description
In SPT Component v4.0.1 DebouncedInput
was moved from VAR to VAR_INST. I assume this was to Issue #64.
Context
Working on converting modules to a library package, and upgrading dependencies. When upgrading SPT Components
from 3.9.3 to 4.0.2, all of my photoelectric sensors started toggling rapidly.
My sensors are LIGHT-ON retro-reflectives, so when unblocked the sensor output is HIGH. When the sensor is blocked, that is my ACTIVE state. I implement my sensors with the FB_DigitalSensor property INVERTED set to TRUE. I use a SimpleFlickerFilter with a 50ms filter time.
I rolled back libraries for on-going development testing; I hope to revert the updated library to 4.0.0 and validate.
Difference
4.0.0 and prior:
METHOD PRIVATE ProcessInput : BOOL
VAR_INPUT
Input : BOOL;
END_VAR
VAR
DebouncedInput : BOOL;
END_VAR
VAR_INST
LastDebouncedInput : BOOL;
MovingAverage : DINT;
END_VAR
4.0.1 and 4.0.2:
METHOD PRIVATE ProcessInput : BOOL
VAR_INPUT
Input : BOOL;
END_VAR
VAR_INST
DebouncedInput : BOOL;
LastDebouncedInput : BOOL;
MovingAverage : DINT;
END_VAR
Theory
In ProcessInput:
E_DebounceMode.SimpleFlickerFilter: // Requires the raw input to be a consistent value for a set time period before output changes
TON_DebounceTimer(IN := (Input <> DebouncedInput), PT := _DebounceTime); // runs the timer whenever a differing input is detected
IF TON_DebounceTimer.Q THEN
DebouncedInput := Input; // once the raw input has been different for the specified debounce time, the processed input is updated
END_IF
...
LastDebouncedInput := DebouncedInput; // Update "Last value"
IF _Inverted THEN // If signal inversion is requested, invert the signal
DebouncedInput := NOT DebouncedInput;
END_IF
ProcessInput := DebouncedInput;
Previously when DebouncedInput
was a VAR, and not a VAR_INST, it wasn't really functioning since on each method call, DebouncedInput was always initialized to FALSE. Therefore #64 was not functional.
Once DebouncedInput
was converted into a VAR_INST, now it is locally persistent and the IF _Inverted THEN
logic causes it to always toggle regardless of the conditions of the filters above.
Potential fix
Previously
LastDebouncedInput := DebouncedInput; // Update "Last value"
IF _Inverted THEN // If signal inversion is requested, invert the signal
DebouncedInput := NOT DebouncedInput;
END_IF
ProcessInput := DebouncedInput;
Proposal
Don't modify DebouncedInput
with the _Inverted
variable, instead modify an intermediate variable.
VAR
ProcessedOutput: BOOL;
END_VAR
LastDebouncedInput := DebouncedInput; // Update "Last value"
IF _Inverted THEN // If signal inversion is requested, invert the signal
ProcessedOutput := NOT DebouncedInput;
ELSE
ProcessedOutput := DebouncedInput;
END_IF
ProcessInput := ProcessedOutput ;