Interrupt vs. Delay - who wins?

@Cameron,

I was “nerd sniped” too, thinking about your pump program driving my kids to school…

here is an example of your process using Timers in a class object. You can try it by sending it a “1” via Particle function. your function will return -99 if the process is underway…

Non-blocking and should be pretty accurate as to the dwell times.

have fun with it! :slight_smile: :smile: :laughing:

//#include "Particle.h"

class PumpManager
{
  public:
    PumpManager(const int &_pumpPin, const int &_numCycles, const int &_dwellTime);  // Pump Output Pin, Number of Startup Attempts, Pulse time in milliseconds
    void begin() const;
    bool startPump(void);
    bool isStarting(void) const;
  private:
    Timer* timer;
    enum State{
      PUMP_INACTIVE,
      PUMP_ACTIVE
    };
    State pumpState = PUMP_INACTIVE;
    int numCycles;
    int remainingCycles;
    int pumpPin;
    void callback(void);
};

PumpManager::PumpManager(const int &_pumpPin, const int &_numCycles, const int &_dwellTime)
{
  pumpPin = _pumpPin;
  numCycles = _numCycles;
  timer = new Timer(_dwellTime, &PumpManager::callback, *this);
}

void PumpManager::callback(void)
{
   if(pumpState == PUMP_INACTIVE)
    return;
   if(digitalRead(pumpPin) == LOW)
   {
     digitalWrite(pumpPin, HIGH);
   }
   else
   {
     digitalWrite(pumpPin, LOW);
     remainingCycles--;
   }
   if(!remainingCycles)
   {
     pumpState = PUMP_INACTIVE;
     remainingCycles = numCycles;
     timer->stop();
   }
}

void PumpManager::begin(void) const
{
  pinMode(pumpPin, OUTPUT);
  digitalWrite(pumpPin, LOW);
}

bool PumpManager::startPump(void)
{
  remainingCycles = numCycles;
  digitalWrite(pumpPin, HIGH);
  pumpState = PUMP_ACTIVE;
  timer->reset();
}

bool PumpManager::isStarting(void) const
{
  return (pumpState == PUMP_ACTIVE);
}

/***********************************************/
/*************** Main Program ******************/
/***********************************************/

PumpManager pump1(D7, 3, 1000);  // Pump Output Pin, Number of Startup Attempts, Pulse time in milliseconds

bool isStarting;

void setup(void)
{
  Particle.function("RunPump", runPump);
  Particle.variable("PumpStarting", isStarting);
  pump1.begin();
}

void loop(void)
{
  isStarting = pump1.isStarting();
  // waiting for Sleep Dragons...
  // I'm free, to do what I want, any old time...
}
int runPump(String command)
{
  if(command.toInt() == 1)
  {
    if(pump1.isStarting())
      return -99; // rejected the command
    pump1.startPump();  // otherwise go ahead and start the pump
    return 1;
  }
  return 0;
}

you could easily add functions to allow the setting of your pump times and attempts…

Keywords: Timer class member function callback non-blocking

2 Likes