Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. My Project
  3. Water leak sensor

Water leak sensor

Scheduled Pinned Locked Moved My Project
6 Posts 4 Posters 2.7k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    flopp
    wrote on last edited by flopp
    #1

    Finally I made my water leak sensor that I have been dreaming about for a long time now :)
    I used those items:
    Enclosure
    2 x AA batteris incl holder
    nRF24L01+
    Home made PCB with ATmega328P-PU
    red, green LED
    si7021, temp & hum
    some capactitors and resistors
    Kitchen aluminum foil
    Copper wire

    I am measuring temperature and humidity with a Si7021, measuring battery voltage with voltage divider and internal reference, just to test which one that shows most correct.

    /**
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0 - Henrik EKblad
     * 
     */
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    
    // Enable debug prints to serial monitor
    #define MY_DEBUG
    
    #define MY_NODE_ID 27
    
    #include <SPI.h>
    #include <MySensors.h>
    #include <Wire.h>
    #include <SI7021.h>
    
    #define CHILD_SIHUM 0
    #define CHILD_SITEMP 1
    #define CHILD_BATT 2
    #define CHILD_SIDEW 3
    #define CHILD_BATTRES 4
    
    #define CHILD_WATER 10
    
    #define CHILD_FAILS 250
    #define CHILD_PARENT 251
    #define CHILD_DISTANCE 252
    #define CHILD_SLEEPTIME 253
    
    //LED
    int GREEN = 7;
    int RED = 8;
    
    //Water alarm
    int Interrupt = 1; // pin 3 on UNO/Nano
    
    //SleepTime
    float SleepTime = 30; // Sleep time between reads (in minutes)
    int OldSleepTime = -1;
    int SleepTimeLoopCount = 10;
    
    //ReadVCC
    long result;
    float BatteryVolt;
    float OldBatteryVolt;
    int BatteryVoltLoopCount = 5;
    
    //ReadVCCRes
    int sensorValue;
    float BatteryResVolt;
    int BATTERY_SENSE_PIN = A2;  // select the input pin for the battery sense point
    
    //SI7021
    SI7021 SI;
    int SILoopCount = 5;
    int SIHum;
    int OldSIHum = -1;
    float SITemp;
    float OldSITemp = -1;
    float SIDew;
    float OldSIDew = -1;
    
    //NRF
    int Fails = 0;
    int OldFails = -1;
    int FailsLoopCount = 10;
    int OldParentNode = -1;
    int ParentNodeLoopCount = 10;
    int OldDistanceNode = -1;
    int DistanceLoopCount = 10;
    
    MyMessage msgSIHum(CHILD_SIHUM, V_HUM);
    MyMessage msgSITemp(CHILD_SITEMP, V_TEMP);
    MyMessage msgSIDew(CHILD_SIDEW, V_TEMP);
    MyMessage msgBatt(CHILD_BATT, V_VOLTAGE);
    MyMessage msgBattRes(CHILD_BATTRES, V_VOLTAGE);
    
    MyMessage msgWater(CHILD_WATER, V_TRIPPED);
    
    MyMessage msgFails(CHILD_FAILS, V_VA);
    MyMessage msgParent(CHILD_PARENT, V_VA);
    MyMessage msgDistance(CHILD_DISTANCE, V_VA);
    MyMessage msgSleepTime(CHILD_SLEEPTIME, V_VA);
    
    void setup() {
    
      //Water Alarm
      pinMode(3, INPUT_PULLUP);
      attachInterrupt(Interrupt, Water, FALLING);
    
      //Battery measurement
      analogReference(INTERNAL); // use the 1.1 V internal reference
      sensorValue = analogRead(BATTERY_SENSE_PIN); // read once to activate the change of reference
    
      pinMode(GREEN, OUTPUT);
      pinMode(RED, OUTPUT);
      digitalWrite(GREEN, HIGH);
      digitalWrite(RED, HIGH);
      delay(200);
      digitalWrite(GREEN, LOW);
      digitalWrite(RED, LOW);
    
      SI.begin();
    }
    void presentation() {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Temp/Humidity/WaterLeak", "20180226");
      // Register all sensors to gateway (they will be created as child devices)
      present(CHILD_SIHUM, S_HUM, "SIHum");
      present(CHILD_SITEMP, S_TEMP, "SITemp");
      present(CHILD_SIDEW, S_TEMP, "SIDew");
      present(CHILD_BATT, S_MULTIMETER, "Volt");
      present(CHILD_BATTRES, S_MULTIMETER, "VoltRes");
    
      present(CHILD_WATER, S_WATER_LEAK, "Water Alarm");
      
      present(CHILD_FAILS, S_POWER, "Fails");
      present(CHILD_PARENT, S_POWER, "Parent");
      present(CHILD_DISTANCE, S_POWER, "Distance");  
      present(CHILD_SLEEPTIME, S_DIMMER, "SleepTime");
    }
    void loop() {
      //Voltage
      readVcc();
      sensorValue = analogRead(BATTERY_SENSE_PIN);
      BatteryResVolt  = sensorValue * 0.003363075;
      
      //SI read both temperature and humidity
      si7021_env SIdata = SI.getHumidityAndTemperature();
      
      //SI Humidity  
      SIHum = SIdata.humidityPercent;
      //Serial.print("SIHum=");
      //Serial.println(SIHum);
      if(SIHum >99)
      {
        SIHum = 99;
      }
      if(SIHum < 1)
      {
        SIHum = 0;
      }
      
      //SI Temperature
      SITemp = SIdata.celsiusHundredths / 100.0;
      SITemp = round(SITemp*10)/10.0;
      //Serial.print("SITemp=");
      //Serial.println(SITemp,1);
    
      //SI Dew
      double a = 17.271;
      double b = 237.7;
      double dewtemp = (a * SITemp) / (b + SITemp) + log(SIHum*0.01);
      SIDew = (b * dewtemp) / (a - dewtemp);
    
      //Get SleepTime from controller
      request(CHILD_SLEEPTIME, V_PERCENTAGE);
      wait(1000);
    
      //Water Alarm
      int WaterLeak = digitalRead(3);
      if (WaterLeak == 0){
        resend((msgWater.set(1)), 100);
      } 
      else{
        resend((msgWater.set(0)), 100);
      }
    
      //Send data to controller
      if ((OldBatteryVolt != BatteryVolt) | (BatteryVoltLoopCount >= 5))
      {
        send(msgBatt.set(BatteryVolt, 3));
        send(msgBattRes.set(BatteryResVolt, 3));
        OldBatteryVolt = BatteryVolt;
        BatteryVoltLoopCount = 0;
      }
        
      if ((OldSIHum != SIHum) | (OldSITemp != SITemp) | (OldSIDew != SIDew) | (SILoopCount >= 5))
      {
        resend((msgSIHum.set(SIHum)), 1);
        resend((msgSITemp.set(SITemp, 1)), 1);
        resend((msgSIDew.set(SIDew, 1)), 1);
        OldSIHum = SIHum;
        OldSITemp = SITemp;
        OldSIDew = SIDew;
        SILoopCount = 0;
      }
      
      if ((OldParentNode != _transportConfig.parentNodeId) | (ParentNodeLoopCount >= 10))
      {
        resend((msgParent.set(_transportConfig.parentNodeId)),1);
        OldParentNode = _transportConfig.parentNodeId;
        ParentNodeLoopCount = 0;
      }
        
      if ((OldDistanceNode != _transportConfig.distanceGW) | (DistanceLoopCount >= 10))
      {
        resend((msgDistance.set(_transportConfig.distanceGW)),1);
        OldDistanceNode = _transportConfig.distanceGW;
        DistanceLoopCount = 0;
      }
    
      if ((OldSleepTime != SleepTime) | (SleepTimeLoopCount >= 10))
      {
        resend((msgSleepTime.set(SleepTime,0)),10);
        OldSleepTime = SleepTime;
        SleepTimeLoopCount = 0;
      }
    
      if ((OldFails != Fails) | (FailsLoopCount >= 10))
      {
        failsend((msgFails.set(Fails)),1);
        OldFails = Fails;
        FailsLoopCount = 0;
      }
         
      BatteryVoltLoopCount++;
      SILoopCount++;
      ParentNodeLoopCount++;
      DistanceLoopCount++;
      SleepTimeLoopCount++;
      FailsLoopCount++;
    
      digitalWrite(GREEN, HIGH);
      delay(200);
      digitalWrite(GREEN, LOW);
      
      sleep(SleepTime*60000); //sleep a bit
    }
    void readVcc() {
      //Serial.println("readVcc");
      // Read 1.1V reference against AVcc
      ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
      delay(2); // Wait for Vref to settle
      ADCSRA |= _BV(ADSC); // Convert
      while (bit_is_set(ADCSRA, ADSC));
      result = ADCL;
      result |= ADCH << 8;
      result = 1126400L / result; // Back-calculate AVcc in mV
      //batteryPcnt = (result - 1900) * 0.090909;
      BatteryVolt = result / 1000.000;
      //sendBatteryLevel(batteryPcnt);
      //Serial.print("battery volt:");
      //Serial.println(batteryVolt, 3);
      //Serial.print("battery percent:");
      //Serial.println(batteryPcnt);
    }
    void resend(MyMessage & msg, int repeats) {
      int repeat = 0;
      int repeatdelay = 0;
      boolean sendOK = false;
      while ((sendOK == false) and(repeat < repeats))
      {
        if (send(msg))
        {
          sendOK = true;
        }
        else
        {
          
          digitalWrite(RED, HIGH);
          delay(200);
          digitalWrite(RED, LOW);
          Fails++;
          sendOK = false;
          Serial.print("Error ");
          Serial.println(repeat);
          repeatdelay += 250;
          repeat++;
          sleep(repeatdelay);
        }
      }
    }
    
    void failsend(MyMessage &msg, int repeats) {
      int repeat = 0;
      int repeatdelay = 0;
      boolean sendOK = false;
    
      while ((sendOK == false) and (repeat < repeats)) {
        if (send(msg))
        {
          Fails = 0;
          sendOK = true;
        }
        else
        {
          Fails++;
          sendOK = false;
          Serial.print("Error ");
          Serial.println(repeat);
          repeatdelay += 250;
          repeat++;
          sleep(repeatdelay);
        }
      }
    }
    
    void receive(const MyMessage &message) {
      if (message.sender == 0) {
        if(message.type == V_PERCENTAGE) {
          //Serial.println( "V_PERCENTAGE command received..." );
          SleepTime = atoi(message.data);
          if ((SleepTime <= 0) | (SleepTime >= 700))
          {
            SleepTime = 30;
          }
          else
          {
            SleepTime = SleepTime / 6.6;
            //Serial.println(SleepTime);
            if (SleepTime < 1)
            {
              SleepTime = 1;  
            }
          }
          //Serial.println(SleepTime);
        }
      } 
    }
    
    void Water() {
      Serial.println("Water");
      resend((msgWater.set(1)), 1000);
      digitalWrite(GREEN, HIGH);
      delay(200);
      digitalWrite(GREEN, LOW);
    }
    

    0_1519677466024_20180226_193839617_iOS.jpg
    0_1519677539241_20180226_193922845_iOS.jpg

    dbemowskD H 2 Replies Last reply
    2
    • F flopp

      Finally I made my water leak sensor that I have been dreaming about for a long time now :)
      I used those items:
      Enclosure
      2 x AA batteris incl holder
      nRF24L01+
      Home made PCB with ATmega328P-PU
      red, green LED
      si7021, temp & hum
      some capactitors and resistors
      Kitchen aluminum foil
      Copper wire

      I am measuring temperature and humidity with a Si7021, measuring battery voltage with voltage divider and internal reference, just to test which one that shows most correct.

      /**
       * The MySensors Arduino library handles the wireless radio link and protocol
       * between your home built sensors/actuators and HA controller of choice.
       * The sensors forms a self healing radio network with optional repeaters. Each
       * repeater and gateway builds a routing tables in EEPROM which keeps track of the
       * network topology allowing messages to be routed to nodes.
       *
       * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
       * Copyright (C) 2013-2015 Sensnology AB
       * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
       *
       * Documentation: http://www.mysensors.org
       * Support Forum: http://forum.mysensors.org
       *
       * This program is free software; you can redistribute it and/or
       * modify it under the terms of the GNU General Public License
       * version 2 as published by the Free Software Foundation.
       *
       *******************************
       *
       * REVISION HISTORY
       * Version 1.0 - Henrik EKblad
       * 
       */
      // Enable and select radio type attached
      #define MY_RADIO_NRF24
      
      // Enable debug prints to serial monitor
      #define MY_DEBUG
      
      #define MY_NODE_ID 27
      
      #include <SPI.h>
      #include <MySensors.h>
      #include <Wire.h>
      #include <SI7021.h>
      
      #define CHILD_SIHUM 0
      #define CHILD_SITEMP 1
      #define CHILD_BATT 2
      #define CHILD_SIDEW 3
      #define CHILD_BATTRES 4
      
      #define CHILD_WATER 10
      
      #define CHILD_FAILS 250
      #define CHILD_PARENT 251
      #define CHILD_DISTANCE 252
      #define CHILD_SLEEPTIME 253
      
      //LED
      int GREEN = 7;
      int RED = 8;
      
      //Water alarm
      int Interrupt = 1; // pin 3 on UNO/Nano
      
      //SleepTime
      float SleepTime = 30; // Sleep time between reads (in minutes)
      int OldSleepTime = -1;
      int SleepTimeLoopCount = 10;
      
      //ReadVCC
      long result;
      float BatteryVolt;
      float OldBatteryVolt;
      int BatteryVoltLoopCount = 5;
      
      //ReadVCCRes
      int sensorValue;
      float BatteryResVolt;
      int BATTERY_SENSE_PIN = A2;  // select the input pin for the battery sense point
      
      //SI7021
      SI7021 SI;
      int SILoopCount = 5;
      int SIHum;
      int OldSIHum = -1;
      float SITemp;
      float OldSITemp = -1;
      float SIDew;
      float OldSIDew = -1;
      
      //NRF
      int Fails = 0;
      int OldFails = -1;
      int FailsLoopCount = 10;
      int OldParentNode = -1;
      int ParentNodeLoopCount = 10;
      int OldDistanceNode = -1;
      int DistanceLoopCount = 10;
      
      MyMessage msgSIHum(CHILD_SIHUM, V_HUM);
      MyMessage msgSITemp(CHILD_SITEMP, V_TEMP);
      MyMessage msgSIDew(CHILD_SIDEW, V_TEMP);
      MyMessage msgBatt(CHILD_BATT, V_VOLTAGE);
      MyMessage msgBattRes(CHILD_BATTRES, V_VOLTAGE);
      
      MyMessage msgWater(CHILD_WATER, V_TRIPPED);
      
      MyMessage msgFails(CHILD_FAILS, V_VA);
      MyMessage msgParent(CHILD_PARENT, V_VA);
      MyMessage msgDistance(CHILD_DISTANCE, V_VA);
      MyMessage msgSleepTime(CHILD_SLEEPTIME, V_VA);
      
      void setup() {
      
        //Water Alarm
        pinMode(3, INPUT_PULLUP);
        attachInterrupt(Interrupt, Water, FALLING);
      
        //Battery measurement
        analogReference(INTERNAL); // use the 1.1 V internal reference
        sensorValue = analogRead(BATTERY_SENSE_PIN); // read once to activate the change of reference
      
        pinMode(GREEN, OUTPUT);
        pinMode(RED, OUTPUT);
        digitalWrite(GREEN, HIGH);
        digitalWrite(RED, HIGH);
        delay(200);
        digitalWrite(GREEN, LOW);
        digitalWrite(RED, LOW);
      
        SI.begin();
      }
      void presentation() {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Temp/Humidity/WaterLeak", "20180226");
        // Register all sensors to gateway (they will be created as child devices)
        present(CHILD_SIHUM, S_HUM, "SIHum");
        present(CHILD_SITEMP, S_TEMP, "SITemp");
        present(CHILD_SIDEW, S_TEMP, "SIDew");
        present(CHILD_BATT, S_MULTIMETER, "Volt");
        present(CHILD_BATTRES, S_MULTIMETER, "VoltRes");
      
        present(CHILD_WATER, S_WATER_LEAK, "Water Alarm");
        
        present(CHILD_FAILS, S_POWER, "Fails");
        present(CHILD_PARENT, S_POWER, "Parent");
        present(CHILD_DISTANCE, S_POWER, "Distance");  
        present(CHILD_SLEEPTIME, S_DIMMER, "SleepTime");
      }
      void loop() {
        //Voltage
        readVcc();
        sensorValue = analogRead(BATTERY_SENSE_PIN);
        BatteryResVolt  = sensorValue * 0.003363075;
        
        //SI read both temperature and humidity
        si7021_env SIdata = SI.getHumidityAndTemperature();
        
        //SI Humidity  
        SIHum = SIdata.humidityPercent;
        //Serial.print("SIHum=");
        //Serial.println(SIHum);
        if(SIHum >99)
        {
          SIHum = 99;
        }
        if(SIHum < 1)
        {
          SIHum = 0;
        }
        
        //SI Temperature
        SITemp = SIdata.celsiusHundredths / 100.0;
        SITemp = round(SITemp*10)/10.0;
        //Serial.print("SITemp=");
        //Serial.println(SITemp,1);
      
        //SI Dew
        double a = 17.271;
        double b = 237.7;
        double dewtemp = (a * SITemp) / (b + SITemp) + log(SIHum*0.01);
        SIDew = (b * dewtemp) / (a - dewtemp);
      
        //Get SleepTime from controller
        request(CHILD_SLEEPTIME, V_PERCENTAGE);
        wait(1000);
      
        //Water Alarm
        int WaterLeak = digitalRead(3);
        if (WaterLeak == 0){
          resend((msgWater.set(1)), 100);
        } 
        else{
          resend((msgWater.set(0)), 100);
        }
      
        //Send data to controller
        if ((OldBatteryVolt != BatteryVolt) | (BatteryVoltLoopCount >= 5))
        {
          send(msgBatt.set(BatteryVolt, 3));
          send(msgBattRes.set(BatteryResVolt, 3));
          OldBatteryVolt = BatteryVolt;
          BatteryVoltLoopCount = 0;
        }
          
        if ((OldSIHum != SIHum) | (OldSITemp != SITemp) | (OldSIDew != SIDew) | (SILoopCount >= 5))
        {
          resend((msgSIHum.set(SIHum)), 1);
          resend((msgSITemp.set(SITemp, 1)), 1);
          resend((msgSIDew.set(SIDew, 1)), 1);
          OldSIHum = SIHum;
          OldSITemp = SITemp;
          OldSIDew = SIDew;
          SILoopCount = 0;
        }
        
        if ((OldParentNode != _transportConfig.parentNodeId) | (ParentNodeLoopCount >= 10))
        {
          resend((msgParent.set(_transportConfig.parentNodeId)),1);
          OldParentNode = _transportConfig.parentNodeId;
          ParentNodeLoopCount = 0;
        }
          
        if ((OldDistanceNode != _transportConfig.distanceGW) | (DistanceLoopCount >= 10))
        {
          resend((msgDistance.set(_transportConfig.distanceGW)),1);
          OldDistanceNode = _transportConfig.distanceGW;
          DistanceLoopCount = 0;
        }
      
        if ((OldSleepTime != SleepTime) | (SleepTimeLoopCount >= 10))
        {
          resend((msgSleepTime.set(SleepTime,0)),10);
          OldSleepTime = SleepTime;
          SleepTimeLoopCount = 0;
        }
      
        if ((OldFails != Fails) | (FailsLoopCount >= 10))
        {
          failsend((msgFails.set(Fails)),1);
          OldFails = Fails;
          FailsLoopCount = 0;
        }
           
        BatteryVoltLoopCount++;
        SILoopCount++;
        ParentNodeLoopCount++;
        DistanceLoopCount++;
        SleepTimeLoopCount++;
        FailsLoopCount++;
      
        digitalWrite(GREEN, HIGH);
        delay(200);
        digitalWrite(GREEN, LOW);
        
        sleep(SleepTime*60000); //sleep a bit
      }
      void readVcc() {
        //Serial.println("readVcc");
        // Read 1.1V reference against AVcc
        ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
        delay(2); // Wait for Vref to settle
        ADCSRA |= _BV(ADSC); // Convert
        while (bit_is_set(ADCSRA, ADSC));
        result = ADCL;
        result |= ADCH << 8;
        result = 1126400L / result; // Back-calculate AVcc in mV
        //batteryPcnt = (result - 1900) * 0.090909;
        BatteryVolt = result / 1000.000;
        //sendBatteryLevel(batteryPcnt);
        //Serial.print("battery volt:");
        //Serial.println(batteryVolt, 3);
        //Serial.print("battery percent:");
        //Serial.println(batteryPcnt);
      }
      void resend(MyMessage & msg, int repeats) {
        int repeat = 0;
        int repeatdelay = 0;
        boolean sendOK = false;
        while ((sendOK == false) and(repeat < repeats))
        {
          if (send(msg))
          {
            sendOK = true;
          }
          else
          {
            
            digitalWrite(RED, HIGH);
            delay(200);
            digitalWrite(RED, LOW);
            Fails++;
            sendOK = false;
            Serial.print("Error ");
            Serial.println(repeat);
            repeatdelay += 250;
            repeat++;
            sleep(repeatdelay);
          }
        }
      }
      
      void failsend(MyMessage &msg, int repeats) {
        int repeat = 0;
        int repeatdelay = 0;
        boolean sendOK = false;
      
        while ((sendOK == false) and (repeat < repeats)) {
          if (send(msg))
          {
            Fails = 0;
            sendOK = true;
          }
          else
          {
            Fails++;
            sendOK = false;
            Serial.print("Error ");
            Serial.println(repeat);
            repeatdelay += 250;
            repeat++;
            sleep(repeatdelay);
          }
        }
      }
      
      void receive(const MyMessage &message) {
        if (message.sender == 0) {
          if(message.type == V_PERCENTAGE) {
            //Serial.println( "V_PERCENTAGE command received..." );
            SleepTime = atoi(message.data);
            if ((SleepTime <= 0) | (SleepTime >= 700))
            {
              SleepTime = 30;
            }
            else
            {
              SleepTime = SleepTime / 6.6;
              //Serial.println(SleepTime);
              if (SleepTime < 1)
              {
                SleepTime = 1;  
              }
            }
            //Serial.println(SleepTime);
          }
        } 
      }
      
      void Water() {
        Serial.println("Water");
        resend((msgWater.set(1)), 1000);
        digitalWrite(GREEN, HIGH);
        delay(200);
        digitalWrite(GREEN, LOW);
      }
      

      0_1519677466024_20180226_193839617_iOS.jpg
      0_1519677539241_20180226_193922845_iOS.jpg

      dbemowskD Offline
      dbemowskD Offline
      dbemowsk
      wrote on last edited by dbemowsk
      #2

      @flopp said in Water leak:

      Finally I made my water leak that I have been dreaming about for a long time now

      Sorry, I know this wasn't meant the way it was written, but at first quick read, I had to do a double take. I said to myself, who dreams about making their water leak...

      Vera Plus running UI7 with MySensors, Sonoffs and 1-Wire devices
      Visit my website for more Bits, Bytes and Ramblings from me: http://dan.bemowski.info/

      zboblamontZ 1 Reply Last reply
      0
      • dbemowskD dbemowsk

        @flopp said in Water leak:

        Finally I made my water leak that I have been dreaming about for a long time now

        Sorry, I know this wasn't meant the way it was written, but at first quick read, I had to do a double take. I said to myself, who dreams about making their water leak...

        zboblamontZ Offline
        zboblamontZ Offline
        zboblamont
        wrote on last edited by
        #3

        @dbemowsk Plumber looking for work ?

        dbemowskD 1 Reply Last reply
        1
        • zboblamontZ zboblamont

          @dbemowsk Plumber looking for work ?

          dbemowskD Offline
          dbemowskD Offline
          dbemowsk
          wrote on last edited by
          #4

          @zboblamont said in Water leak sensor:

          Plumber looking for work ?

          NO, but I know some that wouldn't mind the work.

          Vera Plus running UI7 with MySensors, Sonoffs and 1-Wire devices
          Visit my website for more Bits, Bytes and Ramblings from me: http://dan.bemowski.info/

          1 Reply Last reply
          1
          • F flopp

            Finally I made my water leak sensor that I have been dreaming about for a long time now :)
            I used those items:
            Enclosure
            2 x AA batteris incl holder
            nRF24L01+
            Home made PCB with ATmega328P-PU
            red, green LED
            si7021, temp & hum
            some capactitors and resistors
            Kitchen aluminum foil
            Copper wire

            I am measuring temperature and humidity with a Si7021, measuring battery voltage with voltage divider and internal reference, just to test which one that shows most correct.

            /**
             * The MySensors Arduino library handles the wireless radio link and protocol
             * between your home built sensors/actuators and HA controller of choice.
             * The sensors forms a self healing radio network with optional repeaters. Each
             * repeater and gateway builds a routing tables in EEPROM which keeps track of the
             * network topology allowing messages to be routed to nodes.
             *
             * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
             * Copyright (C) 2013-2015 Sensnology AB
             * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
             *
             * Documentation: http://www.mysensors.org
             * Support Forum: http://forum.mysensors.org
             *
             * This program is free software; you can redistribute it and/or
             * modify it under the terms of the GNU General Public License
             * version 2 as published by the Free Software Foundation.
             *
             *******************************
             *
             * REVISION HISTORY
             * Version 1.0 - Henrik EKblad
             * 
             */
            // Enable and select radio type attached
            #define MY_RADIO_NRF24
            
            // Enable debug prints to serial monitor
            #define MY_DEBUG
            
            #define MY_NODE_ID 27
            
            #include <SPI.h>
            #include <MySensors.h>
            #include <Wire.h>
            #include <SI7021.h>
            
            #define CHILD_SIHUM 0
            #define CHILD_SITEMP 1
            #define CHILD_BATT 2
            #define CHILD_SIDEW 3
            #define CHILD_BATTRES 4
            
            #define CHILD_WATER 10
            
            #define CHILD_FAILS 250
            #define CHILD_PARENT 251
            #define CHILD_DISTANCE 252
            #define CHILD_SLEEPTIME 253
            
            //LED
            int GREEN = 7;
            int RED = 8;
            
            //Water alarm
            int Interrupt = 1; // pin 3 on UNO/Nano
            
            //SleepTime
            float SleepTime = 30; // Sleep time between reads (in minutes)
            int OldSleepTime = -1;
            int SleepTimeLoopCount = 10;
            
            //ReadVCC
            long result;
            float BatteryVolt;
            float OldBatteryVolt;
            int BatteryVoltLoopCount = 5;
            
            //ReadVCCRes
            int sensorValue;
            float BatteryResVolt;
            int BATTERY_SENSE_PIN = A2;  // select the input pin for the battery sense point
            
            //SI7021
            SI7021 SI;
            int SILoopCount = 5;
            int SIHum;
            int OldSIHum = -1;
            float SITemp;
            float OldSITemp = -1;
            float SIDew;
            float OldSIDew = -1;
            
            //NRF
            int Fails = 0;
            int OldFails = -1;
            int FailsLoopCount = 10;
            int OldParentNode = -1;
            int ParentNodeLoopCount = 10;
            int OldDistanceNode = -1;
            int DistanceLoopCount = 10;
            
            MyMessage msgSIHum(CHILD_SIHUM, V_HUM);
            MyMessage msgSITemp(CHILD_SITEMP, V_TEMP);
            MyMessage msgSIDew(CHILD_SIDEW, V_TEMP);
            MyMessage msgBatt(CHILD_BATT, V_VOLTAGE);
            MyMessage msgBattRes(CHILD_BATTRES, V_VOLTAGE);
            
            MyMessage msgWater(CHILD_WATER, V_TRIPPED);
            
            MyMessage msgFails(CHILD_FAILS, V_VA);
            MyMessage msgParent(CHILD_PARENT, V_VA);
            MyMessage msgDistance(CHILD_DISTANCE, V_VA);
            MyMessage msgSleepTime(CHILD_SLEEPTIME, V_VA);
            
            void setup() {
            
              //Water Alarm
              pinMode(3, INPUT_PULLUP);
              attachInterrupt(Interrupt, Water, FALLING);
            
              //Battery measurement
              analogReference(INTERNAL); // use the 1.1 V internal reference
              sensorValue = analogRead(BATTERY_SENSE_PIN); // read once to activate the change of reference
            
              pinMode(GREEN, OUTPUT);
              pinMode(RED, OUTPUT);
              digitalWrite(GREEN, HIGH);
              digitalWrite(RED, HIGH);
              delay(200);
              digitalWrite(GREEN, LOW);
              digitalWrite(RED, LOW);
            
              SI.begin();
            }
            void presentation() {
              // Send the sketch version information to the gateway and Controller
              sendSketchInfo("Temp/Humidity/WaterLeak", "20180226");
              // Register all sensors to gateway (they will be created as child devices)
              present(CHILD_SIHUM, S_HUM, "SIHum");
              present(CHILD_SITEMP, S_TEMP, "SITemp");
              present(CHILD_SIDEW, S_TEMP, "SIDew");
              present(CHILD_BATT, S_MULTIMETER, "Volt");
              present(CHILD_BATTRES, S_MULTIMETER, "VoltRes");
            
              present(CHILD_WATER, S_WATER_LEAK, "Water Alarm");
              
              present(CHILD_FAILS, S_POWER, "Fails");
              present(CHILD_PARENT, S_POWER, "Parent");
              present(CHILD_DISTANCE, S_POWER, "Distance");  
              present(CHILD_SLEEPTIME, S_DIMMER, "SleepTime");
            }
            void loop() {
              //Voltage
              readVcc();
              sensorValue = analogRead(BATTERY_SENSE_PIN);
              BatteryResVolt  = sensorValue * 0.003363075;
              
              //SI read both temperature and humidity
              si7021_env SIdata = SI.getHumidityAndTemperature();
              
              //SI Humidity  
              SIHum = SIdata.humidityPercent;
              //Serial.print("SIHum=");
              //Serial.println(SIHum);
              if(SIHum >99)
              {
                SIHum = 99;
              }
              if(SIHum < 1)
              {
                SIHum = 0;
              }
              
              //SI Temperature
              SITemp = SIdata.celsiusHundredths / 100.0;
              SITemp = round(SITemp*10)/10.0;
              //Serial.print("SITemp=");
              //Serial.println(SITemp,1);
            
              //SI Dew
              double a = 17.271;
              double b = 237.7;
              double dewtemp = (a * SITemp) / (b + SITemp) + log(SIHum*0.01);
              SIDew = (b * dewtemp) / (a - dewtemp);
            
              //Get SleepTime from controller
              request(CHILD_SLEEPTIME, V_PERCENTAGE);
              wait(1000);
            
              //Water Alarm
              int WaterLeak = digitalRead(3);
              if (WaterLeak == 0){
                resend((msgWater.set(1)), 100);
              } 
              else{
                resend((msgWater.set(0)), 100);
              }
            
              //Send data to controller
              if ((OldBatteryVolt != BatteryVolt) | (BatteryVoltLoopCount >= 5))
              {
                send(msgBatt.set(BatteryVolt, 3));
                send(msgBattRes.set(BatteryResVolt, 3));
                OldBatteryVolt = BatteryVolt;
                BatteryVoltLoopCount = 0;
              }
                
              if ((OldSIHum != SIHum) | (OldSITemp != SITemp) | (OldSIDew != SIDew) | (SILoopCount >= 5))
              {
                resend((msgSIHum.set(SIHum)), 1);
                resend((msgSITemp.set(SITemp, 1)), 1);
                resend((msgSIDew.set(SIDew, 1)), 1);
                OldSIHum = SIHum;
                OldSITemp = SITemp;
                OldSIDew = SIDew;
                SILoopCount = 0;
              }
              
              if ((OldParentNode != _transportConfig.parentNodeId) | (ParentNodeLoopCount >= 10))
              {
                resend((msgParent.set(_transportConfig.parentNodeId)),1);
                OldParentNode = _transportConfig.parentNodeId;
                ParentNodeLoopCount = 0;
              }
                
              if ((OldDistanceNode != _transportConfig.distanceGW) | (DistanceLoopCount >= 10))
              {
                resend((msgDistance.set(_transportConfig.distanceGW)),1);
                OldDistanceNode = _transportConfig.distanceGW;
                DistanceLoopCount = 0;
              }
            
              if ((OldSleepTime != SleepTime) | (SleepTimeLoopCount >= 10))
              {
                resend((msgSleepTime.set(SleepTime,0)),10);
                OldSleepTime = SleepTime;
                SleepTimeLoopCount = 0;
              }
            
              if ((OldFails != Fails) | (FailsLoopCount >= 10))
              {
                failsend((msgFails.set(Fails)),1);
                OldFails = Fails;
                FailsLoopCount = 0;
              }
                 
              BatteryVoltLoopCount++;
              SILoopCount++;
              ParentNodeLoopCount++;
              DistanceLoopCount++;
              SleepTimeLoopCount++;
              FailsLoopCount++;
            
              digitalWrite(GREEN, HIGH);
              delay(200);
              digitalWrite(GREEN, LOW);
              
              sleep(SleepTime*60000); //sleep a bit
            }
            void readVcc() {
              //Serial.println("readVcc");
              // Read 1.1V reference against AVcc
              ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
              delay(2); // Wait for Vref to settle
              ADCSRA |= _BV(ADSC); // Convert
              while (bit_is_set(ADCSRA, ADSC));
              result = ADCL;
              result |= ADCH << 8;
              result = 1126400L / result; // Back-calculate AVcc in mV
              //batteryPcnt = (result - 1900) * 0.090909;
              BatteryVolt = result / 1000.000;
              //sendBatteryLevel(batteryPcnt);
              //Serial.print("battery volt:");
              //Serial.println(batteryVolt, 3);
              //Serial.print("battery percent:");
              //Serial.println(batteryPcnt);
            }
            void resend(MyMessage & msg, int repeats) {
              int repeat = 0;
              int repeatdelay = 0;
              boolean sendOK = false;
              while ((sendOK == false) and(repeat < repeats))
              {
                if (send(msg))
                {
                  sendOK = true;
                }
                else
                {
                  
                  digitalWrite(RED, HIGH);
                  delay(200);
                  digitalWrite(RED, LOW);
                  Fails++;
                  sendOK = false;
                  Serial.print("Error ");
                  Serial.println(repeat);
                  repeatdelay += 250;
                  repeat++;
                  sleep(repeatdelay);
                }
              }
            }
            
            void failsend(MyMessage &msg, int repeats) {
              int repeat = 0;
              int repeatdelay = 0;
              boolean sendOK = false;
            
              while ((sendOK == false) and (repeat < repeats)) {
                if (send(msg))
                {
                  Fails = 0;
                  sendOK = true;
                }
                else
                {
                  Fails++;
                  sendOK = false;
                  Serial.print("Error ");
                  Serial.println(repeat);
                  repeatdelay += 250;
                  repeat++;
                  sleep(repeatdelay);
                }
              }
            }
            
            void receive(const MyMessage &message) {
              if (message.sender == 0) {
                if(message.type == V_PERCENTAGE) {
                  //Serial.println( "V_PERCENTAGE command received..." );
                  SleepTime = atoi(message.data);
                  if ((SleepTime <= 0) | (SleepTime >= 700))
                  {
                    SleepTime = 30;
                  }
                  else
                  {
                    SleepTime = SleepTime / 6.6;
                    //Serial.println(SleepTime);
                    if (SleepTime < 1)
                    {
                      SleepTime = 1;  
                    }
                  }
                  //Serial.println(SleepTime);
                }
              } 
            }
            
            void Water() {
              Serial.println("Water");
              resend((msgWater.set(1)), 1000);
              digitalWrite(GREEN, HIGH);
              delay(200);
              digitalWrite(GREEN, LOW);
            }
            

            0_1519677466024_20180226_193839617_iOS.jpg
            0_1519677539241_20180226_193922845_iOS.jpg

            H Offline
            H Offline
            helvetian
            wrote on last edited by
            #5

            @flopp great setup! May I ask what controller you are using and how this works with getting the sleep time from the controller?

            F 1 Reply Last reply
            0
            • H helvetian

              @flopp great setup! May I ask what controller you are using and how this works with getting the sleep time from the controller?

              F Offline
              F Offline
              flopp
              wrote on last edited by flopp
              #6

              @helvetian
              Thanks.
              I am using Domoticz as Controller.
              After you first start-up of node you will get a Light device, change this device to Dimmer, then in Setup-Hardware-MySensorsSetup, select Node then select Child for SleepTime and disable Ack.

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              20

              Online

              11.7k

              Users

              11.2k

              Topics

              113.1k

              Posts


              Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • MySensors
              • OpenHardware.io
              • Categories
              • Recent
              • Tags
              • Popular