#include <HCSR04.h>
#include <LiquidCrystal.h>
//HCSR04 hc(5, 6); //initialisation class HCSR04 (trig pin , echo pin)
UltraSonicDistanceSensor distanceSensor(5, 6); // Initialize sensor that uses digital pins 13 and 12.
const int rs = 12, en = 13, d4 = 11, d5 = 10, d6 = 9, d7 = 8;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
const int PumpPin = 7;
const int ButtonPin = 4;
String PumpStat = "Unknown";
String PumpCheck = "Unknown";
String ButtonStat = "Unknown";
String changeby = "unknown";
unsigned long JamAwal;
unsigned long Jam;
unsigned long changetime;
int changetimemin;
int Refill;
int rfj;
int rfm;
int rfd;
int Hitung = 0;
int kodeerror = 0;
int senattemp = 0;
float SensorValue;
float sen1;
float sen2;
float sen3;
float sen4;
float sensel;
float persen;
float liter;
float konversi;
// Variable Flowrate
int readCount = 0;
float flowRate = 0;
float flowRateAve = 0;
float lastLiter = 0;
unsigned long lastFlowRateCalcTime = 0;
byte logoair[9] = {
B00100,
B00100,
B01110,
B01110,
B11101,
B11101,
B01110,
B00000
};
byte logoplusmin[9] = {
B00100,
B00100,
B11111,
B00100,
B00100,
B00000,
B11111,
B00000
};
byte logolm[9] = {
B10000,
B10001,
B11010,
B00100,
B00000,
B11111,
B10101,
B00000
};
//KALIBRASI
int LowerLimit = 20; // Batas minimal sensor
int UpperLimit = 112; // Batas maximal sensor
int MinLevel = 35; // Mulai pengisian saat ... %
int MaxLevel = 100; // Berhenti pengisian saat ... %
int RefillDelay = 360; // Jadwal pengisian setiap ... menit
float literkal = 7.5; // ... liter per %
void setup() {
Serial.begin(9600);
lcd.createChar(0, logoair);
lcd.createChar(1, logoplusmin);
lcd.createChar(2, logolm);
lcd.begin(16, 2);
lcd.setCursor(1, 0);
lcd.print("- POMPA AIR -");
lcd.setCursor(4, 1);
lcd.print("- APIK -");
lcd.setCursor(9, 0);
lcd.write(byte(0));
pinMode(PumpPin, OUTPUT);
pinMode(ButtonPin, INPUT);
JamAwal = millis();
changetime = millis();
digitalWrite(PumpPin, LOW);
delay(500);
PumpOFF();
}
void loop() {
Jam = ( millis() - JamAwal ) / 1000;
Refill = ( RefillDelay * 60) - Jam;
rfj = Refill / 60 / 60;
rfm = (Refill / 60) % 60;
rfd = Refill % 60;
ReadSensor();
flowRateCalc();
Info();
LcdInfo();
if (( persen <= MinLevel ) || ( Refill <= 0 )) {
if ( persen <= MinLevel ) {
changeby = "ON BY MinLevel";
changetime = millis();
}
if ( Refill <= 0 ) {
changeby = "ON BY Refill";
changetime = millis();
}
PumpON();
}
if ( persen >= MaxLevel ) {
digitalWrite(PumpPin, HIGH);
}
ButtonCheck();
delay(200);
}
void ReadSensor() {
do {
delay(200);
//sen1 = hc.dist();
sen1 = distanceSensor.measureDistanceCm();
delay(200);
//sen2 = hc.dist();
sen2 = distanceSensor.measureDistanceCm();
delay(200);
//sen3 = hc.dist();
sen3 = distanceSensor.measureDistanceCm();
delay(200);
//sen4 = hc.dist();
sen4 = distanceSensor.measureDistanceCm();
sensel = (sen1 + sen2) - (sen3 + sen4);
/*
Serial.print( "S1 : ");
Serial.print( sen1 );
Serial.print( " | S2 : ");
Serial.print( sen2 );
Serial.print( " | S3 : ");
Serial.print( sen3 );
Serial.print( " | S4 : ");
Serial.print( sen2 );
Serial.print( " | SS : ");
Serial.print( sensel );
Serial.print( " | SA : ");
Serial.println( senattemp );
*/
PumpCheck = PumpStat;
ButtonCheck();
if (PumpCheck != PumpStat) {
break;
}
senattemp++;
if (senattemp >= 30) {
break;
}
} while ((sensel > 5) || (sensel < (-5)));
SensorValue = (sen1 + sen2 + sen3 + sen4) / 4;
// SensorValue = hc.dist();
if ((SensorValue > 200) || (senattemp >= 30)) {
SensorValue = 0;
kodeerror = 1;
} else {
kodeerror = 0;
}
senattemp = 0;
konversi = ((SensorValue - UpperLimit - LowerLimit) * (-1));
persen = ((konversi - LowerLimit) / (UpperLimit - LowerLimit) * 100);
liter = persen * literkal;
}
void flowRateCalc() {
if (readCount >= 5) {
flowRate = flowRateAve / float(readCount);
flowRateAve = 0;
readCount = 0;
}
unsigned long flowRateCalcTime = millis();
float elapsedTime = (flowRateCalcTime - lastFlowRateCalcTime) / 1000.0;
flowRateAve = flowRateAve + ((liter - lastLiter) * 60.0 / elapsedTime);
lastLiter = liter;
lastFlowRateCalcTime = flowRateCalcTime;
readCount++;
//flowRate = flowRateAve;
}
void PumpON() {
PumpStat = "ON";
JamAwal = millis();
//while ((persen <= MaxLevel) && (digitalRead(ButtonPin) == HIGH)) {
while (persen <= MaxLevel) {
digitalWrite(PumpPin, LOW);
Jam = ( millis() - JamAwal ) / 1000;
Refill = Jam ;
rfj = Refill / 60 / 60;
rfm = (Refill / 60) % 60;
rfd = Refill % 60;
ReadSensor();
Info();
LcdInfo();
if ( persen >= MaxLevel ) {
changeby = "OFF BY FULL";
changetime = millis();
}
ButtonCheck();
if (PumpStat == "OFF") {
break;
}
delay(200);
}
PumpOFF();
}
void PumpOFF() {
PumpStat = "OFF";
digitalWrite(PumpPin, HIGH);
JamAwal = millis();
Info();
LcdInfo();
delay(500);
}
void ButtonCheck() {
Hitung = 0;
while ( digitalRead(ButtonPin) == LOW) {
Hitung++;
if (Hitung >= 600) {
break;
}
delay(10);
}
if ((Hitung >= 20 ) && (Hitung < 500)) {
if (PumpStat == "OFF") {
digitalWrite(PumpPin, LOW);
Info();
PumpStat = "ON";
LcdInfo();
changeby = "ON BY Button";
changetime = millis();
delay(500);
Hitung = 0;
PumpON();
}
if (PumpStat == "ON") {
digitalWrite(PumpPin, HIGH);
Info();
PumpStat = "OFF";
changeby = "OFF BY Button";
changetime = millis();
LcdInfo();
delay(500);
Hitung = 0;
PumpOFF();
}
}
else if (Hitung >= 500) {
Hitung = 0;
InfoKal();
}
}
void Info() {
/*
Serial.print( "S1 : ");
Serial.print( sen1 );
Serial.print( " | S2 : ");
Serial.print( sen2 );
Serial.print( " | S3 : ");
Serial.print( sen3 );
Serial.print( " | S4 : ");
Serial.print( sen2 );
Serial.print( " | SS : ");
Serial.print( sensel );
Serial.print( " | S : ");
Serial.print( SensorValue );
Serial.print( " | K : ");
Serial.print( konversi );
Serial.print( " | % : ");
Serial.print( persen );
Serial.print( " | L : ");
Serial.print( liter );
Serial.print( " | PS : ");
Serial.print( PumpStat );
Serial.print( " | T : ");
Serial.print( Jam );
Serial.print( " | RF : " );
Serial.print( Refill / 60 );
Serial.print( "J" );
Serial.print( Refill % 60 );
Serial.print( " | BT : " );
Serial.println( ButtonStat );
if (kodeerror == 1) {
Serial.println ("Sensor Error");
}
*/
}
void LcdInfo() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print( " : % L" );
lcd.setCursor(0, 0);
lcd.write(byte(0));
lcd.setCursor(2, 0);
if (persen <= 0.00) {
lcd.print("0.00");
}
else {
lcd.print( persen );
}
lcd.setCursor(7, 0);
lcd.print("%");
lcd.setCursor(9, 0);
lcd.write(byte(1));
lcd.setCursor(10, 0);
if (liter <= 0.00) {
lcd.print("0.00");
}
else {
lcd.print( liter );
lcd.setCursor(15, 0);
lcd.print("L");
}
/*
lcd.setCursor(9, 0);
lcd.print( SensorValue );
lcd.setCursor(14, 0);
lcd.print( "CM" );
*/
lcd.setCursor(0, 1);
/*
lcd.print( "PUMP: " );
if ( PumpStat == "ON" ) {
lcd.setCursor(6, 1);
}
else {
lcd.setCursor(5, 1);
}
lcd.print( PumpStat );
*/
if ((flowRate > -100) && (flowRate < 100)) {
lcd.setCursor(1, 1);
}
if ((flowRate > -10) && (flowRate < 10)) {
lcd.setCursor(2, 1);
}
if (flowRate == 0) {
//lcd.print("o");
lcd.write(byte(127));
lcd.write(byte(126));
} else if (flowRate > 0) {
lcd.print("+");
}
lcd.print(flowRate);
lcd.setCursor(7, 1);
lcd.write(byte(2));
lcd.setCursor(9, 1);
lcd.print(rfj);
lcd.print(":");
if (rfm < 10) {
lcd.print("0");
}
lcd.print(rfm);
lcd.print(":");
if (rfd < 10) {
lcd.print("0");
}
lcd.print(rfd);
if (kodeerror == 1) {
lcd.setCursor(0, 0);
lcd.print(" !!! ERROR !!! ");
lcd.setCursor(0, 1);
lcd.print(" Check Sensor ");
}
}
void InfoKal() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print( "L Mn RF " );
lcd.setCursor(1, 0);
lcd.print(LowerLimit);
lcd.setCursor(7, 0);
lcd.print(MinLevel);
lcd.setCursor(13, 0);
lcd.print(RefillDelay);
lcd.setCursor(0, 1);
lcd.print( "U Mx K " );
lcd.setCursor(1, 1);
lcd.print(UpperLimit);
lcd.setCursor(7, 1);
lcd.print(MaxLevel);
lcd.setCursor(12, 1);
lcd.print(literkal);
delay(3000);
lcd.setCursor(0, 0);
lcd.print(sen1);
lcd.print(" ");
lcd.print(sen2);
lcd.print(" ");
lcd.print(sensel);
lcd.setCursor(0, 1);
lcd.print(sen3);
lcd.print(" ");
lcd.print(sen4);
lcd.print(" ");
lcd.print(SensorValue);
delay(1000);
lcd.scrollDisplayLeft();
delay(1000);
lcd.scrollDisplayLeft();
delay(1000);
lcd.scrollDisplayRight();
delay(1000);
lcd.scrollDisplayRight();
delay(1000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(changeby);
lcd.setCursor(0, 1);
changetimemin = ( millis() - changetime ) / 60000;
lcd.print(changetimemin);
lcd.setCursor(4, 1);
lcd.print("MINUTES AGO");
delay(3000);
}