After testing I have learned a few things...
First I changed the code to just print the pressure difference so I can easily see it as it comes across the monitor, instead of pre and post psi.
if (!inFlush)
{
ManageManualFlush();
}
prePsi = GetPsi(preSensorPin);
//Serial.print("Pre-filter psi: ");
//Serial.print(prePsi);
postPsi = GetPsi(postSensorPin);
//Serial.print(" Post-filter psi: ");
//Serial.println(postPsi);
Serial.println("Pressure Drop");
Serial.println(prePsi - postPsi);
delay(2000); //delay in between reads for stability
ManageFlush();
CheckFilter();
ManageFilterLeds();
}
Next I put a dirty filter, which I would consider being a filter in between the order and change state, and my yellowLED threshold does not light up consistently, even though I see a pressure difference that should trigger the yellow LED come across the monitor. Based on the testing so far, I have yellowLEDThreshold at 1.25psi and redLEDThreshold at 1.50psi. My best guess as to why the LED is not coming on when the difference is greater than the set threshold is the input data is too sporadic??
My best guess for a solution to this is to add the smoothing library to the sketch. I am not sure which type of value store would be better, smoothed average or smoothed exponential. I am just not sure how to add the smoothed values into the code smoothly(dad joke). Here is what I got so far.
/*
REV_5
Automated Water Filter System
2/8/19
*/
//#define BLYNK_PRINT Serial
#include <SPI.h>
#include <WiFiNINA.h>
#include <BlynkSimpleWiFiNINA.h>
#include <Smoothed.h>
enum FilterStatus {FilterOk, OrderFilter, ChangeFilter};
//float prePsi; //declaring pre-filter sensor psi
//float postPsi; //declaring post-filter sensor psi
Smoothed <float> prePsi;
Smoothed <float> postPsi;
byte preSensorPin = A3; //assigning pre-filter sensor to A0
byte postSensorPin = A1; //assigning pre-filter sensor to A1
const byte yellowLEDPin = 2; //assigning pin number to yellow LED
const byte redLEDPin = 5; //assigning pin number to red LED
const byte flushValveSolenoidPin = 7; //assigning pin number to flush valve
const byte buttonPin = A2; //assigning a pin number to button
const byte hotPin = 6; //assigning a pin to hot wire
float redLEDThresholdPsi = 1.5; //assigning a pressure threshold for red LED to illuminate
float yellowLEDThresholdPsi = 1.25; //assigning a pressure threshold for yellow LED to illuminate
int flushValveThresholdPsi = 55; //assinging a pressure threshold for flush out valve to open
const uint32_t flushValveDelay = 5000UL; //assigning a delay for flush out valve
const uint32_t minFlushInterval = 2UL * 60UL * 1000UL; // Minimum time between flushes, however invoked
uint32_t flushValveOnAtMs = 0 ; // flush timer
bool inFlush = false ; // flush timer status
FilterStatus FilterCondition = FilterOk;
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "42b088f5285542f0aeced22e4cce6ee4";
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "";
char pass[] = "";
void setup()
{
Serial.begin(115200);
Serial.println("\nStarting...");
pinMode(preSensorPin, INPUT); //sets pre-filter sensor value as input
pinMode(postSensorPin, INPUT); //sets post-filter sensor value as input
pinMode(yellowLEDPin, OUTPUT);
pinMode(redLEDPin, OUTPUT);
pinMode(flushValveSolenoidPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(hotPin, OUTPUT);
Blynk.begin(auth, ssid, pass);
prePsi.begin(SMOOTHED_EXPONENTIAL, 10);
postPsi.begin(SMOOTHED_EXPONENTIAL, 10);
}
void loop()
{
Blynk.run();
digitalWrite(hotPin, HIGH);
if (!inFlush)
{
ManageManualFlush();
}
prePsi = GetPsi(preSensorPin);
//Serial.print("Pre-filter psi: ");
//Serial.print(prePsi);
postPsi = GetPsi(postSensorPin);
//Serial.print(" Post-filter psi: ");
//Serial.println(postPsi);
Serial.println("Pressure Drop");
Serial.println(prePsi - postPsi);
delay(2000); //delay in between reads for stability
ManageFlush();
CheckFilter();
ManageFilterLeds();
}
float GetPsi(byte AnalogPin)
{
int SensorValue = analogRead(AnalogPin); //read raw reading from sensor
float Voltage = (5.0 / 1023.0) * SensorValue; //calculating voltage from raw reading
return (Voltage - 0.5) * (100.0) / (4.5 - 0.5); //calculating psi from voltage
}
void CheckFilter() // Filter condition state machine
{
// All we can do is go from OK to order or from Order to change
switch (FilterCondition)
{
case FilterOk:
if (prePsi - postPsi > yellowLEDThresholdPsi) // if the pressure drop is greater than Order threshold
{
Serial.println("Order filter");
FilterCondition = OrderFilter;
}
break;
case OrderFilter:
if (prePsi - postPsi > redLEDThresholdPsi) //if the pressure drop is greater than replace threshold
{
Serial.println("Change filter");
FilterCondition = ChangeFilter;
}
break;
case ChangeFilter: // Once we're in this state, only a reset will change it.
break;
}
}
void ManageFilterLeds()
{
switch (FilterCondition)
{
case FilterOk:
//Serial.println("Leds off - filter ok");
digitalWrite(redLEDPin, LOW);
digitalWrite(yellowLEDPin, LOW);
break;
case OrderFilter:
//Serial.println("Show yellow - order filter");
digitalWrite(redLEDPin, LOW);
digitalWrite(yellowLEDPin, HIGH);
break;
case ChangeFilter:
//Serial.println("Show red - replace filter");
digitalWrite(redLEDPin, HIGH);
digitalWrite(yellowLEDPin, LOW);
break;
}
}
void ManageManualFlush()
{
if (digitalRead(buttonPin) == LOW && !inFlush)
{
Serial.println(F("Manual flush"));
StartFlush();
}
}
void ManageFlush()
{
if ( inFlush && millis() - flushValveOnAtMs >= flushValveDelay ) // if flush timer expired stop flushing
{
StopFlush();
}
if (!inFlush && prePsi < flushValveThresholdPsi) // if the psi is lower than threshold see if it's time for an auto flush
{
FlushIfWeMay();
}
}
void StartFlush()
{
{
inFlush = true;
digitalWrite(flushValveSolenoidPin, HIGH); // open flush out valve
flushValveOnAtMs = millis(); // start flush timer
Serial.println(F("Start flush timer"));
}
}
void StopFlush()
{
digitalWrite(flushValveSolenoidPin, LOW); //close flush out valve
inFlush = false;
Serial.println(F("Stop flush timer"));
}
void FlushIfWeMay() // Flush if enough time has passed since the last one or if we don't know when the last one was
{
if ((millis() - flushValveOnAtMs > minFlushInterval) || flushValveOnAtMs == 0) // Honour an initial request for flush - who knows when we did it last
{
Serial.println(F("Auto flush"));
StartFlush();
}
else
{
Serial.print(F("Flush request denied - did one too recently. Next opportunity in: "));
Serial.print((minFlushInterval - (millis() - flushValveOnAtMs)) / 1000UL);
Serial.println(F(" seconds."));
}
}
If folks have a better idea to solve the issue I am all ears.