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. Controllers
  3. Domoticz
  4. Domotiocz + Rain gauge

Domotiocz + Rain gauge

Scheduled Pinned Locked Moved Domoticz
61 Posts 12 Posters 31.2k Views 12 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.
  • HilltanH Offline
    HilltanH Offline
    Hilltan
    wrote on last edited by
    #51

    Thanks @TheoL, I will give it a try.

    1 Reply Last reply
    1
    • HilltanH Offline
      HilltanH Offline
      Hilltan
      wrote on last edited by
      #52

      Finally I get it to run with a light sensor (BH1750), temp/hum sensor (DHT22), and the rain tipping sensor. But there are some problems:

      Domoticz seems not to want to divide the DHT sensor in to two, one humidity and one temperature. What I get in Domoticz is one WTGR800 (temp/hum) and one LaCrosse TX3 (temp). Have played around with the code a little bit, just ending up with one WTGT800 (temp/hum) and one LaCrosse TX3 (temp or humidity).

      The rain sensor gets fault impulse from time to time, the sensor got trigged without that the sensor have been set off?
      Overall your @TheoL Threshhold util is a very nice tool to work with, but the DHT sensor is not that easy to deal with I think…

      // Enable and select radio type attached
      #define MY_RADIO_NRF24
      
      /*
        Include libraries used by the sketch
      */
      #include "ThresholdUtil.h"
      #include <math.h>
      #include <Time.h>
      #include <MySensors.h>
      #include <BH1750.h>
      #include "DHT.h"
      #include <Wire.h>
      
      DHT dht;
      #define DHT 0
      
      #define BUCKET_PIN 3                  // The Arduino pin to which the bucket is attached. We need an interrupt pin (2 or 3 on the Uno and the Pro Mini) 
      #define SKETCH_INFO "Outside weather" // The name of the sketch as presented to the gateway
      #define SKETCH_VERSION "1.0"          // The version of the sketch as presented to the gateway
      #define CHILD_ID_RAIN_LOG 4           // The child id of the rain gauge
      #define MS_WAIT 100                   // short delay used to give the NRF24L01+ antenna some time to recover from the last data sending
      #define bucketSize 0.3                // I've used a MI-SOL Rain Guage which has a bucket size of 0.3 mm
      #define LIGHTLEVEL_SENSOR_CHILD_ID 0
      #define LIGHTLEVEL_SENSOR_ID 3
      
      #define CHILD_ID_TEMP 5
      #define DHT_TEMP 6
      #define CHILD_ID_HUMIDITY 7
      #define DHT_HUM 9
      #define DHT_DATA_PIN 8
      
      MyMessage lightLevelMsg(LIGHTLEVEL_SENSOR_CHILD_ID, V_LIGHT_LEVEL);
      MyMessage msgHum( CHILD_ID_HUMIDITY, V_HUM );
      MyMessage msgTemp( CHILD_ID_TEMP, V_TEMP );
      MyMessage msgRain( CHILD_ID_RAIN_LOG, V_RAIN );
      MyMessage lastCounterMsg( CHILD_ID_RAIN_LOG, V_VAR1 );
      
      BH1750 lightSensor;
      float hwRainVolume = 0;           // Current rainvolume calculated in hardware.
      unsigned long hwPulseCounter = 0; // Pulsecount recieved from GW
      boolean pcReceived = false;       // If we have recieved the pulscount from GW or not
      unsigned long lastTipTime = millis(); // TS of when the bucket tip has been detected for the last time
      volatile unsigned long wasTippedCounter; // Queue for storing the tipped counter as been set by the interrupt handler.
      byte lastHour;                    // Stores the hour used for checking if time needs to be synchronized
      
      void presentation() {
        // Send the sketch version information to the gateway
        
        sendSketchInfo( SKETCH_INFO, SKETCH_VERSION );
        wait( MS_WAIT );
        
        present(LIGHTLEVEL_SENSOR_CHILD_ID, S_LIGHT_LEVEL, "Light level" );
        wait( MS_WAIT );  
        present( CHILD_ID_HUMIDITY, S_HUM, "Outside Humidity" );
        wait( MS_WAIT );
        present( CHILD_ID_TEMP, S_TEMP, "Outside Temperature" );
        wait( MS_WAIT );  
        present( CHILD_ID_RAIN_LOG, S_RAIN, "Rain fall" );
        wait( MS_WAIT );
      
        unsigned long functionTimeout = millis();
        while ( pcReceived == false && millis() - functionTimeout < 30000UL ) {
          request( CHILD_ID_RAIN_LOG, V_VAR1);
          Serial.println(F("Getting pulse count"));
          Serial.println(F("."));
          wait( 1000 );
        }
        attachInterrupt( digitalPinToInterrupt( BUCKET_PIN ), sensorTipped, LOW ); //FALLING );  // depending on location of the hall effect sensor may need CHANGE
      }
      
      void setup() {
        Serial.begin( 115200 );
        pinMode( BUCKET_PIN, INPUT_PULLUP );
      
        lightSensor.begin();
        
        registerThresholdedSensor( LIGHTLEVEL_SENSOR_CHILD_ID,  LIGHTLEVEL_SENSOR_ID,  LIGHTLEVEL_SENSOR,  20,  30, 20 ); // read every 5 sec and report at least every 5 minute ändrat 300 till 20
        registerThresholdedSensor( CHILD_ID_TEMP, DHT_TEMP, TEMPERATURE_SENSOR, 0.5, 30, 20 ); // every 30 seconds report at least every 10 minutes 
        registerThresholdedSensor( CHILD_ID_HUMIDITY, DHT_HUM, HUMIDTY_SENSOR, 1.0, 60, 10 ); // every 60 seconds 
      
        dht.setup( DHT_DATA_PIN ); // data pin 8
        delay( dht.getMinimumSamplingPeriod() );
      
        unsigned long functionTimeout = millis();
        while ( timeStatus() == timeNotSet && millis() - functionTimeout < 30000UL ) {
          requestTime();
          Serial.println(F("Getting Time"));
          Serial.println(F("."));
          wait( 1000 );
        }
      
        lastHour = hour();
      }
      
      /**
        Sends the value of the rain gauge to the Gateway.
      */
      void sendRainVolumeData() {
        float hwRainVolume = hwPulseCounter * bucketSize;
        Serial.print( "Tipped " );
        Serial.print( hwPulseCounter );
        Serial.println( " times." );
        Serial.print( "Rain fall is " );
        Serial.print( hwRainVolume, 1 );
        Serial.println( " mm." );
        send( msgRain.set( (float)hwRainVolume, 1 ) );
        wait( MS_WAIT );
        send( lastCounterMsg.set( hwPulseCounter ) );
        wait( MS_WAIT );
      }
      
      void loop() {
        if ( wasTippedCounter != hwPulseCounter ) {
          hwPulseCounter = wasTippedCounter;
          sendRainVolumeData();
        }
      
        byte currentHour = hour();
        if (currentHour != lastHour) {
          Serial.println( "Resyncing hour" );
          requestTime(); // sync the time every hour
          wait( MS_WAIT );
          lastHour = currentHour;
          sendRainVolumeData(); // Send heart beat
        }
      
      checkThresholdedSensors( readSensorValue, updatedSensorValue );
      
      
      }
      
      void sensorTipped() {
        unsigned long thisTipTime = millis();
        if (thisTipTime - lastTipTime > 100UL) {
          wasTippedCounter++;
        }
        lastTipTime = thisTipTime;
      }
      
      float dhtHumidity; 
      
      void readSensorValue( uint8_t aSensorId, ThreshHoldedSensorType aType, float *value ) {
        switch ( aSensorId ) {    
          case LIGHTLEVEL_SENSOR_ID:
            if ( aType == LIGHTLEVEL_SENSOR ) {
              *value = lightSensor.readLightLevel(); 
            }
            break;      
            case DHT_TEMP:
            if ( aType == TEMPERATURE_SENSOR ) {
              *value = dht.getTemperature();
            }
            break;
            case DHT_HUM:
            if ( aType == HUMIDTY_SENSOR ) {
              *value = dht.getHumidity();
            }
            break;
        }
      }
      
      void updatedSensorValue( uint8_t child_id, uint8_t sensor_id, ThreshHoldedSensorType sensor_type, float value ) {
        switch ( child_id ) {
          case LIGHTLEVEL_SENSOR_CHILD_ID:
            Serial.print( "Light level " ); 
            Serial.print( value, 0 ); 
            Serial.println( "%" );
            send( lightLevelMsg.set( value, 5 ) );
            wait( MS_WAIT );
            break;
          case CHILD_ID_TEMP: 
            Serial.print( "Temperatur " ); 
            Serial.print( value, 0 ); 
            Serial.print( "C" ); 
            send( msgTemp.set( value, 1 ) );
            wait( MS_WAIT );
            break;
          case CHILD_ID_HUMIDITY: 
            Serial.print( "HUMIDITY " ); 
            Serial.print( value, 0 ); 
            Serial.print( "%" ); 
            send( msgHum.set( value, 1 ) );
            wait( MS_WAIT );
            break;  
         
        }
      }
      
      void receiveTime(unsigned long time) {
        Serial.println( F("Time received..."));
        setTime(time);
        char theTime[6];
        sprintf(theTime, "%d:%2d", hour(), minute());
        Serial.println(theTime);
      }
      
      void receive(const MyMessage &message) {
        if ( message.sensor == CHILD_ID_RAIN_LOG && message.type == V_VAR1) { // We only expect pulse count values from the gateway
          hwPulseCounter = message.getULong();
          wasTippedCounter = hwPulseCounter;
          pcReceived = true;
      
          Serial.print("Received last pulse count from gw: ");
          Serial.println(hwPulseCounter);
        }
      }
      

      There are probably strange things in the sketch, I am new to this ;)

      AWIA 1 Reply Last reply
      0
      • HilltanH Hilltan

        Finally I get it to run with a light sensor (BH1750), temp/hum sensor (DHT22), and the rain tipping sensor. But there are some problems:

        Domoticz seems not to want to divide the DHT sensor in to two, one humidity and one temperature. What I get in Domoticz is one WTGR800 (temp/hum) and one LaCrosse TX3 (temp). Have played around with the code a little bit, just ending up with one WTGT800 (temp/hum) and one LaCrosse TX3 (temp or humidity).

        The rain sensor gets fault impulse from time to time, the sensor got trigged without that the sensor have been set off?
        Overall your @TheoL Threshhold util is a very nice tool to work with, but the DHT sensor is not that easy to deal with I think…

        // Enable and select radio type attached
        #define MY_RADIO_NRF24
        
        /*
          Include libraries used by the sketch
        */
        #include "ThresholdUtil.h"
        #include <math.h>
        #include <Time.h>
        #include <MySensors.h>
        #include <BH1750.h>
        #include "DHT.h"
        #include <Wire.h>
        
        DHT dht;
        #define DHT 0
        
        #define BUCKET_PIN 3                  // The Arduino pin to which the bucket is attached. We need an interrupt pin (2 or 3 on the Uno and the Pro Mini) 
        #define SKETCH_INFO "Outside weather" // The name of the sketch as presented to the gateway
        #define SKETCH_VERSION "1.0"          // The version of the sketch as presented to the gateway
        #define CHILD_ID_RAIN_LOG 4           // The child id of the rain gauge
        #define MS_WAIT 100                   // short delay used to give the NRF24L01+ antenna some time to recover from the last data sending
        #define bucketSize 0.3                // I've used a MI-SOL Rain Guage which has a bucket size of 0.3 mm
        #define LIGHTLEVEL_SENSOR_CHILD_ID 0
        #define LIGHTLEVEL_SENSOR_ID 3
        
        #define CHILD_ID_TEMP 5
        #define DHT_TEMP 6
        #define CHILD_ID_HUMIDITY 7
        #define DHT_HUM 9
        #define DHT_DATA_PIN 8
        
        MyMessage lightLevelMsg(LIGHTLEVEL_SENSOR_CHILD_ID, V_LIGHT_LEVEL);
        MyMessage msgHum( CHILD_ID_HUMIDITY, V_HUM );
        MyMessage msgTemp( CHILD_ID_TEMP, V_TEMP );
        MyMessage msgRain( CHILD_ID_RAIN_LOG, V_RAIN );
        MyMessage lastCounterMsg( CHILD_ID_RAIN_LOG, V_VAR1 );
        
        BH1750 lightSensor;
        float hwRainVolume = 0;           // Current rainvolume calculated in hardware.
        unsigned long hwPulseCounter = 0; // Pulsecount recieved from GW
        boolean pcReceived = false;       // If we have recieved the pulscount from GW or not
        unsigned long lastTipTime = millis(); // TS of when the bucket tip has been detected for the last time
        volatile unsigned long wasTippedCounter; // Queue for storing the tipped counter as been set by the interrupt handler.
        byte lastHour;                    // Stores the hour used for checking if time needs to be synchronized
        
        void presentation() {
          // Send the sketch version information to the gateway
          
          sendSketchInfo( SKETCH_INFO, SKETCH_VERSION );
          wait( MS_WAIT );
          
          present(LIGHTLEVEL_SENSOR_CHILD_ID, S_LIGHT_LEVEL, "Light level" );
          wait( MS_WAIT );  
          present( CHILD_ID_HUMIDITY, S_HUM, "Outside Humidity" );
          wait( MS_WAIT );
          present( CHILD_ID_TEMP, S_TEMP, "Outside Temperature" );
          wait( MS_WAIT );  
          present( CHILD_ID_RAIN_LOG, S_RAIN, "Rain fall" );
          wait( MS_WAIT );
        
          unsigned long functionTimeout = millis();
          while ( pcReceived == false && millis() - functionTimeout < 30000UL ) {
            request( CHILD_ID_RAIN_LOG, V_VAR1);
            Serial.println(F("Getting pulse count"));
            Serial.println(F("."));
            wait( 1000 );
          }
          attachInterrupt( digitalPinToInterrupt( BUCKET_PIN ), sensorTipped, LOW ); //FALLING );  // depending on location of the hall effect sensor may need CHANGE
        }
        
        void setup() {
          Serial.begin( 115200 );
          pinMode( BUCKET_PIN, INPUT_PULLUP );
        
          lightSensor.begin();
          
          registerThresholdedSensor( LIGHTLEVEL_SENSOR_CHILD_ID,  LIGHTLEVEL_SENSOR_ID,  LIGHTLEVEL_SENSOR,  20,  30, 20 ); // read every 5 sec and report at least every 5 minute ändrat 300 till 20
          registerThresholdedSensor( CHILD_ID_TEMP, DHT_TEMP, TEMPERATURE_SENSOR, 0.5, 30, 20 ); // every 30 seconds report at least every 10 minutes 
          registerThresholdedSensor( CHILD_ID_HUMIDITY, DHT_HUM, HUMIDTY_SENSOR, 1.0, 60, 10 ); // every 60 seconds 
        
          dht.setup( DHT_DATA_PIN ); // data pin 8
          delay( dht.getMinimumSamplingPeriod() );
        
          unsigned long functionTimeout = millis();
          while ( timeStatus() == timeNotSet && millis() - functionTimeout < 30000UL ) {
            requestTime();
            Serial.println(F("Getting Time"));
            Serial.println(F("."));
            wait( 1000 );
          }
        
          lastHour = hour();
        }
        
        /**
          Sends the value of the rain gauge to the Gateway.
        */
        void sendRainVolumeData() {
          float hwRainVolume = hwPulseCounter * bucketSize;
          Serial.print( "Tipped " );
          Serial.print( hwPulseCounter );
          Serial.println( " times." );
          Serial.print( "Rain fall is " );
          Serial.print( hwRainVolume, 1 );
          Serial.println( " mm." );
          send( msgRain.set( (float)hwRainVolume, 1 ) );
          wait( MS_WAIT );
          send( lastCounterMsg.set( hwPulseCounter ) );
          wait( MS_WAIT );
        }
        
        void loop() {
          if ( wasTippedCounter != hwPulseCounter ) {
            hwPulseCounter = wasTippedCounter;
            sendRainVolumeData();
          }
        
          byte currentHour = hour();
          if (currentHour != lastHour) {
            Serial.println( "Resyncing hour" );
            requestTime(); // sync the time every hour
            wait( MS_WAIT );
            lastHour = currentHour;
            sendRainVolumeData(); // Send heart beat
          }
        
        checkThresholdedSensors( readSensorValue, updatedSensorValue );
        
        
        }
        
        void sensorTipped() {
          unsigned long thisTipTime = millis();
          if (thisTipTime - lastTipTime > 100UL) {
            wasTippedCounter++;
          }
          lastTipTime = thisTipTime;
        }
        
        float dhtHumidity; 
        
        void readSensorValue( uint8_t aSensorId, ThreshHoldedSensorType aType, float *value ) {
          switch ( aSensorId ) {    
            case LIGHTLEVEL_SENSOR_ID:
              if ( aType == LIGHTLEVEL_SENSOR ) {
                *value = lightSensor.readLightLevel(); 
              }
              break;      
              case DHT_TEMP:
              if ( aType == TEMPERATURE_SENSOR ) {
                *value = dht.getTemperature();
              }
              break;
              case DHT_HUM:
              if ( aType == HUMIDTY_SENSOR ) {
                *value = dht.getHumidity();
              }
              break;
          }
        }
        
        void updatedSensorValue( uint8_t child_id, uint8_t sensor_id, ThreshHoldedSensorType sensor_type, float value ) {
          switch ( child_id ) {
            case LIGHTLEVEL_SENSOR_CHILD_ID:
              Serial.print( "Light level " ); 
              Serial.print( value, 0 ); 
              Serial.println( "%" );
              send( lightLevelMsg.set( value, 5 ) );
              wait( MS_WAIT );
              break;
            case CHILD_ID_TEMP: 
              Serial.print( "Temperatur " ); 
              Serial.print( value, 0 ); 
              Serial.print( "C" ); 
              send( msgTemp.set( value, 1 ) );
              wait( MS_WAIT );
              break;
            case CHILD_ID_HUMIDITY: 
              Serial.print( "HUMIDITY " ); 
              Serial.print( value, 0 ); 
              Serial.print( "%" ); 
              send( msgHum.set( value, 1 ) );
              wait( MS_WAIT );
              break;  
           
          }
        }
        
        void receiveTime(unsigned long time) {
          Serial.println( F("Time received..."));
          setTime(time);
          char theTime[6];
          sprintf(theTime, "%d:%2d", hour(), minute());
          Serial.println(theTime);
        }
        
        void receive(const MyMessage &message) {
          if ( message.sensor == CHILD_ID_RAIN_LOG && message.type == V_VAR1) { // We only expect pulse count values from the gateway
            hwPulseCounter = message.getULong();
            wasTippedCounter = hwPulseCounter;
            pcReceived = true;
        
            Serial.print("Received last pulse count from gw: ");
            Serial.println(hwPulseCounter);
          }
        }
        

        There are probably strange things in the sketch, I am new to this ;)

        AWIA Offline
        AWIA Offline
        AWI
        Hero Member
        wrote on last edited by
        #53

        @Hilltan it is a Domoticz 'feature' to combine temperature, humidity and barometric sensors. There is a method to separate them if you have (or pretend to have) multiple sensors of the same type. This is done by presenting the one you want to combine right after each other.

        In your case I would just keep it...

        1 Reply Last reply
        0
        • sundberg84S sundberg84

          This is my rainsensor/tipping bucket for MySensors that works with Domoticz.

          It uses 2xAA as power source, a Pro Mini 3.3v with a 0.9 to 3.3 booster.
          The bucket has a magnet which triggeras a reed switch which triggers an interrupt pin.
          I also use battery sensing with voltage divider.

          // Enable debug prints to serial monitor
          #define MY_DEBUG 
          #define MY_RADIO_NRF24
          #define MY_NODE_ID 7
          
          #include <SPI.h>
          #include <MySensor.h>  
          
          // Running this in Domoticz stable version 2.5 will not work - upgrade to beta.
          
          #define DIGITAL_INPUT_SENSOR 3                  // The reed switch you attached.  (Only 2 and 3 generates interrupt!)
          #define INTERRUPT DIGITAL_INPUT_SENSOR-2        // Usually the interrupt = pin -2 (on uno/nano anyway)
          
          #define CHILD_ID 1                              // Id of the sensor child
          #define SKETCH_NAME "Rain Gauge"                // Change to a fancy name you like
          #define SKETCH_VERSION "1.1"                    // Your version
          
          unsigned long SLEEP_TIME = 18*60000;            // Sleep time (in milliseconds).
          //unsigned long SLEEP_TIME = 20000;             // use this instead for debug
          
          float hwRainVolume = 0;                         // Current rainvolume calculated in hardware.
          int hwPulseCounter = 0;                         // Pulsecount recieved from GW
          float fullCounter = 0;                           // Counts when to send counter
          float bucketSize = 0.5;                           // Bucketsize mm, needs to be 1, 0.5, 0.25, 0.2 or 0.1
          boolean pcReceived = false;                     // If we have recieved the pulscount from GW or not 
          boolean reedState;                              // Current state the reedswitch is in
          boolean oldReedState;                           // Old state (last state) of the reedswitch
          unsigned long lastSend =0;                      // Time we last tried to fetch counter.
          
          MyMessage volumeMsg(CHILD_ID,V_RAIN);
          MyMessage lastCounterMsg(CHILD_ID,V_VAR1);
          
          //=========================
          // BATTERY VOLTAGE DIVIDER SETUP
          // 1M, 470K divider across battery and using internal ADC ref of 1.1V
          // Sense point is bypassed with 0.1 uF cap to reduce noise at that point
          // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
          // 3.44/1023 = Volts per bit = 0.003363075
          #define VBAT_PER_BITS 0.003363075  
          #define VMIN 1.9                                  //  Vmin (radio Min Volt)=1.9V (564v)
          #define VMAX 3.0                                  //  Vmax = (2xAA bat)=3.0V (892v)
          int batteryPcnt = 0;                              // Calc value for battery %
          int batLoop = 0;                                  // Loop to help calc average
          int batArray[3];                                  // Array to store value for average calc.
          int BATTERY_SENSE_PIN = A0;                       // select the input pin for the battery sense point
          //=========================
          
          void presentation() {
          
            // Send the Sketch Version Information to the Gateway
            sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);
          
            // Register this device as Rain sensor (will not show in Domoticz until first value arrives)
            present(CHILD_ID, S_RAIN);       
          }
          
          
          void setup()  
          {  
            // use the 1.1 V internal reference
            analogReference(INTERNAL);             // For battery sensing
            
            pinMode(DIGITAL_INPUT_SENSOR, INPUT_PULLUP);  // sets the reed sensor digital pin as input
          
            reedState = digitalRead(DIGITAL_INPUT_SENSOR); // Read what state the reedswitch is in
            oldReedState = reedState; // Set startup position for reedswitch 
            
            Serial.println("Startup completed");
          }
          
          void loop()     
          { 
          unsigned long currentTime = millis();
          
              //See if we have the counter/pulse from Domoticz - and ask for it if we dont.
              if (!pcReceived && (currentTime - lastSend > 5000)) {      
                request(CHILD_ID, V_VAR1);
                lastSend=currentTime;
                return;
              }
              if (!pcReceived) {
                return;
              }
              
          //Read if the bucket tipped over
          reedState = digitalRead(DIGITAL_INPUT_SENSOR);
          boolean tipped = oldReedState != reedState; 
          
              //BUCKET TIPS!
              if (tipped==true) {
              Serial.println("The bucket has tipped over...");
              oldReedState = reedState;
              hwRainVolume = hwRainVolume + bucketSize;
              send(volumeMsg.set((float)hwRainVolume,1));
              wait(1000);
              fullCounter = fullCounter + bucketSize;
          
                //Count so we send the counter for every 1mm
                if(fullCounter >= 1){
                hwPulseCounter++;
                send(lastCounterMsg.set(hwPulseCounter));
                wait(1000);
                fullCounter = 0;
                }
                
              }
              
              if (tipped==false) {
          
               //No bucket tipped over last sleep-period, check battery then...
               batM(); 
              }
          
          lastSend=currentTime;
          sleep(INTERRUPT, CHANGE, SLEEP_TIME); 
          //The interupt can be CHANGE or FALLING depending on how you wired the hardware.
          }
          
          //Read if we have a incoming message.
          void receive(const MyMessage &msg) {
              if (msg.type==V_VAR1) {
              hwPulseCounter = msg.getULong();
              hwRainVolume = hwPulseCounter;
              pcReceived = true;
              Serial.print("Received last pulse count from gw: ");
              Serial.println(hwPulseCounter);   
              }
          }
          
          void batM(){  //The battery calculations
            
             delay(500);
             // Battery monitoring reading
             int sensorValue = analogRead(BATTERY_SENSE_PIN);    
             delay(500);
             
             // Calculate the battery in %
             float Vbat  = sensorValue * VBAT_PER_BITS;
             int batteryPcnt = static_cast<int>(((Vbat-VMIN)/(VMAX-VMIN))*100.);
             Serial.print("Battery percent: "); Serial.print(batteryPcnt); Serial.println(" %");  
             
             // Add it to array so we get an average of 3 (3x20min)
             batArray[batLoop] = batteryPcnt;
            
             if (batLoop > 1) {  
               batteryPcnt = (batArray[0] + batArray[1] + batArray[2]);
               batteryPcnt = batteryPcnt / 3;
           
             if (batteryPcnt > 100) {
               batteryPcnt=100;
           }
           
               Serial.print("Battery Average (Send): "); Serial.print(batteryPcnt); Serial.println(" %");
                 sendBatteryLevel(batteryPcnt);
                 batLoop = 0;
                 
               //Sends 1 per hour as a heartbeat.
               send(volumeMsg.set((float)hwRainVolume,1));   
               send(lastCounterMsg.set(hwPulseCounter));
               }
               else 
               {
               batLoop++;
               }
          }
          
          M Offline
          M Offline
          Matt
          wrote on last edited by
          #54

          @sundberg84 sorry I know this is an old thread but hoping you can remember how you wrote this code.I have changed it to suit MYS 2.1 as below. I have also added battery level as a separate child ID so I can watch performance over time. Aside from these simple changes the code is all yours from the start of this post. It is built on v8 of your board, controller/GW is latest domoticz beta running on a PI2 using NRFs.
          I have a couple of questions though. I am curious as to why bucketSize needs to be 1, 0.5, 0.25, 0.2 or 0.1 as per your comments and I suspect that when I calibrate my gauge it wont be any of these.
          I am testing at the moment without the gauge. When I earth D3 it actually reports as TWO bucket tips and the volume goes up by 0.5 twice. I dont think this is a bounce issue due to the many wait(1000) functions in your code. Would you know why this is? I have tried changing CHANGE to FALLING in the sleep function. I have a simple reed switch gague.
          Which leads to my third question. Are all the wait times necessary? Could they be much less? I wonder if I will miss bucket tips because of these during heavy rain...
          Many many thanks,
          Matt

          // Enable debug prints to serial monitor
          #define MY_DEBUG 
          #define MY_RADIO_NRF24
          #define MY_RF24_PA_LEVEL RF24_PA_LOW
          #define MY_RF24_DATARATE RF24_250KBPS
          
          
          #include <MySensors.h>  
          
          // Running this in Domoticz stable version 2.5 will not work - upgrade to beta.
          
          #define DIGITAL_INPUT_SENSOR 3                  // The reed switch you attached.  (Only 2 and 3 generates interrupt!)
          #define INTERRUPT DIGITAL_INPUT_SENSOR-2        // Usually the interrupt = pin -2 (on uno/nano anyway)
          
          #define CHILD_ID 1                              // Id of the sensor child
          #define CHILD_ID_BAT 2                          // Id of BAT
          #define SKETCH_NAME "Rain Gauge"                // Change to a fancy name you like
          #define SKETCH_VERSION "1.1"                    // Your version
          
          unsigned long SLEEP_TIME = 18*60000;            // Sleep time (in milliseconds).
          //unsigned long SLEEP_TIME = 20000;             // use this instead for debug
          
          float hwRainVolume = 0;                         // Current rainvolume calculated in hardware.
          int hwPulseCounter = 0;                         // Pulsecount recieved from GW
          float fullCounter = 0;                           // Counts when to send counter
          float bucketSize = 0.5;                           // Bucketsize mm, needs to be 1, 0.5, 0.25, 0.2 or 0.1
          boolean pcReceived = false;                     // If we have recieved the pulscount from GW or not 
          boolean reedState;                              // Current state the reedswitch is in
          boolean oldReedState;                           // Old state (last state) of the reedswitch
          unsigned long lastSend =0;                      // Time we last tried to fetch counter.
          
          MyMessage volumeMsg(CHILD_ID,V_RAIN);
          MyMessage lastCounterMsg(CHILD_ID,V_VAR1);
          MyMessage msgBat(CHILD_ID_BAT, V_VOLTAGE);
          
          //=========================
          // BATTERY VOLTAGE DIVIDER SETUP
          // 1M, 470K divider across battery and using internal ADC ref of 1.1V
          // Sense point is bypassed with 0.1 uF cap to reduce noise at that point
          // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
          // 3.44/1023 = Volts per bit = 0.003363075
          #define VBAT_PER_BITS 0.003363075  
          #define VMIN 1.9                                  //  Vmin (radio Min Volt)=1.9V (564v)
          #define VMAX 3.0                                  //  Vmax = (2xAA bat)=3.0V (892v)
          int batteryPcnt = 0;                              // Calc value for battery %
          int batLoop = 0;                                  // Loop to help calc average
          int batArray[3];                                  // Array to store value for average calc.
          int BATTERY_SENSE_PIN = A0;                       // select the input pin for the battery sense point
          //=========================
          
          void presentation() {
          
            // Send the Sketch Version Information to the Gateway
            sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);
          
            // Register this device as Rain sensor (will not show in Domoticz until first value arrives)
            present(CHILD_ID, S_RAIN); 
            present(CHILD_ID_BAT, S_MULTIMETER);      
          }
          
          
          void setup()  
          {  
                                                           // use the 1.1 V internal reference
            analogReference(INTERNAL);                     // For battery sensing
            
            pinMode(DIGITAL_INPUT_SENSOR, INPUT_PULLUP);   // sets the reed sensor digital pin as input
          
            reedState = digitalRead(DIGITAL_INPUT_SENSOR); // Read what state the reedswitch is in
            oldReedState = reedState;                      // Set startup position for reedswitch 
            
            Serial.println("Startup completed");
            delay(500);                                    // Allow time for radio if power used as reset
          }
          
          void loop()     
          { 
          unsigned long currentTime = millis();
          
              //See if we have the counter/pulse from Domoticz - and ask for it if we dont.
              if (!pcReceived && (currentTime - lastSend > 5000)) {      
                request(CHILD_ID, V_VAR1);
                lastSend=currentTime;
                return;
              }
              if (!pcReceived) {
                return;
              }
              
          //Read if the bucket tipped over
          reedState = digitalRead(DIGITAL_INPUT_SENSOR);
          boolean tipped = oldReedState != reedState; 
          
              //BUCKET TIPS!
              if (tipped==true) {
              Serial.println("The bucket has tipped over...");
              oldReedState = reedState;
              hwRainVolume = hwRainVolume + bucketSize;
              send(volumeMsg.set((float)hwRainVolume,1));
              wait(1000);
              fullCounter = fullCounter + bucketSize;
          
                //Count so we send the counter for every 1mm
                if(fullCounter >= 1){
                hwPulseCounter++;
                send(lastCounterMsg.set(hwPulseCounter));
                wait(1000);
                fullCounter = 0;
                }
                
              }
              
              if (tipped==false) {
          
               //No bucket tipped over last sleep-period, check battery then...
               batM(); 
              }
          
          lastSend=currentTime;
          sleep(INTERRUPT, FALLING, SLEEP_TIME); 
          //The interupt can be CHANGE or FALLING depending on how you wired the hardware.
          }
          
          //Read if we have a incoming message.
          void receive(const MyMessage &msg) {
              if (msg.type==V_VAR1) {
              hwPulseCounter = msg.getULong();
              hwRainVolume = hwPulseCounter;
              pcReceived = true;
              Serial.print("Received last pulse count from gw: ");
              Serial.println(hwPulseCounter);   
              }
          }
          
          void batM(){  //The battery calculations
            
             delay(500);
             // Battery monitoring reading
             int sensorValue = analogRead(BATTERY_SENSE_PIN);    
             delay(500);
             
             // Calculate the battery in %
             float Vbat  = sensorValue * VBAT_PER_BITS;
             int batteryPcnt = static_cast<int>(((Vbat-VMIN)/(VMAX-VMIN))*100.);
             Serial.print("Battery percent: "); Serial.print(batteryPcnt); Serial.println(" %");  
             
             // Add it to array so we get an average of 3 (3x20min)
             batArray[batLoop] = batteryPcnt;
            
             if (batLoop > 1) {  
               batteryPcnt = (batArray[0] + batArray[1] + batArray[2]);
               batteryPcnt = batteryPcnt / 3;
           
             if (batteryPcnt > 100) {
               batteryPcnt=100;
           }
           
               Serial.print("Battery Average (Send): "); Serial.print(batteryPcnt); Serial.println(" %");
                 sendBatteryLevel(batteryPcnt);
                 send(msgBat.set(Vbat, 4));
                 batLoop = 0;
                 
               //Sends 1 per hour as a heartbeat.
               send(volumeMsg.set((float)hwRainVolume,1));   
               send(lastCounterMsg.set(hwPulseCounter));
               }
               else 
               {
               batLoop++;
               }
          }```
          sundberg84S 1 Reply Last reply
          0
          • M Matt

            @sundberg84 sorry I know this is an old thread but hoping you can remember how you wrote this code.I have changed it to suit MYS 2.1 as below. I have also added battery level as a separate child ID so I can watch performance over time. Aside from these simple changes the code is all yours from the start of this post. It is built on v8 of your board, controller/GW is latest domoticz beta running on a PI2 using NRFs.
            I have a couple of questions though. I am curious as to why bucketSize needs to be 1, 0.5, 0.25, 0.2 or 0.1 as per your comments and I suspect that when I calibrate my gauge it wont be any of these.
            I am testing at the moment without the gauge. When I earth D3 it actually reports as TWO bucket tips and the volume goes up by 0.5 twice. I dont think this is a bounce issue due to the many wait(1000) functions in your code. Would you know why this is? I have tried changing CHANGE to FALLING in the sleep function. I have a simple reed switch gague.
            Which leads to my third question. Are all the wait times necessary? Could they be much less? I wonder if I will miss bucket tips because of these during heavy rain...
            Many many thanks,
            Matt

            // Enable debug prints to serial monitor
            #define MY_DEBUG 
            #define MY_RADIO_NRF24
            #define MY_RF24_PA_LEVEL RF24_PA_LOW
            #define MY_RF24_DATARATE RF24_250KBPS
            
            
            #include <MySensors.h>  
            
            // Running this in Domoticz stable version 2.5 will not work - upgrade to beta.
            
            #define DIGITAL_INPUT_SENSOR 3                  // The reed switch you attached.  (Only 2 and 3 generates interrupt!)
            #define INTERRUPT DIGITAL_INPUT_SENSOR-2        // Usually the interrupt = pin -2 (on uno/nano anyway)
            
            #define CHILD_ID 1                              // Id of the sensor child
            #define CHILD_ID_BAT 2                          // Id of BAT
            #define SKETCH_NAME "Rain Gauge"                // Change to a fancy name you like
            #define SKETCH_VERSION "1.1"                    // Your version
            
            unsigned long SLEEP_TIME = 18*60000;            // Sleep time (in milliseconds).
            //unsigned long SLEEP_TIME = 20000;             // use this instead for debug
            
            float hwRainVolume = 0;                         // Current rainvolume calculated in hardware.
            int hwPulseCounter = 0;                         // Pulsecount recieved from GW
            float fullCounter = 0;                           // Counts when to send counter
            float bucketSize = 0.5;                           // Bucketsize mm, needs to be 1, 0.5, 0.25, 0.2 or 0.1
            boolean pcReceived = false;                     // If we have recieved the pulscount from GW or not 
            boolean reedState;                              // Current state the reedswitch is in
            boolean oldReedState;                           // Old state (last state) of the reedswitch
            unsigned long lastSend =0;                      // Time we last tried to fetch counter.
            
            MyMessage volumeMsg(CHILD_ID,V_RAIN);
            MyMessage lastCounterMsg(CHILD_ID,V_VAR1);
            MyMessage msgBat(CHILD_ID_BAT, V_VOLTAGE);
            
            //=========================
            // BATTERY VOLTAGE DIVIDER SETUP
            // 1M, 470K divider across battery and using internal ADC ref of 1.1V
            // Sense point is bypassed with 0.1 uF cap to reduce noise at that point
            // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
            // 3.44/1023 = Volts per bit = 0.003363075
            #define VBAT_PER_BITS 0.003363075  
            #define VMIN 1.9                                  //  Vmin (radio Min Volt)=1.9V (564v)
            #define VMAX 3.0                                  //  Vmax = (2xAA bat)=3.0V (892v)
            int batteryPcnt = 0;                              // Calc value for battery %
            int batLoop = 0;                                  // Loop to help calc average
            int batArray[3];                                  // Array to store value for average calc.
            int BATTERY_SENSE_PIN = A0;                       // select the input pin for the battery sense point
            //=========================
            
            void presentation() {
            
              // Send the Sketch Version Information to the Gateway
              sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);
            
              // Register this device as Rain sensor (will not show in Domoticz until first value arrives)
              present(CHILD_ID, S_RAIN); 
              present(CHILD_ID_BAT, S_MULTIMETER);      
            }
            
            
            void setup()  
            {  
                                                             // use the 1.1 V internal reference
              analogReference(INTERNAL);                     // For battery sensing
              
              pinMode(DIGITAL_INPUT_SENSOR, INPUT_PULLUP);   // sets the reed sensor digital pin as input
            
              reedState = digitalRead(DIGITAL_INPUT_SENSOR); // Read what state the reedswitch is in
              oldReedState = reedState;                      // Set startup position for reedswitch 
              
              Serial.println("Startup completed");
              delay(500);                                    // Allow time for radio if power used as reset
            }
            
            void loop()     
            { 
            unsigned long currentTime = millis();
            
                //See if we have the counter/pulse from Domoticz - and ask for it if we dont.
                if (!pcReceived && (currentTime - lastSend > 5000)) {      
                  request(CHILD_ID, V_VAR1);
                  lastSend=currentTime;
                  return;
                }
                if (!pcReceived) {
                  return;
                }
                
            //Read if the bucket tipped over
            reedState = digitalRead(DIGITAL_INPUT_SENSOR);
            boolean tipped = oldReedState != reedState; 
            
                //BUCKET TIPS!
                if (tipped==true) {
                Serial.println("The bucket has tipped over...");
                oldReedState = reedState;
                hwRainVolume = hwRainVolume + bucketSize;
                send(volumeMsg.set((float)hwRainVolume,1));
                wait(1000);
                fullCounter = fullCounter + bucketSize;
            
                  //Count so we send the counter for every 1mm
                  if(fullCounter >= 1){
                  hwPulseCounter++;
                  send(lastCounterMsg.set(hwPulseCounter));
                  wait(1000);
                  fullCounter = 0;
                  }
                  
                }
                
                if (tipped==false) {
            
                 //No bucket tipped over last sleep-period, check battery then...
                 batM(); 
                }
            
            lastSend=currentTime;
            sleep(INTERRUPT, FALLING, SLEEP_TIME); 
            //The interupt can be CHANGE or FALLING depending on how you wired the hardware.
            }
            
            //Read if we have a incoming message.
            void receive(const MyMessage &msg) {
                if (msg.type==V_VAR1) {
                hwPulseCounter = msg.getULong();
                hwRainVolume = hwPulseCounter;
                pcReceived = true;
                Serial.print("Received last pulse count from gw: ");
                Serial.println(hwPulseCounter);   
                }
            }
            
            void batM(){  //The battery calculations
              
               delay(500);
               // Battery monitoring reading
               int sensorValue = analogRead(BATTERY_SENSE_PIN);    
               delay(500);
               
               // Calculate the battery in %
               float Vbat  = sensorValue * VBAT_PER_BITS;
               int batteryPcnt = static_cast<int>(((Vbat-VMIN)/(VMAX-VMIN))*100.);
               Serial.print("Battery percent: "); Serial.print(batteryPcnt); Serial.println(" %");  
               
               // Add it to array so we get an average of 3 (3x20min)
               batArray[batLoop] = batteryPcnt;
              
               if (batLoop > 1) {  
                 batteryPcnt = (batArray[0] + batArray[1] + batArray[2]);
                 batteryPcnt = batteryPcnt / 3;
             
               if (batteryPcnt > 100) {
                 batteryPcnt=100;
             }
             
                 Serial.print("Battery Average (Send): "); Serial.print(batteryPcnt); Serial.println(" %");
                   sendBatteryLevel(batteryPcnt);
                   send(msgBat.set(Vbat, 4));
                   batLoop = 0;
                   
                 //Sends 1 per hour as a heartbeat.
                 send(volumeMsg.set((float)hwRainVolume,1));   
                 send(lastCounterMsg.set(hwPulseCounter));
                 }
                 else 
                 {
                 batLoop++;
                 }
            }```
            sundberg84S Offline
            sundberg84S Offline
            sundberg84
            Hardware Contributor
            wrote on last edited by sundberg84
            #55

            @Matt said in Domotiocz + Rain gauge:

            OK :) Lets see what I can do...

            I am curious as to why bucketSize needs to be 1, 0.5, 0.25, 0.2 or 0.1 as per your comments and I suspect that when I calibrate my gauge it wont be any of these.

            Its because of this calculaction and that Domoticz uses 1mm counter:

                fullCounter = fullCounter + bucketSize;
            
                  //Count so we send the counter for every 1mm
                  if(fullCounter >= 1){
                  hwPulseCounter++;
                  send(lastCounterMsg.set(hwPulseCounter));
                  wait(1000);
                  fullCounter = 0;
                  }
            

            If the bucketsize is set to say 0,3mm it will not add up to a full 1 and the code is lost. (0,3+0,3+0,3+0,3 = 1.2) and 0,2 is lost. Im sure you can code this better (code is not my strong side!!!)

            I am testing at the moment without the gauge. When I earth D3 it actually reports as TWO bucket tips and the volume goes up by 0.5 twice. I dont think this is a bounce issue due to the many wait(1000) functions in your code. Would you know why this is? I have tried changing CHANGE to FALLING in the sleep function. I have a simple reed switch gague.

            Do you have a pulldown/up resistor to avoid the pin floats?

            Are all the wait times necessary? Could they be much less?

            Its a matter of code and what bucket you have. Some wait() are for debounce and stabilising power for radio and readings. I would not change those but I always aim for the high numbers to be sure(wait(1000); = really high!!). Try!
            Other wait() could depend on what kind of bucket you use - im sorry to say, but all you can do is try!

            Controller: Proxmox VM - Home Assistant
            MySensors GW: Arduino Uno - W5100 Ethernet, Gw Shield Nrf24l01+ 2,4Ghz
            MySensors GW: Arduino Uno - Gw Shield RFM69, 433mhz
            RFLink GW - Arduino Mega + RFLink Shield, 433mhz

            M 1 Reply Last reply
            0
            • sundberg84S sundberg84

              @Matt said in Domotiocz + Rain gauge:

              OK :) Lets see what I can do...

              I am curious as to why bucketSize needs to be 1, 0.5, 0.25, 0.2 or 0.1 as per your comments and I suspect that when I calibrate my gauge it wont be any of these.

              Its because of this calculaction and that Domoticz uses 1mm counter:

                  fullCounter = fullCounter + bucketSize;
              
                    //Count so we send the counter for every 1mm
                    if(fullCounter >= 1){
                    hwPulseCounter++;
                    send(lastCounterMsg.set(hwPulseCounter));
                    wait(1000);
                    fullCounter = 0;
                    }
              

              If the bucketsize is set to say 0,3mm it will not add up to a full 1 and the code is lost. (0,3+0,3+0,3+0,3 = 1.2) and 0,2 is lost. Im sure you can code this better (code is not my strong side!!!)

              I am testing at the moment without the gauge. When I earth D3 it actually reports as TWO bucket tips and the volume goes up by 0.5 twice. I dont think this is a bounce issue due to the many wait(1000) functions in your code. Would you know why this is? I have tried changing CHANGE to FALLING in the sleep function. I have a simple reed switch gague.

              Do you have a pulldown/up resistor to avoid the pin floats?

              Are all the wait times necessary? Could they be much less?

              Its a matter of code and what bucket you have. Some wait() are for debounce and stabilising power for radio and readings. I would not change those but I always aim for the high numbers to be sure(wait(1000); = really high!!). Try!
              Other wait() could depend on what kind of bucket you use - im sorry to say, but all you can do is try!

              M Offline
              M Offline
              Matt
              wrote on last edited by
              #56

              @sundberg84
              Thankyou very much for your reply.
              It seems strange that domoticz would only accept 1mm pulses I wonder if this has changed... In any case it should be easy to save the 'lost' volume and add it to the next bucket in code...
              The internal pullup is switched on in code so reed switch pin won't be floating. Will have a fiddle round with your code today.
              Will also try to calibrate by gauge today will be easy to see max tipping speed and can adjust wait times accordingly...
              Thanks again,
              Matt

              sundberg84S 1 Reply Last reply
              0
              • M Matt

                @sundberg84
                Thankyou very much for your reply.
                It seems strange that domoticz would only accept 1mm pulses I wonder if this has changed... In any case it should be easy to save the 'lost' volume and add it to the next bucket in code...
                The internal pullup is switched on in code so reed switch pin won't be floating. Will have a fiddle round with your code today.
                Will also try to calibrate by gauge today will be easy to see max tipping speed and can adjust wait times accordingly...
                Thanks again,
                Matt

                sundberg84S Offline
                sundberg84S Offline
                sundberg84
                Hardware Contributor
                wrote on last edited by
                #57

                @Matt - Let me know if I can help you anything-

                Controller: Proxmox VM - Home Assistant
                MySensors GW: Arduino Uno - W5100 Ethernet, Gw Shield Nrf24l01+ 2,4Ghz
                MySensors GW: Arduino Uno - Gw Shield RFM69, 433mhz
                RFLink GW - Arduino Mega + RFLink Shield, 433mhz

                1 Reply Last reply
                0
                • HilltanH Offline
                  HilltanH Offline
                  Hilltan
                  wrote on last edited by
                  #58

                  I need could need some help/advice to get my rain gauge to show correct values, as per today my rain gauge shows to low values. The rain gauge that I use is this one: Rain gauge
                  I use Domoticz V 3.8153 with Mysensors V2.1.1 and have bucket size 0,3. Anyone that have experience with this rain gauge and what bucket size to use for correct values or is there something with my code that creates problems?

                  This it my sketch that I am usning:

                  // Enable and select radio type attached
                  #define MY_RADIO_NRF24
                  #define MY_NODE_ID 5
                  
                  #include "ThresholdUtil.h"
                  #include <math.h>
                  #include <Time.h>
                  #include <MySensors.h>
                  #include "DHT.h"
                  #include <Wire.h>
                  
                  DHT dht;
                  #define DHT 0
                  
                  #define BUCKET_PIN 3                  // The Arduino pin to which the bucket is attached. We need an interrupt pin (2 or 3 on the Uno and the Pro Mini) 
                  #define SKETCH_INFO "Rain,Temp&Hum" // The name of the sketch as presented to the gateway
                  #define SKETCH_VERSION "1.0"          // The version of the sketch as presented to the gateway
                  #define CHILD_ID_RAIN_LOG 4           // The child id of the rain gauge
                  #define MS_WAIT 100                   // short delay used to give the NRF24L01+ antenna some time to recover from the last data sending
                  #define bucketSize 0.3                // I've used a MI-SOL Rain Guage which has a bucket size of 0.3 mm
                  
                  
                  #define CHILD_ID_TEMP 5
                  #define DHT_TEMP 6
                  #define CHILD_ID_HUMIDITY 7
                  #define DHT_HUM 9
                  #define DHT_DATA_PIN 5
                  
                  MyMessage msgHum( CHILD_ID_HUMIDITY, V_HUM );
                  MyMessage msgTemp( CHILD_ID_TEMP, V_TEMP );
                  MyMessage msgRain( CHILD_ID_RAIN_LOG, V_RAIN );
                  MyMessage lastCounterMsg( CHILD_ID_RAIN_LOG, V_VAR1 );
                  
                  
                  float hwRainVolume = 0;           // Current rainvolume calculated in hardware.
                  unsigned long hwPulseCounter = 0; // Pulsecount recieved from GW
                  boolean pcReceived = false;       // If we have recieved the pulscount from GW or not
                  unsigned long lastTipTime = millis(); // TS of when the bucket tip has been detected for the last time
                  volatile unsigned long wasTippedCounter; // Queue for storing the tipped counter as been set by the interrupt handler.
                  byte lastHour;                    // Stores the hour used for checking if time needs to be synchronized
                  
                  void presentation() {
                    // Send the sketch version information to the gateway
                    
                    sendSketchInfo( SKETCH_INFO, SKETCH_VERSION );
                    wait( MS_WAIT );  
                    present( CHILD_ID_HUMIDITY, S_HUM, "Outside Humidity" );
                    wait( MS_WAIT );
                    present( CHILD_ID_TEMP, S_TEMP, "Outside Temperature" );
                    wait( MS_WAIT );  
                    present( CHILD_ID_RAIN_LOG, S_RAIN, "Rain fall" );
                    wait( MS_WAIT );
                  
                    unsigned long functionTimeout = millis();
                    while ( pcReceived == false && millis() - functionTimeout < 30000UL ) {
                      request( CHILD_ID_RAIN_LOG, V_VAR1);
                      Serial.println(F("Getting pulse count"));
                      Serial.println(F("."));
                      wait( 1000 );
                    }
                    attachInterrupt( digitalPinToInterrupt( BUCKET_PIN ), sensorTipped, LOW ); //FALLING );  // depending on location of the hall effect sensor may need CHANGE, LOW or HIGE
                  }
                  
                  void setup() {
                    Serial.begin( 115200 );
                    pinMode( BUCKET_PIN, INPUT_PULLUP ); 
                  
                    registerThresholdedSensor( CHILD_ID_TEMP, DHT_TEMP, TEMPERATURE_SENSOR, 0.5, 60, 8 ); // Change of value +/-0,5 , every 60 seconds report, and force report every 8 minutes 
                    registerThresholdedSensor( CHILD_ID_HUMIDITY, DHT_HUM, HUMIDTY_SENSOR, 1.0, 60, 8 ); // Change of value +/- 1, every 60 seconds report, and force report every 8 minutes  
                  
                    dht.setup( DHT_DATA_PIN ); // data pin 8
                    delay( dht.getMinimumSamplingPeriod() );
                  
                    unsigned long functionTimeout = millis();
                    while ( timeStatus() == timeNotSet && millis() - functionTimeout < 30000UL ) {
                      requestTime();
                      Serial.println(F("Getting Time"));
                      Serial.println(F("."));
                      wait( 1000 );
                    }
                  
                    lastHour = hour();
                  }
                  
                  /**
                    Sends the value of the rain gauge to the Gateway.
                  */
                  void sendRainVolumeData() {
                    float hwRainVolume = hwPulseCounter * bucketSize;
                    Serial.print( "Tipped " );
                    Serial.print( hwPulseCounter );
                    Serial.println( " times." );
                    Serial.print( "Rain fall is " );
                    Serial.print( hwRainVolume, 1 );
                    Serial.println( " mm." );
                    send( msgRain.set( (float)hwRainVolume, 1 ) );
                    wait( MS_WAIT );
                    send( lastCounterMsg.set( hwPulseCounter ) );
                    wait( MS_WAIT );
                  }
                  
                  void loop() {
                    if ( wasTippedCounter != hwPulseCounter ) {
                      hwPulseCounter = wasTippedCounter;
                      sendRainVolumeData();
                    }
                  
                    byte currentHour = hour();
                    if (currentHour != lastHour) {
                      Serial.println( "Resyncing hour" );
                      requestTime(); // sync the time every hour
                      wait( MS_WAIT );
                      lastHour = currentHour;
                      sendRainVolumeData(); // Send heart beat
                    }
                  
                  checkThresholdedSensors( readSensorValue, updatedSensorValue );
                  
                  
                  }
                  
                  void sensorTipped() {
                    unsigned long thisTipTime = millis();
                    if (thisTipTime - lastTipTime > 100UL) {
                      wasTippedCounter++;
                    }
                    lastTipTime = thisTipTime;
                  }
                  
                  float dhtHumidity; 
                  
                  void readSensorValue( uint8_t aSensorId, ThreshHoldedSensorType aType, float *value ) {
                    switch ( aSensorId ) {    
                        case DHT_TEMP:
                        if ( aType == TEMPERATURE_SENSOR ) {
                          *value = dht.getTemperature();
                        }
                        break;
                        case DHT_HUM:
                        if ( aType == HUMIDTY_SENSOR ) {
                          *value = dht.getHumidity();
                        }
                        break;
                    }
                  }
                  
                  void updatedSensorValue( uint8_t child_id, uint8_t sensor_id, ThreshHoldedSensorType sensor_type, float value ) {
                    switch ( child_id ) {
                        case CHILD_ID_TEMP: 
                        Serial.print( "Temperatur " ); 
                        Serial.print( value, 0 ); 
                        Serial.print( "C" ); 
                        send( msgTemp.set( value, 1 ) );
                        wait( MS_WAIT );
                        break;
                      case CHILD_ID_HUMIDITY: 
                        Serial.print( "HUMIDITY " ); 
                        Serial.print( value, 0 ); 
                        Serial.print( "%" ); 
                        send( msgHum.set( value, 1 ) );
                        wait( MS_WAIT );
                        break;  
                     
                    }
                  }
                  
                  void receiveTime(unsigned long time) {
                    Serial.println( F("Time received..."));
                    setTime(time);
                    char theTime[6];
                    sprintf(theTime, "%d:%2d", hour(), minute());
                    Serial.println(theTime);
                  }
                  
                  void receive(const MyMessage &message) {
                    if ( message.sensor == CHILD_ID_RAIN_LOG && message.type == V_VAR1) { // We only expect pulse count values from the gateway
                      hwPulseCounter = message.getULong();
                      wasTippedCounter = hwPulseCounter;
                      pcReceived = true;
                  
                      Serial.print("Received last pulse count from gw: ");
                      Serial.println(hwPulseCounter);
                    }
                  } 
                  
                  1 Reply Last reply
                  0
                  • J Offline
                    J Offline
                    JCH
                    wrote on last edited by
                    #59

                    Hi
                    I am using this sketch on my battery powered rain gauge but have noticed the gauge never resets, how are you managing this? i am using Vera as a controller

                    sundberg84S 1 Reply Last reply
                    0
                    • J JCH

                      Hi
                      I am using this sketch on my battery powered rain gauge but have noticed the gauge never resets, how are you managing this? i am using Vera as a controller

                      sundberg84S Offline
                      sundberg84S Offline
                      sundberg84
                      Hardware Contributor
                      wrote on last edited by
                      #60

                      @jch I made this just because the standard sketch didn't work with domoticz. The example sketch should work with Vera. It's been a long time now since I made this so thing might changed.

                      Controller: Proxmox VM - Home Assistant
                      MySensors GW: Arduino Uno - W5100 Ethernet, Gw Shield Nrf24l01+ 2,4Ghz
                      MySensors GW: Arduino Uno - Gw Shield RFM69, 433mhz
                      RFLink GW - Arduino Mega + RFLink Shield, 433mhz

                      1 Reply Last reply
                      0
                      • J Offline
                        J Offline
                        JCH
                        wrote on last edited by
                        #61

                        Ok thanks for the reply.... I was only wanting to use your sketch as my node is battery powered and the mysensors example uses a lot of power as it doesn't sleep.
                        I will try and modify it.

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


                        19

                        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