/*
Sketch generated by the Arduino IoT Cloud Thing "Untitled"
https://create.arduino.cc/cloud/things/495fceb7-af0e-414a-8fb2-8f8f2a58ccd2
Arduino IoT Cloud Variables description
The following variables are automatically generated and updated when changes are made to the Thing
CloudLight led;
CloudLength lowlevel;
CloudLength highlevel;
CloudLength tankheight;
CloudLength waterlevel;
Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
which are called when their values are changed from the Dashboard.
These functions are generated with the Thing and added at the end of this sketch.
*/
// #include "thingProperties.h"
#include <HCSR04.h>
#include <millisDelay.h>
//LCD
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display
#include <EEPROM.h>
// int addr = 0;
// int addr2 = 1;
int flag = 0;
int flagFlowErr = 0;
//int flagFlowErrCount = 0;
byte readval;
//#define resetPin 12
//int buttonState = 0;
float WaterLevelMAX, GapbwSonar, SonarReading, ActualReading, Temp;
int percentage = 0, oldpercentage = 0;
int percentLevelUpCount = 0, percentLevelDownCount = 0, percentLevelSameCount = 0, percentLevelSameMCount = 0;
double TankHeight;
unsigned int baseAddr = 0;
// Define Trig and Echo pin: LED Pin
#define trigPin 5
#define echoPin 4
#define powerPin 15
#define MOTOR_CONTROL_PIN 2
#define MOTORPIN 14 // Pump Relay
#define led2 13
boolean ledOn = false;
millisDelay levelCheckDelay;
// Define variables:
// long duration;
// int distance;
int waterLevelUpCount = 0;
int waterLevelDownCount = 0;
//int lowlevel = 80;
//int highlevel = 140;
//int tankheight = 150;
//Button
const byte buttonPins[] = {18,19}; // LEFT, UP, RIGHT, DOWN const byte buttonPins[] = {4, 2, 5, 3}; // LEFT, UP, RIGHT, DOWN
typedef enum {
Red,
Green,
} Direction;
Direction dir;
Direction newDir;
int waterTriggerLevel = 50;
int led = HIGH;
int waterlevel = 0;
int waterLevelLow = 80;
int waterLevelHigh = 150;
int waterTankHeight = 200;
float distance;
int maxDistanceCm = 350;
const unsigned int MAX_DIST = 23200;
//UltraSonicDistanceSensor distanceSensor(trigPin, echoPin,maxDistanceCm); // Initialize sensor that uses digital pins 13 and 12.
// UltraSonicDistanceSensor distanceSensor(trigPin, echoPin);
void setup() {
EEPROM.begin(10);
// Initialize serial and wait for port to open:
Serial.begin(9600);
// Define inputs and outputs
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(powerPin, OUTPUT);
pinMode(MOTOR_CONTROL_PIN,OUTPUT);
pinMode(MOTORPIN, OUTPUT);// Relay pin as output pin
digitalWrite(MOTORPIN, LOW); //Turn off the relay
// pinMode(led, OUTPUT);
pinMode(led2, OUTPUT);
digitalWrite(led2, LOW);
ledOn = false;
levelCheckDelay.start(6000); /// led blink delay of 6000 is 6 sec
// we should have 300 sec or 5 min
//Button Setup
for (byte i = 0; i < 2; i++) {
pinMode(buttonPins[i], INPUT_PULLUP);
}
dir = Red;
newDir = Red;
// LCD
lcd.init(); // initialize the lcd
// Print a message to the LCD.
lcd.backlight();
lcd.setCursor(1,0);
lcd.print("Hello, Kaavya!");
lcd.setCursor(0,1);
lcd.print("*Motomatic Pro*");
// lcd.setCursor(0,2);
// lcd.print("Arduino LCM IIC 2004");
// lcd.setCursor(2,3);
// lcd.print("Power By Ec-yuan!");
// This delay gives the chance to wait for a Serial Monitor without blocking if none is found
delay(1500);
// lcd.noBacklight(); // turn backlight off
//pinMode(resetPin, INPUT_PULLUP);
lcd.clear();
lcd.setCursor(0, 0);
// lcd.print("Starting ARDUINO, ");
// lcd.setCursor(0, 1);
lcd.print(" Press SCAN to ");
lcd.setCursor(0, 1);
lcd.print("ChangeTankHeight");
// lcd.setCursor(0, 3);
// lcd.print("If Required ");
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Confirm Tank Be");
lcd.setCursor(0, 1);
lcd.print("Empty to SetTank");
// lcd.setCursor(0, 2);
// lcd.print("Height using Sonar ");
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Now Scan 2 Change");
lcd.setCursor(0, 1);
lcd.print("Tank Height to New");
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Long Press Button...");
for (int i=0; i<=5; i++)
{
lcd.setCursor(0, 1);
lcd.print("Hold:");
lcd.print(5-i);
lcd.print("Sec ");
// buttonState = digitalRead(resetPin);
Serial.print("Button State : ");
Serial.println(buttonPress());
if (buttonPress())
{
TankHeight = ping_cm();
EEPROM_writeAnything( baseAddr, TankHeight);
lcd.print("Ht.");
lcd.print(TankHeight);
Serial.print("Tank Height New : ");
Serial.println(TankHeight);
// Serial.print("EEPROM : ");
// Serial.println( EEPROM.read(addr));
}
delay(1000);
}
EEPROM.commit();
EEPROM_readAnything( baseAddr, TankHeight);
Serial.print("Tank Height Old: ");
Serial.println(TankHeight);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Tank New Height Set@");
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.print(TankHeight);
lcd.print("cm ");
lcd.setCursor(0, 2);
lcd.print("Cheers ");
// lcd.setCursor(0, 3);
// lcd.print("WELCOME to SMART ");
delay(2000);
lcd.clear();
lcd.setCursor(0, 2);
lcd.print("TANK HEIGHT: ");
lcd.setCursor(12, 2);
lcd.print(TankHeight);
lcd.print("cm ");
WaterLevelMAX=0.9*TankHeight; // 10CM GAP BETWEEN MAX WATER LEVEL TO SONAR FIX
GapbwSonar=TankHeight-WaterLevelMAX;
// Defined in thingProperties.h
// initProperties();
// Connect to Arduino IoT Cloud
// ArduinoCloud.begin(ArduinoIoTPreferredConnection);
/*
The following function allows you to obtain more information
related to the state of network and IoT Cloud connection and errors
the higher number the more granular information you’ll get.
The default is 0 (only errors).
Maximum is 4
*/
// setDebugMessageLevel(2);
// ArduinoCloud.printDebugInfo();
}
void loop()
{
// ArduinoCloud.update();
// Your code here
digitalWrite(powerPin,HIGH);//SR04 active HIGH given 5V
if(levelCheckDelay.justFinished())
{
levelCheckDelay.repeat();
/*
ledOn = !ledOn;
if(ledOn) {
digitalWrite(led2, HIGH);
} else {
digitalWrite(led2, LOW);
}
*/
if ( percentage > oldpercentage + 5 ) //Flow Increasing
percentLevelUpCount++;
else percentLevelUpCount=0;
if ( percentage < oldpercentage - 5 ) //Flow Decreasing
percentLevelDownCount++;
else percentLevelDownCount=0;
if ( percentage == oldpercentage && flag == 1 ) //Flow Not Increasing Motor ON
percentLevelSameMCount++;
else percentLevelSameMCount=0;
if ( percentage == oldpercentage && flag == 0) //Flow Not Increasing
percentLevelSameCount++;
else percentLevelSameCount=0;
if(percentLevelUpCount==3)
{//Flow Increasing
lcd.setCursor(8, 1);
lcd.print("FLOW:Inc");
// Serial.println("motor turned on");
//led=HIGH;
digitalWrite(led2,HIGH);
oldpercentage = percentage;
// flagFlowErrCount = 0 ; //Reset FlowErrCount
}
if(percentLevelDownCount==3)
{//Flow Decreasing
lcd.setCursor(8, 1);
lcd.print("FLOW:Dec");
// Serial.println("motor turned off");
// led=LOW;
digitalWrite(led2,LOW);
oldpercentage = percentage;
}
if(percentLevelSameMCount==5)
{//Flow Not Increasing even if motor is on
lcd.setCursor(8, 1);
lcd.print("FLOW:Err");
// Serial.println("motor turned off");
// led=LOW;
digitalWrite(led2,LOW);
oldpercentage = percentage;
flag = 0; // Turn Motor Off
flagFlowErr = 1; // Flow Error Flag
}
if(percentLevelSameCount==3)
{//Flow Not Increasing with motor is off
lcd.setCursor(8, 1);
lcd.print(" ");
digitalWrite(led2,LOW);
// Serial.println("motor turned off");
// led=LOW;
//digitalWrite(led2,LOW);
oldpercentage = percentage;
//flag = 0; // Turn Motor Off
flagFlowErr = 0; // Reset Flow Error Flag
}
}
/*
// Clear the trigPin by setting it LOW:
digitalWrite(trigPin, LOW);
delayMicroseconds(5);
// Trigger the sensor by setting the trigPin high for 10 microseconds:
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Read the echoPin. pulseIn() returns the duration (length of the pulse) in microseconds:
duration = pulseIn(echoPin, HIGH);
// Calculate the distance:
distance = duration*0.034/2;
// Print the distance on the Serial Monitor (Ctrl+Shift+M):
Serial.print("Distance = ");
Serial.print(distance);
Serial.println(" cm");
*/
// Every 500 miliseconds, do a measurement using the sensor and print the distance in centimeters.
/* distance = distanceSensor.measureDistanceCm();
delay(1500);
Serial.print("Distance Sensor Output = ");
Serial.print(distance);
Serial.println(" cm");
*/
distance = ping_cm(); // call function new made
Serial.print("Distance Sensor Output = ");
Serial.print(distance);
Serial.println(" cm");
SonarReading = distance;
Temp= SonarReading-GapbwSonar;
ActualReading= WaterLevelMAX-Temp;
percentage=(ActualReading/WaterLevelMAX*100);
Serial.print("Percentage = ");
Serial.println(percentage);
lcd.setCursor(0, 0);
lcd.print("WATER LEVEL:");
lcd.print(percentage);
lcd.print("% ");
// if(DRYsensorValue>=100)
// {
if(percentage<=waterTriggerLevel && flagFlowErr == 0)
{
// lcd.setCursor(0, 0);
// lcd.print("SUMP:WaterFilled");
lcd.setCursor(0, 1);
lcd.print("PUMP:On ");
digitalWrite(MOTORPIN, HIGH);
flag=1;
// EEPROM.write(addr2, flag);
// flag= EEPROM.read(addr2);
// ZeroPercentage();
}
else if(percentage<=waterTriggerLevel && flagFlowErr ==1)
{
// lcd.setCursor(0, 0);
// lcd.print("SUMP:WaterFilled");
lcd.setCursor(0, 1);
lcd.print("PUMP:Off");
digitalWrite(MOTORPIN, LOW);
flag=0;
// flagFlowErr=0;
// EEPROM.write(addr2, flag);
// flag= EEPROM.read(addr2);
// ZeroPercentage();
}
else if(percentage>waterTriggerLevel && percentage<=100)
{
// flag= EEPROM.read(addr2);
if(percentage>waterTriggerLevel && percentage<=100 && flag ==1)
{
digitalWrite(MOTORPIN, HIGH);
// digitalWrite(EXTRELAYPIN, LOW);
lcd.setCursor(0, 1);
lcd.print("PUMP:On ");
}
else if(percentage>waterTriggerLevel && percentage<=100 && flag ==0)
{
digitalWrite(MOTORPIN, LOW);
lcd.setCursor(0, 1);
lcd.print("PUMP:Off");
}
}
else if(percentage>100)
{
delay(500);
lcd.setCursor(0, 1);
lcd.print("PUMP:Off");
// lcd.setCursor(0, 0);
// lcd.print("Water Level:");
// lcd.print("100");
// lcd.print("% ");
digitalWrite(MOTORPIN, LOW);
flag=0;
//EEPROM.write(addr2, flag);
//flag= EEPROM.read(addr2);
// HundredPercentage();
}
//}
/* else if(DRYsensorValue<=100)
{
flag= EEPROM.read(addr2);
if(flag==1)
{
// lcd.clear();
lcd.setCursor(0, 3);
lcd.print("SUMP: WATER FILLED ");
lcd.setCursor(0, 1);
lcd.print("PUMP:Dry");
digitalWrite(BUZZER, HIGH);
digitalWrite(MOTORPIN, LOW);
digitalWrite(BUZZER, LOW);
}
else if(flag==0)
{
lcd.setCursor(0, 3);
lcd.print("SUMP: NOWATER/CHECK");
}
}
*/
delay(1000);
if ( distance > 1 && distance < maxDistanceCm )
waterlevel = waterTankHeight - distance;
// if ( waterlevel > waterTankHeight )
// waterlevel = waterTankHeight;
// if ( waterlevel < 0 )
// waterlevel = 0;
Serial.print("Water level = ");
Serial.print(waterlevel);
Serial.println(" cm");
//Debug
// Serial.print("FlagFlowLevelCount=");
// Serial.println(flagFlowErrCount);
// temperature = distance;
// delay(100);
if(waterlevel<=waterLevelLow)
waterLevelDownCount++;
else waterLevelDownCount=0;
if(waterlevel>=waterLevelHigh)
waterLevelUpCount++;
else waterLevelUpCount=0;
// waterLevel.publish(liters);
if(waterLevelDownCount==3)
{//TURN ON RELAY
Serial.println("Motor turned On");
led=HIGH;
digitalWrite(MOTOR_CONTROL_PIN,HIGH);//Relay is active HIGH
}
if(waterLevelUpCount==3)
{//TURN OFF RELAY
Serial.println("Motor turned off");
led=LOW;
digitalWrite(MOTOR_CONTROL_PIN,LOW);//Relay is active HIGH
}
if(buttonPress())
{
readDirection();
dir = newDir;
lcd.backlight();
lcd.setCursor(0,0);
lcd.print("Button Pressed ");
lcd.print(dir);
Serial.print("ButtonPressed ");
Serial.print(dir);
Serial.println();
delay(2000);
}
else
{
// lcd.noBacklight();
// lcd.setCursor(0,0);
// lcd.print("No ButtonPressed");
}
}
//Loop END
// Distance Function
float ping_cm()
{
digitalWrite(powerPin,HIGH);//SR04 active HIGH given 5V
unsigned long t1;
unsigned long t2;
unsigned long pulse_width;
float cm;
float inches;
// Hold the trigger pin high for at least 10 us
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Wait for pulse on echo pin
while ( digitalRead(echoPin) == 0 );
// Measure how long the echo pin was held high (pulse width)
// Note: the micros() counter will overflow after ~70 min
t1 = micros();
while ( digitalRead(echoPin) == 1);
t2 = micros();
pulse_width = t2 - t1;
// Calculate distance in centimeters and inches. The constants
// are found in the datasheet, and calculated from the assumed speed
//of sound in air at sea level (~340 m/s).
cm = pulse_width / 58.0;
inches = pulse_width / 148.0;
// Print out results
if ( pulse_width > MAX_DIST ) {
Serial.println("Out of range");
} else {
Serial.print(cm);
Serial.print(" cm \t");
Serial.print(inches);
Serial.println(" in");
}
return(cm);
}
//Button Function
bool buttonPress() {
for (byte i = 0; i < 2; i++) {
byte buttonPin = buttonPins[i];
if (digitalRead(buttonPin) == LOW) {
return true;
}
}
return false;
}
void readDirection() {
for (byte i = 0; i < 2; i++) {
byte buttonPin = buttonPins[i];
if (digitalRead(buttonPin) == LOW && i != ((int)dir + 2) % 2) {
newDir = (Direction)i;
return;
}
}
}
//EEPROM Long size to store
template <class T> int EEPROM_writeAnything(int ee, const T& value)
{
const byte* p = (const byte*)(const void*)&value;
int i;
for (i = 0; i < sizeof(value); i++)
EEPROM.write(ee++, *p++);
return i;
}
template <class T> int EEPROM_readAnything(int ee, T& value)
{
byte* p = (byte*)(void*)&value;
int i;
for (i = 0; i < sizeof(value); i++)
*p++ = EEPROM.read(ee++);
return i;
}
/* ONLY TO DEFINE FOR ESP Cloud
void onLedChange() {
// Do something
if (led == 1)
{
digitalWrite(MOTOR_CONTROL_PIN,HIGH);
led=HIGH;
waterLevelUpCount=0;
}
else
{
digitalWrite(MOTOR_CONTROL_PIN,LOW);
led=LOW;
waterLevelDownCount=0;
}
}
void onPressureChange() {
// Do something
}
void onLowlevelChange() {
// Do something
waterLevelLow = lowlevel;
}
void onHighlevelChange() {
// Do something
waterLevelHigh = highlevel;
}
void onTankheightChange() {
// Do something
waterTankHeight = tankheight;
}
void onWaterlevelChange() {
// Do something
}
ONLY TO DEFINE FOR ESP Cloud */