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.
  • TheoLT TheoL

    @AWI do you happen to know if the pulse counter in Domoticz is a 1mm pulse counter? Or is it a real tip pulse counter? Right know where checking whenever the rain fall exceeds 1mm and send a pulse ++ in that case. Meaning we miss some pulse counts when we reset the node.

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

    @TheoL My rain meter counts in 1 mm resolution but I am sending actual total (in mm) from the start of sensor and keep totals in EEPROM.

    TheoLT 1 Reply Last reply
    0
    • AWIA AWI

      @TheoL My rain meter counts in 1 mm resolution but I am sending actual total (in mm) from the start of sensor and keep totals in EEPROM.

      TheoLT Offline
      TheoLT Offline
      TheoL
      Contest Winner
      wrote on last edited by
      #19

      @AWI (Glad that your back, hope you're doing allright) So, if I understand your setup correctly you don't send the pulse count to Domoticz? I kind of like it, because that way I can reset the rain sensor many times and still keep the rain fall log in sync, without using the EPROM.

      And my rain sensor did reset a couple of times. I had to put a diode (Dutch name is blus diode) between the two wires coming out from the rain gauge to prevent this.

      AWIA 1 Reply Last reply
      0
      • TheoLT TheoL

        @AWI (Glad that your back, hope you're doing allright) So, if I understand your setup correctly you don't send the pulse count to Domoticz? I kind of like it, because that way I can reset the rain sensor many times and still keep the rain fall log in sync, without using the EPROM.

        And my rain sensor did reset a couple of times. I had to put a diode (Dutch name is blus diode) between the two wires coming out from the rain gauge to prevent this.

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

        @TheoL (i'm fine, thank you) That is what i'm doing. The only thing what I need to do after a reset is delete the miscalculation in Domoticz (easy). My sensor (oregon) uses a 'reed' switch (no induction). I MySensoriz'ed it without losing the original circuitry and function. (so in parallel).

        0_1475422212074_upload-82d166bf-a999-4d76-b3e3-8c010fa5f427

        TheoLT 1 Reply Last reply
        0
        • AWIA AWI

          @TheoL (i'm fine, thank you) That is what i'm doing. The only thing what I need to do after a reset is delete the miscalculation in Domoticz (easy). My sensor (oregon) uses a 'reed' switch (no induction). I MySensoriz'ed it without losing the original circuitry and function. (so in parallel).

          0_1475422212074_upload-82d166bf-a999-4d76-b3e3-8c010fa5f427

          TheoLT Offline
          TheoLT Offline
          TheoL
          Contest Winner
          wrote on last edited by TheoL
          #21

          @AWI A lesson learned a couple of month ago. When using an induction reed switch (some of them have a coil around the glass) always add a reversed diode. Otherwise the polarity of the reed switch is being turned for just a millisecond which is enough to cause the arduino to reset ;-). I'm still learning a lot about electronics.

          At the moment the diode seems to work. No Arduino resetting for the last couple of hours.

          Regarding to the pulse counter is seems to work perfectly. That way I don't need to store any values on the EPROM, which is something I prefer not to do. I just query the current pulse count from Domoticz when the sensors boots. Sending the total amount of rain is as easy as pulse count * bucket size. Not real rocket science.

          1 Reply Last reply
          0
          • sundberg84S sundberg84

            @TheoL - If you modify the sketch with a heartbeat() please post it :) Im interested as well!

            TheoLT Offline
            TheoLT Offline
            TheoL
            Contest Winner
            wrote on last edited by TheoL
            #22

            @sundberg84 Here's the first version of the sketch. Note that I don't use the sleep. My main goal for creating my own outside weather station is to get rid of the batteries. Because they always same to stop working whenever I'm not at home.

            /*
             Arduino Tipping Bucket Rain Gauge, SI7021 Temperature + Humidity sensor
            
             Created October 2nd 2016
             Author by Theo
            
             This node uses a tipping bucket rain gauge for measuring rain fall. And a si7021 Temperature and Humidity sensor. The logic in
             this sketch might be specific for Domoticz, because of the Pulse counter.
            
             Based upon sketches created by @BulldogLowell / @PeteWill, @sundber84
             for free public use
            
             Hardware used:
             Arduino Pro Mini 3.3V
             buck converter
             nrf24L01+ radio
             100 uf capacitor
             2 10K resistors (for i2c)
             1N007 diode
             MI-SOL Rain Guage 
             SI7021 sensor
            
             Version history:
             02-10-2016 Initial version
            */
            
            /**
               Configure MySensors
            */
            // Enable debug prints
            // #define MY_DEBUG
            
            // 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 <SI7021.h>
            #include <MySensors.h>
            
            /**
               Define constants used by sketch
            */
            #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_HUM  2               // The child id of the humidity sensor
            #define CHILD_ID_TEMP 1               // The child id of the temperature sensor
            #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
            
            /**
               Declare MySensors messages used by the node
            */
            MyMessage msgHum( CHILD_ID_HUM, 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 );
            
            /**
               Declare variables used by the Sketch
            */
            SI7021 humiditySensor; // Declare a SI7021 Temp humidity sensor object
            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
            
            /**
              Present all child's to the gateway and query for the pulse count known by the HA controller.
            */
            void presentation() {
              // Send the sketch version information to the gateway
              sendSketchInfo( SKETCH_INFO, SKETCH_VERSION );
            
              wait( MS_WAIT );
              // Register all sensors to gw (they will be created as child devices)
              present( CHILD_ID_HUM, S_HUM, "Outside temperature" );
              wait( MS_WAIT );
              present( CHILD_ID_TEMP, S_TEMP, "Outside humidity" );
              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
            }
            
            /**
               Setup of the sketch. It initializes all sensors and queries the gateway for the current time.
            */
            void setup() {
              Serial.begin( 115200 );
              pinMode( BUCKET_PIN, INPUT_PULLUP );
            
              humiditySensor.begin();
            
              registerThresholdedSensor( CHILD_ID_TEMP, 1, TEMPERATURE_SENSOR, 0.5, 30, 20 );
              registerThresholdedSensor( CHILD_ID_HUM, 2, HUMIDTY_SENSOR, 2.0, 30, 20 );
            
              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 );
            }
            
            /**
              Main loop of the node. It checks:
              - whether the rain gauge bucket has been tipped.
              - whether the hourly heartbeat needs to be send.
              - checks all thresholded sensors
            */
            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( readTHSensor, updatedTHSensorValue );
            }
            
            /**
              Interrupt handler for handling bucket tips.
            */
            void sensorTipped() {
              unsigned long thisTipTime = millis();
              if (thisTipTime - lastTipTime > 100UL) {
                wasTippedCounter++;
              }
              lastTipTime = thisTipTime;
            }
            
            /**
              Threshold util wants to know the current value of a specific sensor.
            */
            void readTHSensor( uint8_t aSensorId, ThreshHoldedSensorType aType, float *value ) {
              si7021_env data = humiditySensor.getHumidityAndTemperature();
              switch ( aSensorId ) {
                case CHILD_ID_TEMP:
                  *value = data.celsiusHundredths / 100.0;
                  break;
                case CHILD_ID_HUM:
                  *value = data.humidityPercent;
                  break;
              }
            }
            
            /**
              Threshhold util detects that the value of a specific sensor needs to be send to the gateway.
            */
            void updatedTHSensorValue( uint8_t child_id, uint8_t sensor_id, ThreshHoldedSensorType sensor_type, float value ) {
              switch ( child_id ) {
                case CHILD_ID_TEMP:
                  Serial.print( "Sending temp " );
                  Serial.println( value, 1 );
                  send( msgTemp.set( value, 1 ) );
                  wait( MS_WAIT );
                  break;
                case CHILD_ID_HUM:
                  Serial.print( "Sending Humidity " );
                  Serial.println( value, 1 );
                  send( msgHum.set( value, 1 ) );
                  wait( MS_WAIT );
                  break;
              }
            }
            
            /**
              Call back handler for handling time send by the gateway.
            */
            void receiveTime(unsigned long time) {
              Serial.println( F("Time received..."));
              setTime(time);
              char theTime[6];
              sprintf(theTime, "%d:%2d", hour(), minute());
              Serial.println(theTime);
            }
            
            /**
              Callback handler for handling incomming MySensors message.
            */
            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);
              }
            }
            

            ps. Because the old MySensors API's where removed from the main page, I had to move over to MySensors 2.0. I just uploaded the MySensors 2.0 to my serial gateway and everything seems to work fine. With this I mean all MySensors 1.5 node's are still doing their work. Love it!

            EDITED: Added rain rate. But still testing.

            1 Reply Last reply
            0
            • TheoLT Offline
              TheoLT Offline
              TheoL
              Contest Winner
              wrote on last edited by
              #23

              @AWI last question for today. Do you send the rain rate to domoticz as well? Still figuring out how to do this.

              sundberg84S F 2 Replies Last reply
              0
              • TheoLT TheoL

                @AWI last question for today. Do you send the rain rate to domoticz as well? Still figuring out how to do this.

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

                @TheoL - No I dont, and if i remember right its because i sleep the node I cant do the calculations.

                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

                TheoLT 1 Reply Last reply
                0
                • sundberg84S sundberg84

                  @TheoL - No I dont, and if i remember right its because i sleep the node I cant do the calculations.

                  TheoLT Offline
                  TheoLT Offline
                  TheoL
                  Contest Winner
                  wrote on last edited by
                  #25

                  @sundberg84 I've added it. But so far Domoticz doesn't return a value whenever I query a JSON for the sensor. Maybe it does when the clock switches to the next hour.

                  1 Reply Last reply
                  0
                  • TheoLT TheoL

                    @AWI last question for today. Do you send the rain rate to domoticz as well? Still figuring out how to do this.

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

                    @TheoL said:

                    @AWI last question for today. Do you send the rain rate to domoticz as well? Still figuring out how to do this.

                    Domoticz have some sort of rain rate, not like mm/12h, mm/6h but it will give mm/h depending how you send data to Domoticz it will be more or less correct.
                    0_1475427368240_IMG_2992.PNG

                    TheoLT 1 Reply Last reply
                    0
                    • F flopp

                      @TheoL said:

                      @AWI last question for today. Do you send the rain rate to domoticz as well? Still figuring out how to do this.

                      Domoticz have some sort of rain rate, not like mm/12h, mm/6h but it will give mm/h depending how you send data to Domoticz it will be more or less correct.
                      0_1475427368240_IMG_2992.PNG

                      TheoLT Offline
                      TheoLT Offline
                      TheoL
                      Contest Winner
                      wrote on last edited by
                      #27

                      @flopp Thank you. What do you mean by sending data correctly? Do you have an example sketch?

                      F 1 Reply Last reply
                      0
                      • TheoLT TheoL

                        @flopp Thank you. What do you mean by sending data correctly? Do you have an example sketch?

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

                        @TheoL said:

                        @flopp Thank you. What do you mean by sending data correctly? Do you have an example sketch?

                        Not correctly, I wrote depending.

                        If you send data every 2 hours and ot every time the buck has tiped the rate will not be correct. Lets say you send/report every 2 hour, you report 10 mm, that means you have "collect" 10 mm for 2 hours. Maybe the hour was not raining, then the rate will show you 10mm/h, sorry if I confusing you.

                        What I mean is that you should send/report directly when the buck has tiped then the rate in DZ will be correct rate/h.

                        my sketch

                        #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 BATT_CHILD 2
                        #define NODE_ID AUTO // or AUTO to let controller assign
                        #define SKETCH_NAME "Rain Gauge" // Change to a fancy name you like
                        #define SKETCH_VERSION "1.8" // Your version
                        
                        unsigned long SLEEP_TIME = 180*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.
                        
                        MySensor gw;
                        MyMessage volumeMsg(CHILD_ID,V_RAIN);
                        MyMessage lastCounterMsg(CHILD_ID,V_VAR1);
                        MyMessage battMsg(BATT_CHILD, 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
                        //=========================
                        */
                        
                        long result;
                        float batteryPcnt;
                        float batteryVolt;
                        
                        void setup() 
                        { 
                        pinMode(6,OUTPUT);
                        digitalWrite(6,HIGH);
                        // 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
                        
                        delay(500); // Allow time for radio if power used as reset
                        
                        //Begin (Change if you dont want static node_id! (NODE_ID to AUTO)
                        gw.begin(incomingMessage, NODE_ID, false);
                        
                        // Send the Sketch Version Information to the Gateway
                        gw.sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);
                        
                        // Register this device as Rain sensor (will not show in Domoticz until first value arrives)
                        gw.present(CHILD_ID, S_RAIN); 
                        gw.present(BATT_CHILD, S_MULTIMETER);
                        
                        Serial.println("Startup completed");
                        }
                        
                        void loop() 
                        { 
                        
                        digitalWrite(6,HIGH);
                        delay(100);
                        
                        gw.process();
                        //gw.begin(incomingMessage, NODE_ID, false);
                        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)) { 
                        gw.begin(incomingMessage, NODE_ID, false);
                        gw.request(CHILD_ID, V_VAR1);
                        Serial.println("Request pulsecount");
                        lastSend=currentTime;
                        gw.process();
                        return;
                        }
                        if (!pcReceived) {
                        return;
                        }
                        
                        //Read if the bucket tipped over
                        reedState = digitalRead(DIGITAL_INPUT_SENSOR);
                        boolean tipped = oldReedState != reedState; 
                        
                        //BUCKET TIPS!
                        if (tipped==true) {
                        gw.begin(incomingMessage, NODE_ID, false);
                        Serial.println("The bucket has tipped over...");
                        oldReedState = reedState;
                        hwRainVolume = hwRainVolume + bucketSize;
                        gw.send(volumeMsg.set((float)hwRainVolume,1));
                        gw.wait(1000);
                        fullCounter = fullCounter + bucketSize;
                        
                        //Count so we send the counter for every 1mm
                        if(fullCounter >= 1){
                        hwPulseCounter++;
                        gw.send(lastCounterMsg.set(hwPulseCounter));
                        gw.wait(1000);
                        fullCounter = 0;
                        }
                        readVcc(); 
                        }
                        
                        if (tipped==false) {
                        
                        //No bucket tipped over last sleep-period, check battery then...
                        readVcc(); 
                        }
                        
                        lastSend=currentTime;
                        Serial.println("sleep");
                        digitalWrite(6,LOW);
                        delay(1000);
                        gw.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 incomingMessage(const MyMessage &message) {
                        if (message.type==V_VAR1) {
                        hwPulseCounter = message.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(" %");
                        gw.sendBatteryLevel(batteryPcnt);
                        batLoop = 0;
                        
                        //Sends 1 per hour as a heartbeat.
                        gw.send(volumeMsg.set((float)hwRainVolume,1));
                        gw.send(lastCounterMsg.set(hwPulseCounter));
                        }
                        else 
                        {
                        batLoop++;
                        }
                        }
                        */
                        long 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
                        //return result;
                        gw.begin(incomingMessage, NODE_ID, false);
                        batteryPcnt = (result - 3300) * 0.111111;
                        batteryVolt = result/1000.000;
                        gw.sendBatteryLevel(batteryPcnt);
                        gw.send(battMsg.set(batteryVolt, 3));
                        /*Serial.print("battery volt:");
                        Serial.println(batteryVolt, 3);
                        Serial.print("battery percent:");
                        Serial.println(batteryPcnt);
                        */
                        }
                        
                        TheoLT 1 Reply Last reply
                        1
                        • F flopp

                          @TheoL said:

                          @flopp Thank you. What do you mean by sending data correctly? Do you have an example sketch?

                          Not correctly, I wrote depending.

                          If you send data every 2 hours and ot every time the buck has tiped the rate will not be correct. Lets say you send/report every 2 hour, you report 10 mm, that means you have "collect" 10 mm for 2 hours. Maybe the hour was not raining, then the rate will show you 10mm/h, sorry if I confusing you.

                          What I mean is that you should send/report directly when the buck has tiped then the rate in DZ will be correct rate/h.

                          my sketch

                          #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 BATT_CHILD 2
                          #define NODE_ID AUTO // or AUTO to let controller assign
                          #define SKETCH_NAME "Rain Gauge" // Change to a fancy name you like
                          #define SKETCH_VERSION "1.8" // Your version
                          
                          unsigned long SLEEP_TIME = 180*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.
                          
                          MySensor gw;
                          MyMessage volumeMsg(CHILD_ID,V_RAIN);
                          MyMessage lastCounterMsg(CHILD_ID,V_VAR1);
                          MyMessage battMsg(BATT_CHILD, 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
                          //=========================
                          */
                          
                          long result;
                          float batteryPcnt;
                          float batteryVolt;
                          
                          void setup() 
                          { 
                          pinMode(6,OUTPUT);
                          digitalWrite(6,HIGH);
                          // 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
                          
                          delay(500); // Allow time for radio if power used as reset
                          
                          //Begin (Change if you dont want static node_id! (NODE_ID to AUTO)
                          gw.begin(incomingMessage, NODE_ID, false);
                          
                          // Send the Sketch Version Information to the Gateway
                          gw.sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);
                          
                          // Register this device as Rain sensor (will not show in Domoticz until first value arrives)
                          gw.present(CHILD_ID, S_RAIN); 
                          gw.present(BATT_CHILD, S_MULTIMETER);
                          
                          Serial.println("Startup completed");
                          }
                          
                          void loop() 
                          { 
                          
                          digitalWrite(6,HIGH);
                          delay(100);
                          
                          gw.process();
                          //gw.begin(incomingMessage, NODE_ID, false);
                          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)) { 
                          gw.begin(incomingMessage, NODE_ID, false);
                          gw.request(CHILD_ID, V_VAR1);
                          Serial.println("Request pulsecount");
                          lastSend=currentTime;
                          gw.process();
                          return;
                          }
                          if (!pcReceived) {
                          return;
                          }
                          
                          //Read if the bucket tipped over
                          reedState = digitalRead(DIGITAL_INPUT_SENSOR);
                          boolean tipped = oldReedState != reedState; 
                          
                          //BUCKET TIPS!
                          if (tipped==true) {
                          gw.begin(incomingMessage, NODE_ID, false);
                          Serial.println("The bucket has tipped over...");
                          oldReedState = reedState;
                          hwRainVolume = hwRainVolume + bucketSize;
                          gw.send(volumeMsg.set((float)hwRainVolume,1));
                          gw.wait(1000);
                          fullCounter = fullCounter + bucketSize;
                          
                          //Count so we send the counter for every 1mm
                          if(fullCounter >= 1){
                          hwPulseCounter++;
                          gw.send(lastCounterMsg.set(hwPulseCounter));
                          gw.wait(1000);
                          fullCounter = 0;
                          }
                          readVcc(); 
                          }
                          
                          if (tipped==false) {
                          
                          //No bucket tipped over last sleep-period, check battery then...
                          readVcc(); 
                          }
                          
                          lastSend=currentTime;
                          Serial.println("sleep");
                          digitalWrite(6,LOW);
                          delay(1000);
                          gw.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 incomingMessage(const MyMessage &message) {
                          if (message.type==V_VAR1) {
                          hwPulseCounter = message.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(" %");
                          gw.sendBatteryLevel(batteryPcnt);
                          batLoop = 0;
                          
                          //Sends 1 per hour as a heartbeat.
                          gw.send(volumeMsg.set((float)hwRainVolume,1));
                          gw.send(lastCounterMsg.set(hwPulseCounter));
                          }
                          else 
                          {
                          batLoop++;
                          }
                          }
                          */
                          long 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
                          //return result;
                          gw.begin(incomingMessage, NODE_ID, false);
                          batteryPcnt = (result - 3300) * 0.111111;
                          batteryVolt = result/1000.000;
                          gw.sendBatteryLevel(batteryPcnt);
                          gw.send(battMsg.set(batteryVolt, 3));
                          /*Serial.print("battery volt:");
                          Serial.println(batteryVolt, 3);
                          Serial.print("battery percent:");
                          Serial.println(batteryPcnt);
                          */
                          }
                          
                          TheoLT Offline
                          TheoLT Offline
                          TheoL
                          Contest Winner
                          wrote on last edited by
                          #29

                          @flopp Thank you for the explanation. I think I've got it.

                          I've added a RAINRATE msg like this
                          MyMessage rainRateMsg( CHILD_ID_RAIN_LOG, V_RAINRATE );

                          But I don't think domoticz uses it.

                          F 1 Reply Last reply
                          0
                          • TheoLT Offline
                            TheoLT Offline
                            TheoL
                            Contest Winner
                            wrote on last edited by
                            #30

                            @sundberg84 Using a real pulse counter instead of a 1mm pulse counter seems to work perfectly. Luckily it makes the sketch a bunch easier to implement and read. And there will also be no loss of 0.2 or 0.5 mm rain fall whenever you reset the node while it didn't have a .0 value.

                            BulldogLowellB 1 Reply Last reply
                            2
                            • TheoLT TheoL

                              @flopp Thank you for the explanation. I think I've got it.

                              I've added a RAINRATE msg like this
                              MyMessage rainRateMsg( CHILD_ID_RAIN_LOG, V_RAINRATE );

                              But I don't think domoticz uses it.

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

                              @TheoL RAINRATE is implemented according to this page https://github.com/domoticz/domoticz/blob/master/hardware/MySensorsBase.cpp but I don't know how to use it. I know that DZ doesn't work with this example https://www.mysensors.org/build/rain

                              1 Reply Last reply
                              0
                              • F Offline
                                F Offline
                                flopp
                                wrote on last edited by flopp
                                #32

                                I have adjust my bucked to tip every ~0.25mm and calibrated it ofcourse

                                AWIA 1 Reply Last reply
                                0
                                • F flopp

                                  I have adjust my bucked to tip every ~0.25mm and calibrated it ofcourse

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

                                  Domoticz just recently changed the method of rain rate calculation. It does not interpret rainrate values sent by sensors but calculates this by the total value coming in.

                                  TheoLT 1 Reply Last reply
                                  0
                                  • AWIA AWI

                                    Domoticz just recently changed the method of rain rate calculation. It does not interpret rainrate values sent by sensors but calculates this by the total value coming in.

                                    TheoLT Offline
                                    TheoLT Offline
                                    TheoL
                                    Contest Winner
                                    wrote on last edited by
                                    #34

                                    @AWI Thank you again. I already had a gut feeling this would be the case. I'll strip out the rain rate code from the sketch.

                                    1 Reply Last reply
                                    0
                                    • TheoLT TheoL

                                      @sundberg84 Using a real pulse counter instead of a 1mm pulse counter seems to work perfectly. Luckily it makes the sketch a bunch easier to implement and read. And there will also be no loss of 0.2 or 0.5 mm rain fall whenever you reset the node while it didn't have a .0 value.

                                      BulldogLowellB Offline
                                      BulldogLowellB Offline
                                      BulldogLowell
                                      Contest Winner
                                      wrote on last edited by
                                      #35

                                      @TheoL

                                      Great to see this project continuing to grow legs!

                                      1 Reply Last reply
                                      0
                                      • HilltanH Offline
                                        HilltanH Offline
                                        Hilltan
                                        wrote on last edited by
                                        #36
                                        This post is deleted!
                                        1 Reply Last reply
                                        0
                                        • sundberg84S sundberg84

                                          This is great!
                                          1 year - times fly by, but my rainsensor is going strong!

                                          I just wanted to celebrate 1 year for my Rainsensor on batteries, reporting every hour (or less when it rains). Still going strong and 81% battery left! Except for some range issues in the beginning you can see its working as it should:

                                          Also It will be my (almost) 1000th post so thank you all for making MySensors such a great community. I just love every minute here!

                                          0_1474871808445_1.jpg

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

                                          @sundberg84 said:

                                          I just wanted to celebrate 1 year for my Rainsensor on batteries, reporting every hour (or less when it rains). Still going strong and 81% battery left! Except for some range issues in the beginning you can see its working as it should:

                                          WOW, nice. Would it be possible to see your Battery graph, if you have one?
                                          I am send data every 2h or often when it rains but my battery is draining much quicker than yours. Maybe I will get 1 year out of it, so I am happy anyway.
                                          But I am interested in your graph if the voltage is going down quicker in the beginning.

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


                                          23

                                          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