Suppress the initial update for a class following a reboot


#1

I’m using some code, that I haven’t written myself, to monitor a toggle switch. It works brilliantly to control a WiFi controlled light bulb. However, if the Particle device is power cycled for whatever reason, the toggle switch class will be inadvertently triggered to do an initial ‘update’. I’d like to suppress that initial update and only update the switch if it’s physically toggled. Am I making any sense?

TLDR: ToggleSwitchAction::update(); when executed for the first time after a reset toggles the state even if the switch itself hasn’t been toggled.

This is how the switch is updated in loop():
ToggleSwitchAction::update();

and here it is in my support libraries:-

  class ToggleSwitchAction{
    public:
      ToggleSwitchAction(functionPtr openAction, functionPtr closeAction) : onOpen(openAction), onClosed(closeAction){};
      void bindToPin(uint8_t togglePin);
      static void update(void);

    private:
      uint8_t pin;
      uint32_t lastPressMillis;
      functionPtr onOpen;
      functionPtr onClosed;
      enum SwitchState{
        OPEN,
        CLOSED,
        UNKNOWN,
      };
      SwitchState lastState = UNKNOWN;
      static std::vector<ToggleSwitchAction*>instances;
  };
void IndicatorLED::toggle(void)
{
  state = !state;
  digitalWrite(pin, state? HIGH : LOW);
}

Any help appreciated. My first thought was to add a ‘flag’ into setup() like donotupdate = 1, then then set that flag to 0 at the END of loop, then add an if check somewhere to only update the switch if donotupdate is 0. But it seems like there must be a more elegant solution. And I’m not even sure my proposed solution IS a solution!

Thank you


#2

You need to have a state flag the is persistent across reboots.
If you can be sure the device won’t lose power during the reboot you can use a retained variable.
If that can’t be guaranteed you can use EEPROM.


#3

Thanks Scruff - appreciate the tip - but all I’m interested in is a toggle which changes state every time you flip it - it retaining the state it was previously in isn’t so important - I just want to avoid publishing the way the code treats power on as a state change when it isn’t one. It’s just power on.
This may not be possible however without a total rewrite of the code. In which case I’ll just live with it. It’s rare that the device is power cycled to be sure.


#4

OK, in that case I could give you a solution but I get the feeling you’d rather need to think how you detect a change of state and then picture how this plays out with an unknown starting condition.

Also if you are content with an unknown starting condition and the only thing you can learn from a toggle action that your new state is another unknown state then there is no place for explicit OPEN or CLOSED states as you’ll never know which it actually is (inverse of unknown is still unknown).

BTW, after startup all pins will be set as INPUT and changing them to pinMode(pin, OUTPUT) will inevitably caus it to pull LOW (unless you explicitly set another starting state - but for that you’d need to know what this should be).
So when your pin was HIGH before you depowered the device you’d have to change of state if it was LOW you don’t.


#5

Thanks Scruff!

I’ll try changing this to

  SwitchState lastState = OPEN;