/*
Level Contorl Inlet Pump Outlet Pump
Tank Level: 10 m³ Flow Rate: 3,600 m³/h Flow Rate: 3,600 m³/h
Level Alarm-> Low Alarm: 2 m³ High Alarm: 8 m³
*/
#include "ExponentialFilter.h"
#define LEVEL_AI_PIN A0
#define START_DI_PIN 7
#define STOP_DI_PIN 6
#define INLET_VALVE_DO_PIN 11
#define OUTLET_VALVE_DO_PIN 10
#define INLET_VALVE_STATUS_DO_PIN 5
#define OUTLET_VALVE_STATUS_DO_PIN 4
#define RUNNING_STATUS_DO_PIN 3
#define TANK_LEVEL_MIN 0.0
#define TANK_LEVEL_MAX 10.0
#define LEVEL_LOW 2.0
#define LEVEL_HIGH 8.0
#define INTERVAL_PLOT 10 // 10 Milliseconds
bool start;
bool stop;
bool running;
bool risingRun;
bool inletPump;
bool outletPump;
ExponentialFilter expLevel;
void setup() {
Serial.begin(115200);
pinMode(START_DI_PIN, INPUT_PULLUP);
pinMode(STOP_DI_PIN, INPUT_PULLUP);
pinMode(INLET_VALVE_DO_PIN, OUTPUT);
pinMode(OUTLET_VALVE_DO_PIN, OUTPUT);
pinMode(INLET_VALVE_STATUS_DO_PIN, OUTPUT);
pinMode(OUTLET_VALVE_STATUS_DO_PIN, OUTPUT);
pinMode(RUNNING_STATUS_DO_PIN, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
expLevel.expMode(AUTO); // Exponential Filter in Auto Mode
expLevel.expCutoffTime(MS2S(3000)); // Debounce Period = 20 milliseconds
expLevel.expInit(TANK_LEVEL_MIN); // INPUT = 0.0, INPUT_PULLUP = 1.0
}
void loop() {
RuningCommand();
Filter();
PumpControl();
SerialPlot();
}
void RuningCommand() {
bool prevRun = running;
start = !digitalRead(START_DI_PIN);
stop = digitalRead(STOP_DI_PIN);
running = (running | start) & stop;
risingRun = running & !prevRun;
digitalWrite(RUNNING_STATUS_DO_PIN, running);
}
void PumpControl() {
bool highLevelAlarm = expLevel.output >= LEVEL_HIGH;
bool lowLevelAlarm = expLevel.output <= LEVEL_LOW;
inletPump = (inletPump | lowLevelAlarm | risingRun) & !highLevelAlarm & running;
outletPump = (outletPump | highLevelAlarm) & !lowLevelAlarm & running;
digitalWrite(INLET_VALVE_DO_PIN, inletPump);
digitalWrite(OUTLET_VALVE_DO_PIN, outletPump);
digitalWrite(INLET_VALVE_STATUS_DO_PIN, inletPump);
digitalWrite(OUTLET_VALVE_STATUS_DO_PIN, outletPump);
}
void Filter() {
int rawLevel = analogRead(LEVEL_AI_PIN);
float level = rawLevel * (TANK_LEVEL_MAX - TANK_LEVEL_MIN) / 1023.0f + TANK_LEVEL_MIN;
float returnValue = expLevel.expFilter(level);
}
void SerialPlot() {
static unsigned long startTime;
unsigned long currTime = millis();
if (currTime - startTime < INTERVAL_PLOT) return;
startTime = currTime;
Serial.println(
", Exp-Input:" + String(expLevel.input, 2)
+ ", Exp-Output:" + String(expLevel.output, 2)
+ ", Low-Alarm:" + String(LEVEL_LOW, 2)
+ ", High-Alarm:" + String(LEVEL_HIGH, 2)
+ ", Tank-Level-Min:" + String(TANK_LEVEL_MIN, 2)
+ ", Tank-Level-Max:" + String(TANK_LEVEL_MAX, 2)
);
}
INLET
RATE (m³/h)
OUTLET
RATE (m³/h)
INLET-PUMP
OUTLET-PUMP
3600.0 -------------------------------
0.0 -------------------------------