Skip to content

[BUG] [SPT Components] [4.0.1 .. 4.0.2] FB_DigitalSensor Inverted logic causes constant toggling #118

@gx1400

Description

@gx1400

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 ;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions