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!
//#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