Continuous function call or extra variable?

Hello,

I'm just curious about your opinion about a hypothetical question. Let's say we have some kind of an external sensor, which provides data about an object if it is in the sensors range. If data is received a timer is always updated, but if data is not received in a given time, the gathered info should be cleared.

We simply put an if to check the timer in the loop.

if ( (millis() - objectDataReceivedTimer) >= RESET_TIMEOUT_MS )
{
  //data has not been received recently, clear the gathered data
  clearData();
}

Okay, the timer has expired we cleared the data. But if data is still not received, this clearData() function will be called in every loop cycle until new data has arrived and the timer gets updated along with it.

To prevent this we can add a variable to remember that data was cleared, and make it false if data has arrived.

if ( ((millis() - objectDataReceivedTimer) >= RESET_TIMEOUT_MS) &&
     (dataWasCleared == false) )
{
  //data has not been received recently, clear the gathered data
  clearData();
  dataWasCleared = true;
}

Let's suppose that the function call is not a significant overhead (e.g. 20us) and clearing it in every loop doesn't do any harm. Which option would you choose? Call the function in every loop or add the extra variable?

Thanks in advance.

You presuppose only two options.

If neither option causes a problem then it doesn't matter which one you pick. So just pick one and stop worrying about it.

@Coding Badly: I'm listening..

@Jiggy-Ninja: you're probably right. It seems that I'm at leisure. :smiley:

A third option, the one I would choose, is to code the application as a state machine. In such a machine clearData would only be called on the appropriate transition (essentially the if in your first snippet). If coded correctly clearData is actually unreachable except on that transition.

In other words, dataWasCleared would be a richer datatype (with a different name) indicating the state of the machine. An example might be an enum with HAVE_DATA and WAITING_FOR_DATA as two elements. When the transition from HAVE_DATA to WAITING_FOR_DATA occurs clearData is called.

I think you are on to an important point, which is learning how often it's appropriate to do a particular thing in non blocking code. Things to consider are: how often does it need to be done, what is the overhead for doing it, what is the overhead for deciding whether to do it, is there any harm in doing it more often than necessary?.

The answer to those questions will inform the decision on how to deal with particular event or task, and sometimes the answers will not give a clearly preferred solution. If in doubt try one solution, if it works and doesn't cause a problem then it's good, otherwise try a different approach.

A third option, the one I would choose, is to code the application as a state machine.

Is this not what the use of a control variable does ?

ie, if the system is in the state defined by the value of the control variable then take these actions. The fact that it is a state machine would be more obvious if switch/case were used, which I favour, but switch/case is really just another way of writing a series of if/else statements

Another option is to reset the timer when the data is cleared. Then the redundant clearing of the data only happens every 'RESET_TIMEOUT_MS' milliseconds:

if ( (millis() - objectDataReceivedTimer) >= RESET_TIMEOUT_MS )
{
  //data has not been received recently, clear the gathered data
  clearData();
  objectDataReceivedTimer = millis();  // restart the data timeout
}

UKHeliBob:
Is this not what the use of a control variable does ?

...code the application as a state machine...

:wink: