Original code:
enum SwitchState{
TOGGLE_OFF,
TOGGLE_ON,
UNKNOWN,
} savedState = UNKNOWN;
void setCycle(SwitchState state);
constexpr uint32_t MINUTES_TO_MILLIS(uint32_t min) {
return min * 60 * 1000;
};
constexpr uint32_t DEBOUNCE_TIME = 50;
class PumpTimer {
using functPtr = void(*)(void);
public:
PumpTimer(int pumpPin, uint32_t runTime, uint32_t pauseTime, functPtr stoppedAction = nullptr) : pin(pumpPin), cycleMillis(runTime), offMillis(pauseTime), callback(stoppedAction) {}
void setTime(uint32_t runTime) {
cycleMillis = runTime;
}
void setTime(uint32_t runTime, uint32_t pauseTime) {
cycleMillis = runTime;
offMillis = pauseTime;
}
void setPauseTime(uint32_t pauseTime) {
offMillis = pauseTime;
}
void init(void) {
pinMode(pin, OUTPUT);
}
void start(uint32_t duration) {
cycleMillis = duration;
start();
}
void start(void) {
startMillis = millis();
state = ACTIVE_RUNNING;
digitalWrite(pin, HIGH);
}
void process(void) {
switch (state) {
case STOPPED:
break;
case ACTIVE_RUNNING:
if (millis() - startMillis > cycleMillis) {
digitalWrite(pin, LOW);
state = ACTIVE_PAUSED;
startMillis = millis();
}
break;
case ACTIVE_PAUSED:
if (millis() - startMillis > offMillis) {
state = STOPPED;
if (callback) {
callback();
}
}
break;
}
}
void stop(bool runCallback = false) {
digitalWrite(pin, LOW);
state = STOPPED;
if (callback and runCallback) {
callback();
}
}
private:
enum {
STOPPED,
ACTIVE_RUNNING,
ACTIVE_PAUSED,
} state = STOPPED;
uint8_t pin;
uint32_t cycleMillis;
uint32_t offMillis;
uint32_t startMillis;
functPtr callback;
};
PumpTimer timer[] = {
/*Pin number, On Time, Pause Time and pointer to callback function */
{ 4, MINUTES_TO_MILLIS(8), MINUTES_TO_MILLIS(12), []() {
timer[1].start();
}
},
{ 5, MINUTES_TO_MILLIS(8), MINUTES_TO_MILLIS(12), []() {
timer[2].start();
}
},
{ 6, MINUTES_TO_MILLIS(8), MINUTES_TO_MILLIS(12), []() {
timer[0].start();
}
},
};
const uint8_t togglePin = 7;
void setup() {
pinMode(togglePin, INPUT_PULLUP);
for (auto& t : timer) {
t.init();
}
timer[0].start();
}
void loop() {
for (auto& t : timer) {
t.process();
}
static uint32_t lastSwitchMillis = 0;
SwitchState currentState = digitalRead(togglePin)? TOGGLE_OFF : TOGGLE_ON;
if (currentState != savedState) {
if (millis() - lastSwitchMillis > DEBOUNCE_TIME) {
lastSwitchMillis = millis();
savedState = currentState;
setCycle(currentState);
}
}
}
void setCycle(SwitchState state) {
switch (state) {
case TOGGLE_OFF:
for (auto& t : timer) {
t.stop();
t.setTime(MINUTES_TO_MILLIS(8), MINUTES_TO_MILLIS(12));
}
timer[0].start();
break;
case TOGGLE_ON:
for (auto& t : timer) {
t.stop();
t.setTime(MINUTES_TO_MILLIS(15), MINUTES_TO_MILLIS(20));
}
timer[0].start();
break;
case UNKNOWN:
// nothing to do here
break;
}
}
I "lent" it to OP, having once done something similar...