Set up an IoT Sump Pump Monitor with machinechat JEDI One, a SEN0287 AC Current Sensor and WiFi

Description

This project sets up an Arduino MKRWIFI1010 board and DFRobot SEN0287 to monitor AC current in a home sump pump and track when it turns on and off. Whenever the sump pump changes state, the MKRWIFI1010 uses WiFi to HTTP post the sump pump state to the JEDI One IoT data platform. JEDI One is used to remotely track and display the state of the sump pump and calculate and display the hourly rate the sump pump is on. JEDI One is running on a Raspberry Pi 4.

image

Hardware

Software

  • JEDI One
    JEDI One is a ready-to-use IoT data management software solution. Capabilities include: collect data from sensors, devices and machines; build intuitive real-time and historical data and system view dashboards; create rules to monitor and respond to data conditions automatically; receive alert notifications by email and SMS.
  • Arduino
    Arduino is an open-source electronics platform based on easy-to-use hardware and software.

Background

For many homes with basements a common issue is a wet or damp basement due to a high water table or poor drainage around the foundation. The typical solution for this issue is have drain tile around the house and pump out the water that collects in the drainage system with a sump pump. Sump pumps are generally automatic water pumps that utilize a float (or some other mechanism) to turn the pump on when the water reaches a certain high level and off when the water decreases to a certain low level.

Implementation

For this project, the MKRWIFI1010 board provides 5V power to the SEN0287 AC current sensor board and the sensor’s analog output is wired to it’s A0 analog input to measure AC current. The SEN0287 AC current transformer is clamped around one of the sump pump’s AC power lines. Below schematic diagram illustrates how the circuit is wired up and implemented.

Electrical connections are shown below:

MKRWIFI1010 pin SEN0287 AC Current Sensor connector
GND 1 GND
5 V 2 Power Input
A0 3 Signal Output

Set up the MKRWIFI1010 and SEN0287 sensor

1 - Set up Arduino on the MKRWIFI1010. See link Getting started with the MKR WiFi 1010

2 - Install libraries needed for application. Add these libraries thru Arduino’s Library Manager:

3 - Code walkthrough (filename: MKR1010wifiACcurrentSEN0287.ino)

Initial setup and connect to Wifi network

#include <Arduino.h>
#include <WiFiNINA.h>
#include <ArduinoHttpClient.h>
#include "arduino_secrets.h" 
#include <Wire.h>  //this is not needed

#include <ArduinoJson.h>   //include Json library
// Create a unique ID for the data from the MKRWIFI1010 running this code
const char* jediID = "MKR1010WiFiSensor_Sump";

///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;        // your network SSID (name)
char pass[] = SECRET_PASS;    // your network password (use for WPA, or use as key for WEP)
int status = WL_IDLE_STATUS;     // the Wifi radio's status
static int wifiConnectTry = 0;

// IP address of server or Raspberry Pi running Machinechat JEDI software
// If you changed the JEDI port number, replace 8100 with the new port
char serverAddress[] = "192.168.1.7";  // server address
int port = 8100;

WiFiClient client;
HttpClient http = HttpClient(client, serverAddress, port);



const int ACPin = A0;         //set arduino signal read pin for AC current sensor
#define ACTectionRange 5;    //set Non-invasive AC Current Sensor tection range (5A,10A,20A)

// VREF: Analog reference
// For Arduino UNO, Leonardo and mega2560, etc. change VREF to 5
// For Arduino Zero, Due, MKR Family, ESP32, etc. 3V3 controllers, change VREF to 3.3
#define VREF 3.3

unsigned long start, finished, elapsed;
int Istate = 0; //current sensor state 1 = ON, 0 = OFF
int loop_ctr = 0;  //counter for wifi connects

AC current calculation

// routine for reading current from DFRobot code for SEN0287
float readACCurrentValue()
{
  float ACCurrtntValue = 0;
  float peakVoltage = 0;  
  float voltageVirtualValue = 0;  //Vrms
  for (int i = 0; i < 5; i++)
  {
    peakVoltage += analogRead(ACPin);   //read peak voltage
    delay(1);
  }
  peakVoltage = peakVoltage / 5;   //average out peak voltage
  peakVoltage = peakVoltage - 5.12; //calibrate out 0 current ADC reading (about 5mV)
  if (peakVoltage < 0.03) peakVoltage = 0; // zero out 0 current measurement
 
  voltageVirtualValue = peakVoltage * 0.707;    //change the peak voltage to the Virtual Value of voltage
  /*The circuit is amplified by 2 times, so it is divided by 2.*/
  voltageVirtualValue = (voltageVirtualValue / 1024 * VREF ) / 2;  
  ACCurrtntValue = voltageVirtualValue * ACTectionRange;

  return ACCurrtntValue;
}

Set up sensor data in JSON format and send to JEDI One using HTTP post

void loop() 
{
    // prep for sending HTTP post to JEDI One
  String postData1; //Json string 
  StaticJsonDocument <200> doc;
  
  float ACCurrentValue = readACCurrentValue(); //read AC Current Value
  Serial.print(ACCurrentValue);
  Serial.println(" A");

   // try reconnecting if not connected   
  if (WiFi.status() != WL_CONNECTED) {
        Serial.println("not connected to WiFi, try reconnecting");
        WiFi.disconnect();
        WiFi.end();
        delay(5000);
        wifiConnect();
      }

   Serial.print("WiFi status code: ");
   Serial.println(WiFi.status());
   Serial.print("WiFi reconnect trys = ");
   Serial.println(wifiConnectTry);


  //check if AC current is ON and current Istate = 0
  if ((ACCurrentValue > 0.05) && (Istate == 0)){
    digitalWrite(LED_BUILTIN, HIGH);
    start = millis();
    Istate = 1;
    //Following code creates the serialized JSON string to send to JEDI One
    //using ArduinoJson library
    //StaticJsonDocument <200> doc;  //move to start of loop
    JsonObject context = doc.createNestedObject("context");
    context["target_id"] = String(jediID);
    JsonObject data = doc.createNestedObject("data");
    data["Isensor"] = Istate;
    data["MilliStamp"] = start;
    serializeJson(doc, postData1);
    Serial.println(postData1);    //debug, can be commented out

    //format http post to be compatible with JEDI one
    String contentType = "application/json";
    http.post("/v1/data/mc", contentType, postData1);
    // read the status code and body of the response
    int statusCode = http.responseStatusCode();
    String response = http.responseBody();
    Serial.print("Status code: ");
    Serial.println(statusCode);
    Serial.print("Response: ");
    Serial.println(response);

    // try disconnecting from server after posting data
    http.stop();
    Serial.println("disconnect from server");

  }
  //check if AC current has turned off and current Istate = 1 
  if ((ACCurrentValue < 0.05) && (Istate == 1)) {
    digitalWrite(LED_BUILTIN, LOW);
    finished = millis();
    elapsed = finished - start;
    Istate = 0;
    Serial.print("On time = ");
    Serial.println(elapsed);

    //Following code creates the serialized JSON string to send to JEDI One
    //using ArduinoJson library
    //StaticJsonDocument <200> doc;  //move to start of loop
    JsonObject context = doc.createNestedObject("context");
    context["target_id"] = String(jediID);
    JsonObject data = doc.createNestedObject("data");
    data["Isensor"] = Istate;
    data["MilliStamp"] = finished;
    serializeJson(doc, postData1);
    Serial.println(postData1);    //debug, can be commented out

    //format http post to be compatible with JEDI one
    String contentType = "application/json";
    http.post("/v1/data/mc", contentType, postData1);
    // read the status code and body of the response
    int statusCode = http.responseStatusCode();
    String response = http.responseBody();
    Serial.print("Status code: ");
    Serial.println(statusCode);
    Serial.print("Response: ");
    Serial.println(response);

    // try disconnecting from server after posting data
    http.stop();
    Serial.println("disconnect from server");    
  }
  
  
  delay(1000);
}

Latest source code for the MKR1010wifiACcurrentSEN0287 sump pump monitor application is on github at below link:

Set up the JEDI One

1 - If machinechat JEDI One is not already installed on the Raspberry Pi see below:

2 - Set up a JEDI One Rule to count the hourly rate the sump pump turns on

In the JEDI One, select “Rule” tab, then select “+” to add a new rule and configure Condition as shown below. Select Data Source “/MKR1010WIFISensor_Sump/Isensor” (note: this is “drag and drop” from list of sources) and Operator “==” and Value “1”.

Configure Action as shown below. Add Action Name, Set Action Type to “Count Events”, name Target ID and Metric Name, and set Counter Reset to “EVERY 1 HOURS”.

3 - Set up the JEDI One dasboard

In the JEDI One, select “Dashboards” tab, then select “+” to add a new chart and configure.

Name the chart, select “Chart Type”, select “Source” (MKR1010WiFiSensor_Sump), select "Property (Isensor), enter “Units” and enter “Refresh Interval”. For the second chart, name the chart, select “Source” (SumpPumpOn), select "Property (SumpOnCount), enter “Units” and enter “Refresh Interval”. When complete the dashboard should look similar to below.

Conclusion

DFRobot’s SEN0287 AC current sensor and the Arduino MKRWIFI1010 hardware platforms makes it quick and easy to remotely monitor the on/off state of a sump pump. Using WiFi, the sensor data is easily be sent to machinechat’s JEDI One IoT data management software running on a Raspberry Pi. and sump pump data tracked and displayed. Additional alerts can easily be set up on the JEDI One to email or send an SMS if the sump pump has not turned on after a set amount of time.

References

1 Like