Water level switch de-bounce logic question

I’m being brain dead today., and this seem like an easy thing to do, please a little guidance. :confused:

I have a high level float switch in a water tank, connected to an IDC5-SW.
When the water level raises the float switch, there can be a period of multiple off-on-off transients.

I know I can used the on latch to trigger an alarm.
However, how do I know that the water has dropped, since the off latch may have been set multiple times.

Latching works great for know if it is full, but not less than full. Can you set up a float switch off timer that resets whenever the float switch is on? So if the timer reaches whatever time setpoint you want, then you know the tank is no longer full (or the super duper reliable float switch just broke - again).

Hope that is clear - it’s monday and the vitamin c (caffeine), hasn’t kicked in.

1 Like

Thanks Phillip,

I know what you mean, three cups so far. :laughing: I may have answer my own question, if you have time, please check my logic.

Thanks again

Change to two separate tests.

  • if on latch, test for the float totalizer being on for 5 minutes, (assuming its not broken) should be plenty of time for the level to settle. Clear the off latch, and set the alarm stuff.

  • if off latch, clear the on latch, and the totalizer.


if (flg_water[nCntl_idx] == True) then //--- Read current leases high water switch --- ppWater_Point = pptWater[nCntl_idx];
if (IsOnLatchSet(*ppWater_Point)) then
	if (GetOnTimeTotalizer(*ppWater_Point) > 300) then
		ClearOffLatch(*ppWater_Point);	//--- clear the off latch ---
    //--- Set the water alarm for the current lease ---
    ntLease_ALM_water[nCntl_lease_xref] = ALM_RED;
    ntLease_ALM[nCntl_lease_xref] = ALM_RED;
    ALM_Master_Alarm = ALM_RED;

if (IsOffLatchSet(*ppWater_Point)) then
	ClearOnLatch(*ppWater_Point);	           //--- clear the on latch ---
	GetRestartOnTimeTotalizer(*ppWater_Point); //--- clear on time total ---

    //--- Clear the water alarm for the current lease ---
    ntLease_ALM_water[nCntl_lease_xref] = ALM_GRN;


Your off latch may get latched as the water level drops and bounces (since the on time totalizer has been reset and will not reach the 300 second on time totalizer since the water is dropping). The on latch will toggle on and off as it bounces as well along with the ntLease_ALM_water switching between RED and GRN.

I was thinking something more like this:

if(IsOnLatchSet() or IsOn() ) then
 //This may happen multiple times due to bounce
elseif(GetOffTimeTotalizer() > 300) then
  //We've been off for a while, water dropping
  //Only called if float hasn't been on at all for 300 seconds.
1 Like

Hey Phillip,
Not sure why we would use the OffTimeTotalizer, not that it’s wrong, it just seems overcomplicated. Wouldn’t it be simpler to just use a timer in the strategy?

if ( IsOnLatchSet() or IsOn() ) then
    HighWaterDownTimer = 300;
elseif ( HasTimerExpired(HighWaterDownTimer) ) then

Sure, I just stuck with the totalizers since that is what Marty was using in the code he posted. A timer would work just as well for these short time periods.

Thanks guys,

The logic works great, but I can’t get it to compile with eather GetOffTimeTotalizer or GetRestartOffTimeTotalizer using a pointer to the point. It does work if you use the direct point name. I’ve logged a case with support.


Hi @Taipan89,

I’m sorry you had trouble compiling your OptoScript there. I was not able to reproduce that same issue. What was the compile error?

Two very common pointer problems folks get all the time:

  • Error: "The pointer may need to be dereferenced with the * operator."
    Easy fix: stick a * immediately before the name of your pointer variable.

  • Error: "**Invalid type for argument #**X"
    Easy fix: Check your data type. OptoScript does automatic conversions of some stuff (e.g. you can assign an integer to a float or vice versa). But for the commands you mentioned, you’re going to need a Pointer to Type: “Off Totalizer” otherwise the compiler will get cranky/confused.

FYI - in case you’ve not seen my 101 Lesson on pointers (I had fun writing it, some people were amused reading it), check out this post: PAC Control 101: Why/when/how would I use POINTERS?

Happy pointing!