/*
INTEX Chlorine Generator Control System
Cletus Berkeley 2020/02/11 08:20AM
Ver. 04.30 Locked-Down: 03:45PM
*/
//TIMING AND CONSTANTS SETUP
int Startup=5000UL; // Startup delay - this allows time for pump to start circulation
int Restart=5000; // Low-Flow restart delay - this allows time for flow stabilization
int SalConst=700; // Constant for converting Amperes to Salinity (SalConst= Tested PPM/Display Amps)
int OverSALT=3600; // Higher than this value amps stop generating "HIGH SALT" (Req'd PPM + 20%)
int UnderSALT=2400; // Lower than this value amps stop generating "LOW SALT" (Req'd PPM - 20%)
//const long revTime=21600000L; //Interval to reverse electrodes (6-HOURS) 60*60*1000*6
const long revTime=60000; //FOR TESTING PURPOSES - to reverse electrodes (60-seconds)
// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
//Input and Output pin configuration
int FLOWsensor=11;
int FWDPolarity=5;
int REVPolarity=12;
int BUZZ=10;
int mainRelay=9; // Conrols power to electrodes / Soft-start
// LCD DISPLAY LIBRARY
#include <SoftwareSerial.h>
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#define I2C_ADDR 0x27 // Define I2C Address where the SainSmart LCD is
#define BACKLIGHT_PIN 3
//LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
LiquidCrystal_I2C lcd(I2C_ADDR,2,1,0,4,5,6,7);
// Variables will change:
int fwdState = LOW; // used to set the Polarity
int revState = LOW; // State used to set the Polarity
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time cycle time was updated
// constants won't change:
const long interval = revTime; // interval at which to reverse (milliseconds)
void setup() {
digitalWrite(11, HIGH);
Serial.begin(9600);
// configure the digital pins as inputs and outputs:
pinMode (FLOWsensor, INPUT);
pinMode(FWDPolarity, OUTPUT);
pinMode(REVPolarity, OUTPUT);
pinMode (BUZZ, OUTPUT);
pinMode (mainRelay, OUTPUT);
digitalWrite(mainRelay, LOW); //Initialize the main relay to off
digitalWrite(BUZZ, LOW); //Initialize buzzer to off
// Configure the LCD DISPLAY
lcd.begin (20, 4); // Switch on the backlight
lcd.setBacklightPin(3,POSITIVE);
lcd.setBacklight(HIGH);
lcd.home();
// System Initialization and Welcome Screen
lcd.clear();
lcd.setCursor ( 0, 0 );
lcd.print(" CLETUS BERKELEY");
lcd.setCursor ( 0, 1 );
lcd.print(" Ver.: 4.30");
lcd.setCursor ( 0, 2 );
lcd.print(" Chlorine Generator");
lcd.setCursor ( 0, 3 );
lcd.print(" Ver. 4.24 Feb 2020");
delay (2000);
lcd.clear();
lcd.setCursor ( 0, 0 );
lcd.print(" Chlorine Generator");
lcd.setCursor ( 0, 2 );
lcd.print("STATUS: STANDBY");
lcd.setCursor ( 0, 3 );
lcd.print(" <<BOOTING-UP>>");
delay (Startup); // Startup delay - this allows time for pump to start circulation
}
void loop() {
digitalWrite(BUZZ, LOW); //if buzzer was on turn it off
// HERE WE READ THE ACS715 CURRENT SENSOR DATA
unsigned int x=0;
float AcsValue=0.0,Samples=0.0,AvgAcs=0.0,AcsValueF=0.0,SalinityPPM=0.0;
for (int x = 0; x < 150; x++){ //Get 150 samples
AcsValue = analogRead(A0); //Read current sensor values
Samples = Samples + AcsValue; //Add samples together
//delay (3); // let ADC settle before next sample 3ms
}
AvgAcs=Samples/150.0; //Take Average of Samples
//((AvgAcs * (5.0 / 1024.0)) converitng the read voltage in 0-5 volts
//2.5 is offset(assuming arduino is working on 5v so the viout at no current comes
//out to be 2.5 which is the offset. If Arduino is working on different voltage
//the offset must be altered according to the input voltage)
//0.066v(66mV) is rise in output voltage when 1A current flows at input (66mV per Amp)
AcsValueF = (2.5 - (AvgAcs * (5.0 / 1024.0)) )/0.066;
SalinityPPM = (AcsValueF * SalConst); // Here we try to corelate amps to Salinity PPM using a simple conversion value
Serial.print(AcsValueF);//Print the read current on Serial monitor
delay(50);
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// HIGH/LOW CURRENT MONITOR / REACTOR TRIP
//LOW SALT
if (SalinityPPM < UnderSALT)
{
lcd.clear();
lcd.setCursor ( 0, 0 );
lcd.print(" Chlorine Generator");
lcd.setCursor ( 0, 1 );
lcd.print(" NOTIFICATION ONLY ");
lcd.setCursor ( 0, 2 );
lcd.print("STATUS: LOW SALT");
lcd.setCursor ( 0, 4 );
lcd.print("<PLEASE CHECK POOL>");
digitalWrite (BUZZ, HIGH); // Audible Alarm
delay (2000);
}
else {
}
//HIGH SALT
if (SalinityPPM > OverSALT)
{
lcd.clear();
lcd.setCursor ( 0, 0 );
lcd.print(" Chlorine Generator");
lcd.setCursor ( 0, 1 );
lcd.print(" REACTOR SHUTDOWN");
lcd.setCursor ( 0, 2 );
lcd.print("OVER-CURRENT");
lcd.setCursor ( 13, 2 );
lcd.print(AcsValueF);
lcd.setCursor ( 18, 2 );
lcd.print("A");
lcd.setCursor ( 0, 4 );
lcd.print("PLEASE CHECK SYSTEM");
digitalWrite (mainRelay, LOW);
digitalWrite (BUZZ, HIGH); // Audible Alarm
delay (60000);
}
else {
}
// FLOW-SENSOR TEST AND DISPLAY UPDATE
if (digitalRead(FLOWsensor) == HIGH){
digitalWrite (mainRelay, LOW); // Flow Sensor is open - No water is flowing
delay(1000);
lcd.clear();
lcd.setCursor ( 0, 0 );
lcd.print(" Chlorine Generator");
lcd.setCursor ( 0, 1 );
lcd.print(" WARNING");
lcd.setCursor ( 0, 2 );
lcd.print("STATUS: LOW FLOW");
lcd.setCursor ( 0, 4 );
lcd.print(" REACTOR STOPPED");
}
else {
// THIS IS THE DISPLAY UPDATE PROTOCOL (FWD)
if (fwdState == LOW) {
lcd.clear();
lcd.print(" Chlorine Generator");
lcd.setCursor ( 0, 2 );
lcd.print("STATUS: GENERATING");
lcd.setCursor (0, 1 );
lcd.print(AcsValueF);
lcd.setCursor (5, 1 );
lcd.print("Amps");
lcd.setCursor (13, 1 );
lcd.print(SalinityPPM);
lcd.setCursor (17, 1 );
lcd.print("ppm");
lcd.setCursor ( 0, 4 );
lcd.print("MODE: --NORMAL--->>>");
}
else {
// THIS IS THE DISPLAY UPDATE PROTOCOL (REV)
lcd.clear();
lcd.print(" Chlorine Generator");
lcd.setCursor ( 0, 2 );
lcd.print("STATUS: GENERATING");
lcd.setCursor (0, 1 );
lcd.print(AcsValueF);
lcd.setCursor (5, 1 );
lcd.print("Amps");
lcd.setCursor (13, 1 );
lcd.print(SalinityPPM);
lcd.setCursor (17, 1 );
lcd.print("ppm");
lcd.setCursor ( 0, 4 );
lcd.print("MODE:<--CELL-REVERSE");
}
delay(Restart); //Delay on restart of generator - time for flow to resume and stabilize
digitalWrite (mainRelay, HIGH);// Flow Sensor is closed - Water-flow established
}
// + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
// check to see if it's time to Cycle the Electrodes; that is, if the difference
// between the current time and last time the electrodes cycled is greater than
// the interval at which the electrodes should be cycled.
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= revTime) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (fwdState == LOW) {
fwdState = HIGH;
} else {
fwdState = LOW;
}
// if the Relay is off turn it on and vice-versa:
if (fwdState == LOW) {
}
// if the Relay is off turn it on and vice-versa:
if (fwdState == LOW) {
revState = HIGH;
} else {
revState = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(FWDPolarity, fwdState);
}
}