Things used in this project

Hardware components:
Photon new
Particle Photon
×1
12002 04
Breadboard (generic)
×1
11026 02
Jumper wires (generic)
×2
Openbuilds self tapping screw
OpenBuilds Self-Tapping Screw
×2
Software apps and online services:
Pushbullet
Hand tools and fabrication machines:
Screwdriver
Plastic Water Bowl

Schematics

Wiring Schematic
Black wire is ground and goes to bottom of the water container. The red wire is positive and goes to the water level at which you would like to be notified.
Schematic uzdzun0kff

Code

Building CodeC/C++
This is the code you will put into Particle builder
// This #include statement was automatically added by the Particle IDE.
#include "elapsedMillis/elapsedMillis.h"

// This #include statement was automatically added by the Particle IDE.
#include "elapsedMillis/elapsedMillis.h"

String _version = "0.04";

//this reads the flood sensor every 2 seconds
#define FLOOD_READ_INTERVAL 2000

//this defines the frequency of the notifications sent to the user
#define FLOOD_FIRST_ALARM 10000 //10 seconds
#define FLOOD_SECOND_ALARM 60000 //1 minute
#define FLOOD_THIRD_ALARM 300000 //5 minutes
#define FLOOD_FOURTH_ALARM 900000 //15 minutes
#define FLOOD_FIFTH_ALARM 3600000 //1 hour
#define FLOOD_SIXTH_ALARM 14400000 //4 hours - and every 4 hours ever after, until the situation is rectified (ie no more water is detected)

#define FLOOD_NOTIF "FLOOD"

elapsedMillis flood_timer;
elapsedMillis flood_alarm_timer;

int flood_alarms_array[6]={FLOOD_FIRST_ALARM, FLOOD_SECOND_ALARM, FLOOD_THIRD_ALARM, FLOOD_FOURTH_ALARM, FLOOD_FIFTH_ALARM, FLOOD_SIXTH_ALARM};
int flood_alarm_index = 0;
bool flood_detected = false;
unsigned long flood_next_alarm = 0;

int FLOOD_SENSOR = D0;
int LED = D7;

void setup() {
 pinMode(FLOOD_SENSOR, INPUT_PULLUP);
 pinMode(LED, OUTPUT);
 Spark.publish("device starting", "Firmware version: " + _version, 60, PRIVATE);
}

void loop() {

    flood_check();
    
    if ( flood_detected ) {
        flood_notify_user();
    }
}

/*******************************************************************************
 * Function Name  : flood_check
 * Description    : check water leak sensor at FLOOD_READ_INTERVAL, turns on led on D7 and raises alarm if water is detected
 * Return         : 0
 *******************************************************************************/
int flood_check()
{
    if (flood_timer < FLOOD_READ_INTERVAL) {
        return 0;
    }
    
    //time is up, so reset timer
    flood_timer = 0;

    if (digitalRead(FLOOD_SENSOR)) {
        
        //if flood is already detected, no need to do anything, since an alarm will be fired
        if (flood_detected){
            return 0;
        }
        
        flood_detected = true;
    
        //reset alarm timer
        flood_alarm_timer = 0;

        //set next alarm
        flood_alarm_index = 0;
        flood_next_alarm = flood_alarms_array[0];
        
        digitalWrite(LED,HIGH);
    } else {
        
        digitalWrite(LED,LOW);
        flood_detected = false;
    }
    return 0;
}

/*******************************************************************************
 * Function Name  : flood_notify_user
 * Description    : will fire notifications to user at scheduled intervals
 * Return         : 0
 *******************************************************************************/
int flood_notify_user()
{

    if (flood_alarm_timer < flood_next_alarm) {
        return 0;
    }

    
    //time is up, so reset timer
    flood_alarm_timer = 0;
    
    //set next alarm or just keep current one if there are no more alarms to set
    if (flood_alarm_index < arraySize(flood_alarms_array)-1) {
        flood_alarm_index = flood_alarm_index + 1;
        flood_next_alarm = flood_alarms_array[flood_alarm_index];
    }

    //send an alarm to user (this one goes to the dashboard)
    Spark.publish(FLOOD_NOTIF, "Livestock Need Water!", 60, PRIVATE);

    //send an alarm to user (this one goes to pushbullet servers)
    Spark.publish("pushbullet", "Livestock Need Water!", 60, PRIVATE);
   
   return 0; 
}
This is the JSON.file codeC/C++
This is put into the integration within particle dashboard.
{
  "eventName": "pushbullet",
  "url": "https://api.pushbullet.com/v2/pushes",
  "requestType": "POST",
  "headers": {
    "Authorization": "Bearer access key",
    "Content-Type": "application/json"
  },
  "json": {
      "type": "note",
      "title": "{{SPARK_EVENT_VALUE}}",
      "body": ""
  },
  "mydevices": true
}
Graphing and linkingC/C++
This code just shows our professor how we linked our photons together and sent data to them along with sending data collected to IFTTT to be graphed. This is not needed if you want a system to check the water status.
// This #include statement was automatically added by the Particle IDE.
#include <elapsedMillis.h>

// This #include statement was automatically added by the Particle IDE.
#include "elapsedMillis/elapsedMillis.h"

// This #include statement was automatically added by the Particle IDE.
#include "elapsedMillis/elapsedMillis.h"

String _version = "0.04";

//this reads the flood sensor every 2 seconds
#define FLOOD_READ_INTERVAL 2000

//this defines the frequency of the notifications sent to the user
#define FLOOD_FIRST_ALARM 10000 //10 seconds
#define FLOOD_SECOND_ALARM 60000 //1 minute
#define FLOOD_THIRD_ALARM 300000 //5 minutes
#define FLOOD_FOURTH_ALARM 900000 //15 minutes
#define FLOOD_FIFTH_ALARM 3600000 //1 hour
#define FLOOD_SIXTH_ALARM 14400000 //4 hours - and every 4 hours ever after, until the situation is rectified (ie no more water is detected)

#define FLOOD_NOTIF "FLOOD"

elapsedMillis flood_timer;
elapsedMillis flood_alarm_timer;

int flood_alarms_array[6]={FLOOD_FIRST_ALARM, FLOOD_SECOND_ALARM, FLOOD_THIRD_ALARM, FLOOD_FOURTH_ALARM, FLOOD_FIFTH_ALARM, FLOOD_SIXTH_ALARM};
int flood_alarm_index = 0;
bool flood_detected = false;
unsigned long flood_next_alarm = 0;
bool auxEvent = Particle.function("blinkLED",blinkLed);

int FLOOD_SENSOR = D0;
int LED = D7;

void setup() {
 pinMode(FLOOD_SENSOR, INPUT_PULLUP);
 pinMode(LED, OUTPUT);
 Spark.publish("device starting", "Firmware version: " + _version, 60, PRIVATE);
}

void loop() {

    flood_check();
    
    if ( flood_detected ) {
        flood_notify_user();
    }
    
}

/*******************************************************************************
 * Function Name  : flood_check
 * Description    : check water leak sensor at FLOOD_READ_INTERVAL, turns on led on D7 and raises alarm if water is detected
 * Return         : 0
 *******************************************************************************/
int flood_check()
{
    if (flood_timer < FLOOD_READ_INTERVAL) {
        return 0;
    }
    
    //time is up, so reset timer
    flood_timer = 0;

    if (digitalRead(FLOOD_SENSOR)) {
        
        //if flood is already detected, no need to do anything, since an alarm will be fired
        if (flood_detected){
            //IFTT
            Particle.publish("Water_check", "1");
            return 0;
        }
        
        flood_detected = true;
    
        //reset alarm timer
        flood_alarm_timer = 0;

        //set next alarm
        flood_alarm_index = 0;
        flood_next_alarm = flood_alarms_array[0];
        
        digitalWrite(LED,HIGH);
    } else {
        
        digitalWrite(LED,LOW);
        flood_detected = false;
    }
    return 0;
}

/*******************************************************************************
 * Function Name  : flood_notify_user
 * Description    : will fire notifications to user at scheduled intervals
 * Return         : 0
 *******************************************************************************/
int flood_notify_user()
{

    if (flood_alarm_timer < flood_next_alarm) {
        return 0;
    }

    
    //time is up, so reset timer
    flood_alarm_timer = 0;
    
    //set next alarm or just keep current one if there are no more alarms to set
    if (flood_alarm_index < arraySize(flood_alarms_array)-1) {
        flood_alarm_index = flood_alarm_index + 1;
        flood_next_alarm = flood_alarms_array[flood_alarm_index];
    }

    //send an alarm to user (this one goes to the dashboard)
    Spark.publish(FLOOD_NOTIF, "Livestock Need Water!", 60, PRIVATE);

    //send an alarm to user (this one goes to pushbullet servers)
    Spark.publish("pushbullet", "Livestock Need Water!", 60, PRIVATE);
    
    //IFTT
    Particle.publish("Water_check", "0");
   
   return 0; 
}

/****************************************************************************
 * Function Name    : blinkL(String)
 * Description      : will blink D7 LED 20 times
 * Return           : 0
 ****************************************************************************/
int blinkLed(String s)
{
    for(int k=0; k<20; k++)     //k<(number of blinks+1)
    {
        digitalWrite(LED,HIGH);
        delay(250);
        digitalWrite(LED,LOW);
        delay(250);
    }
    
    return 0;
}

Credits

Unnamed dhq3bivswq
Treece Hogan

Engineering student at UNC Charlotte

Contact
Img 7757 briowg4rnr
Kolton Hawks

Mechanical Engineering Student at UNC-Charlotte

Contact
Thanks to William Wiseman.

Replications

Did you replicate this project? Share it!

I made one

Love this project? Think it could be improved? Tell us what you think!

Give feedback

Comments

Similar projects you might like

Whats My I2C Address?
Easy
  • 32
  • 1

Protip

The story of how a Brix will be a clock by using an LCD 1602 or LCD 2004 over I2C.

MyHumidity Controlled by BME280 and Photon
Easy
  • 104
  • 2

Full instructions

Checks if humidity threshold is reached and informs the user by using Blynk/IFTTT-services with softAP integration.

Tweeting Particle Photon
Easy
  • 16
  • 1

Full instructions

Tweet your friends with only the press of a button!

MyLight-Clock with NeoPixel Ring 12 Controlled by Photon
Easy
  • 244
  • 2

Full instructions

Read the time at night? Without glasses? Impossible? Focus on 2 light points, which will tell you the hour and the minute.

Map Your Particles!
Easy
  • 1,323
  • 20

Protip

Locate your Particle Photons, P1s and Electrons on a map without needing extra hardware. Use Ubidots or an offline map alternative

BME280 measures and displays on OLED controlled by Photon
Easy
  • 320
  • 2

Protip

I share my first steps with the sensor BME280 (temp / humi / pressure / altitude) and an OLED 128 * 64 px

Add projectSign up / Login