#include "pump.h" volatile uint32_t interruptCounter = 0; void flowISR() { interruptCounter++; } Pump::Pump(uint8_t pumpPin, uint8_t pressurePin, uint8_t flowPin, uint8_t ledPin) { this->pumpPin = pumpPin; this->pressurePin = pressurePin; this->flowPin = flowPin; this->ledPin = ledPin; pinMode(this->pumpPin, OUTPUT); pinMode(this->ledPin, OUTPUT); pinMode(this->pressurePin, INPUT); attachInterrupt(digitalPinToInterrupt(this->flowPin), flowISR, RISING); this->lastMillisReadFlow = millis(); digitalWrite(this->pumpPin, LOW); digitalWrite(this->ledPin, LOW); } void Pump::loop() { this->readSensorValues(); switch (this->state) { case State::Off : break; case State::On : this->timerStandby = false; this->checkSensorsValues(); break; case State::Timer : this->stateTimer(); break; case State::Standby : this->stateStandby(); break; case State::PreError : { bool res = this->checkSensorsValues(); this->statePreError(res); } break; case State::Error : this->stateError(); break; default : break; } } void Pump::activate(uint32_t duration) { if (duration) { this->changeState(State::Timer); this->duration = duration; } else { this->changeState(State::On); } } void Pump::activateWithoutSecurity() { this->changeState(State::OnStupid); } void Pump::stop() { this->changeState(State::Off); } void Pump::clearError() { if (this->state == State::Error) { this->state = State::Off; this->changeState(State::Off); } } uint32_t Pump::getRunningTime() const { return (millis() - this->startTime) / 1000; } uint32_t Pump::getRemainingTime() const { if (this->state != State::Timer) return 0; return (this->duration * 60) - ((millis() - this->startTime) / 1000); } void Pump::readSensorValues() { if (millis() - this->lastMillisReadPressure > Pump::delayReadPressure) { this->pressure = analogRead(this->pressurePin); this->lastMillisReadPressure = millis(); } // Flussimpulseigenschaften: F=(8xQ-4)±5%, F ist die Frequenz, Q ist L/Min. if (millis() - this->lastMillisReadFlow > Pump::delayReadFlow) { uint32_t edgesDelta = interruptCounter; interruptCounter = 0; this->lastMillisReadFlow = millis(); uint32_t timeDelta = millis() - this->lastMillisReadFlow; this->flow = (edgesDelta + 4) / 8; } } bool Pump::checkSensorsValues() { if (millis() - this->lastMillisCheckSensor < Pump::delayCheckSensor) return false; this->lastMillisCheckSensor = millis(); if (this->flow > 1) { return true; } if (this->pressure < Pump::minPressure) { this->changeState(State::PreError); return false; } if (pressure > Pump::maxPressure) { if (this->maxPressureStart == 0) this->maxPressureStart = millis(); else if (millis() - this->maxPressureStart > Pump::maxMaxPressureTime) this->changeState(State::Standby); } else { this->maxPressureStart = 0; } return true; } void Pump::handlePins(bool state) { digitalWrite(this->pumpPin, state); digitalWrite(this->ledPin, state); this->startTime = millis(); if (state) { this->timerStandby = false; this->maxPressureStart = 0; } } void Pump::changeState(State state) { if (this->state == State::Error) return; if (this->state == state) return; switch (state) { case State::Off : this->handlePins(false); this->pressure = 0; this->flow = 0; break; case State::On : this->handlePins(true); break; case State::Timer : this->handlePins(true); break; case State::Standby : if (this->state == State::Timer) this->timerStandby = true; this->handlePins(false); break; case State::Error : this->handlePins(false); break; case State::PreError : this->lastStatePreError = this->state; this->preErrorStartTime = millis(); break; case State::OnStupid : this->handlePins(true); break; default: break; } this->state = state; } void Pump::stateTimer() { if (!this->checkSensorsValues()) return; if (millis() - this->lastMillisTimer < this->delayTimer) return; this->lastMillisTimer = millis(); uint8_t minutesOn = (millis() - this->startTime) / 1000 / 60; if (minutesOn >= this->duration) this->changeState(State::Off); } void Pump::stateStandby() { if (this->pressure < Pump::restartPressure) { if (this->timerStandby) this->changeState(State::Timer); else this->changeState(State::On); } } void Pump::stateError() { if (millis() - this->startTime > Pump::blinkTime) { this->startTime = millis(); if (this->ledState) { this->ledState = false; digitalWrite(this->ledPin, LOW); } else { this->ledState = true; digitalWrite(this->ledPin, HIGH); } } } void Pump::statePreError(bool checkSensor) { if (checkSensor) { this->changeState(this->lastStatePreError); return; } if (millis() - this->preErrorStartTime > Pump::maxPreErrorTime) { this->changeState(State::Error); } }