Files
Bewaesserung-Arduino/lib/Pump/pump.cpp
T
2023-07-06 11:56:35 +02:00

243 lines
5.9 KiB
C++

#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 {
if (this->state == State::Off)
return 0;
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->pressure = 12;
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;
if (timeDelta > Pump::delayReadFlow + 50)
Serial.println(F("Flow resualt may be inaccurate"));
this->flow = (edgesDelta + 4) / 8;
// this->flow = 13;
}
}
bool Pump::checkSensorsValues() {
if (millis() - this->lastMillisCheckSensor < Pump::delayCheckSensor)
return true;
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);
}
return true;
}
void Pump::handlePins(bool state) {
digitalWrite(this->pumpPin, state);
digitalWrite(this->ledPin, state);
if (state) {
this->timerStandby = false;
this->startTime = millis();
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() {
this->checkSensorsValues();
if (this->pressure < Pump::maxPressure / 2) {
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);
}
}