Sump pump water level monitor: ultrasonic sensor HC-SR04, wifi module ESP8266, and Gmail sender

A few months ago, my sump pump float switch failed. It was second time since we moved in this house a few years ago. There are a few different types of float switches in the store and mine was one of those popular ones: a pig-tailed plastic float with a metal ball inside, like the one in below picture.

Selection_033

I asked how long they can guarantee this type of float switch to a salesclerk at the store when I bought a new one, and he said it’s only 1 year. It has very weak point where the electric wire bends as the float moving up and down so many times. So 1 year guarantee seems to be understandable. But it’s not cheap for its simple and weak design.

I tried to find a better switch, but unfortunately, there was no other option on that day. It was in February and rained a lot for unusual warm weather this year. At that time, the sump pump runs almost every 10-20 minutes, so I couldn’t look around the stores to find a better switch and had to buy whatever available and replace it immediately, which I did.

But I started worrying about its failure when nobody’s at home and doing some research on the backup plans. There are existing products and ideas you can find through internet search including a second pump with a second switch and backup power supply like a emergency generator or a UPS battery. There are also a venturi pump using city water line which doesn’t need electricity for the pump. I think this venturi pump might be a good solution and maybe I will investigate this option further later.

Anyway, since I replaced the float switch, I knew it would work at least a year. But I needed to have some backup system and monitoring system.

For a backup system, I assumed the pump itself can work much longer than the switch which is true, and decided to add another float switch with different type that has a floater with a rod that triggers the switch (see below picture for example). A good thing about this switch is the electric wire is not the part of the mechanical movement, so its lifetime is much longer than the ball float type.

Selection_034

I have arranged this second backup switch a little higher than the ball float so that it can trigger the pump when the ball float switch fails.

Selection_036

This prevents overflow by the ball float switch failure, but that’s not enough. I need to know when it happens. So I decided to put a sensor to monitor the water level and send me notification by either emails or text messages to my cell phone. There are many ways to sense the water level, using like resistance or inductance based immersed electrodes, a series of mechanical float switches, optical sensors, or ultrasonic sensor.

I had heard about the ultrasonic sensor, HC-SR04 with Arduino before, but had never bought or used it. One attractive thing about this option is that it’s a non-contact measurement which means there is no mechanical moving parts involved so it has relatively longer lifetime. My younger son, who used to be a programmer for the FIRST robotics robots and is now studying Mechatronics in university, had experience with an ultrasonic sensors to measure the distance from the robot body to an object, and he recommended to use it for water level monitoring. I wasn’t sure about the accuracy, but my son said it was quite accurate for cm ranges. So I ordered one of those HC-SR04 and tried with my Jeonlab mini and it worked perfectly. I don’t need mm scale but cm scale is just good enough for this type of measurements.

Now, I needed a solution to drive the sensor and interface to send the messages to my email or phone. ESP8266-01 seemed to me a good choice because it has even more memory (not that I need bigger memory for this project) than Jeonlab mini (ATmega328p based Arduino variant) and two GPIO pins as well as wifi interface. The sensor has two pins, trigger and echo. So, that’s perfect combination.

The entire circuit diagram including voltage regulator is as below.

Selection_035

One thing you need to consider with this combination is the voltages for those two devices. The HC-SR04 need 5V while the ESP8266 needs 3.3V. So the trigger line is fine from ESP8266 because 3.3V is high enough to trigger HIGH on HC-SR04, but the echo signal from the HC-SR04 is 5V and need to be converted to 3.3V using either voltage divider or a transistor. In my case, I used a NPN transistor because the GPIO0 needs to be pulled up for normal booting anyway.

Here is some pictures of assembled sump pump water level monitoring system.

Now the programming part.  I searched and found this link and followed his instructable and it worked perfectly with Gmail. He explained well how to set up the wifi account in his instructable and all the core program is his work, so I put only the setup() and loop() part and distance conversion function for the HC-SR04 below.


void setup()
{
int cm;
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
Serial.begin(115200);
connection_state = WiFiConnect();
if (!connection_state) // if not connected to WIFI
Awaits(); // constantly trying to connect

Gsender *gsender = Gsender::Instance(); // Getting pointer to class instance
String subject;
subject = "Sump pump monitor started";if (gsender->Subject(subject)->Send("your_gmail_here@gmail.com", "")) {
Serial.println("Message send.");
} else {
Serial.print("Error sending message: ");
Serial.println(gsender->getError());
}

do {
cm = measure_cm();
if (count == 0) {
level_high = cm;
level_low = cm;
}
else {
if (cm < level_high) level_high = cm;
if (cm > level_low) level_low = cm;
}

count++;
delay(120000);
} while (count < 40);

subject = "High: " + String(level_high) + " Low: " + String(level_low);

if (gsender->Subject(subject)->Send("your_gmail_here@gmail.com", "")) {
Serial.println("Message send.");
} else {
Serial.print("Error sending message: ");
Serial.println(gsender->getError());
}
count = 0;
}

void loop() {
int cm = measure_cm();
Gsender *gsender = Gsender::Instance();
String subject, interval;

if (cm < level_high - 5) {
subject = "Sump water level HIGH: " + String(cm);
if (gsender->Subject(subject)->Send("your_at&t phone_number@txt.att.net", "")) {
Serial.println("Message send.");
} else {
Serial.print("Error sending message: ");
Serial.println(gsender->getError());
}
}
if (cm - previous_cm > 10 && previous_cm != 0) {
subject = "Sump pump ON: " + String(previous_cm) + " to " + String(cm);
interval = String((millis() - mil_sec) / milsec_to_min) + " minutes";
mil_sec = millis();
if (gsender->Subject(subject)->Send("your_gmail_here@gmail.com", interval)) {
Serial.println("Message send.");
} else {
Serial.print("Error sending message: ");
Serial.println(gsender->getError());
}
count = 0;
}
if (count > 29) {
subject = "Current water level: " + String(cm);
if (gsender->Subject(subject)->Send("your_gmail_here@gmail.com", "")) {
Serial.println("Message send.");
} else {
Serial.print("Error sending message: ");
Serial.println(gsender->getError());
}
count = 0;
}
previous_cm = cm;
count++;
delay(60000);
}

int measure_cm() {
long duration;
int cm, cm_sum = 0, cm_min = 0, cm_max = 0, count = 0;

do {
// trigger 10us pulse
digitalWrite(trigPin, 0);
delayMicroseconds(5);
digitalWrite(trigPin, 1);
delayMicroseconds(10);
digitalWrite(trigPin, 0);

duration = pulseIn(echoPin, 0);

// convert the time into a distance
cm = duration / 58;
if (count == 0) {
cm_min = cm;
cm_max = cm;
}
else {
if (cm < cm_min) cm_min = cm;
if (cm > cm_max) cm_max = cm;
}
cm_sum = cm_sum + cm;

count++;
delay(1000);
} while (count < 10);

cm_sum = cm_sum - cm_min - cm_max;
cm = cm_sum / 8;

return cm;
}

It keeps monitoring water level and when the pump runs (sudden change in level), it sends an email to me. If it doesn’t run after 30 minutes, it also send me an email with current level to ensure the monitoring system is working and the power is on. If the water level is higher than a threshold, it sends a text message to my phone so that it notify me there is a either pump or switch issue.

Update:
I found a little problem in the code. That is, the sump pump used to run so often, every 20 minutes or so, earlier this year. I guess that was because of melted ice in the soil and it rained often at that time. So I thought monitoring the water level for 2 hours should be enough to measure the highest and lowest level. The lowest level is not used, but the highest level is used to detect the issues either the pump or the float switches. However, these days in July, warm and dry weather seems to dry up the soil and my sump pump does not run that often. Recent report to my Gmail shows it has run every 3 hours or so.

It was yesterday that there was brief power out that was barely noticeable. But because of this, the my circuit got reset and it started measure the highest and lowest water level again. Unfortunately, it finished its measurements before the full cycle ends. As a result, the highest level was wrong, about 100mm below the actual highest level. Now you might guess what happened. Because I set in the program that it sends me a text message if the water level is higher that the highest level by 50mm, it kept sent me text messages. I ran down to my basement only to find the pump working fine. And then I realized I need to update my program. I put the updated code below. It now keeps monitoring the water level and update the highest and lowest values until the sump pump runs twice which is long enough to monitor the highest and lowest water level.


void setup()
{
int cm;
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
Serial.begin(115200);
connection_state = WiFiConnect();
if (!connection_state) // if not connected to WIFI
Awaits(); // constantly trying to connect

Gsender *gsender = Gsender::Instance(); // Getting pointer to class instance
String subject;
subject = "Sump pump monitor started";
if (gsender->Subject(subject)->Send("your_gmail@gmail.com", "")) {
Serial.println("Message send.");
} else {
Serial.print("Error sending message: ");
Serial.println(gsender->getError());

}

level_high = 50;
level_low = 50;

count = 0;
}

void loop() {
int cm = measure_cm();
Gsender *gsender = Gsender::Instance();
String subject, message;

if (cm < level_high - 5 && pumpCount == 2) {
subject = "Sump water level HIGH: " + String(cm);
if (gsender->Subject(subject)->Send("your AT&T phone number@txt.att.net", "")) {
Serial.println("Message send.");
} else {
Serial.print("Error sending message: ");
Serial.println(gsender->getError());
}
}
if (cm - previous_cm > 10 && previous_cm != 0) {
level_high = previous_cm;
level_low = cm;
subject = "Sump pump ON: " + String(previous_cm) + " to " + String(cm);
message = String((millis() - mil_sec) / milsec_to_min) + " minutes";
mil_sec = millis();
if (gsender->Subject(subject)->Send("your_gmail@gmail.com", message)) {
Serial.println("Message send.");
} else {
Serial.print("Error sending message: ");
Serial.println(gsender->getError());
}
count = 0;
if (pumpCount != 2) pumpCount++;
}
if (count > 29) {
subject = "Current water level: " + String(cm);
message = "High: " + String(level_high)+ " Low: " + String(level_low);
if (gsender->Subject(subject)->Send("your_gmail@gmail.com", message)) {
Serial.println("Message send.");
} else {
Serial.print("Error sending message: ");
Serial.println(gsender->getError());
}
count = 0;
}
if (cm < level_high) level_high = cm;
if (cm > level_low) level_low = cm;
previous_cm = cm;
count++;
delay(milsec_to_min);
}

Advertisements
About

Opto-mechatronic Engineering scientist.

Posted in Electronics

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

June 2017
S M T W T F S
« Jan    
 123
45678910
11121314151617
18192021222324
252627282930  
Archives

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 12 other followers

%d bloggers like this: