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. Troubleshooting
  3. Rain Gauge, error double send/trigger [SOLVED]

Rain Gauge, error double send/trigger [SOLVED]

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

    I have tried many hours now, please help me.
    I have same code on a second rain gauge and it works perfect. But on this it is not working.
    When it is tipping it triggers the Node twice and Node sends data twice, 95 of 100 times, and it will be double amount of rain.
    What is wrong? How can I add some kind of delay between triggers, it is sleeping so millis doesn't work.
    If I use gw.wait or gw.sleep it will only work first tip and then it will send same value every time the it tipped
    Version 1.5.1. Node is Pro Mini with Low power Bootloader

    Serial printout, when I tipped it once, without gw.sleep ot gw.wait

    send: 29-29-0-0 s=255,c=0,t=17,pt=0,l=5,sg=0,st=ok:1.5.1
    send: 29-29-0-0 s=255,c=3,t=6,pt=1,l=1,sg=0,st=ok:0
    read: 0-0-29 s=255,c=3,t=6,pt=0,l=1,sg=0:M
    sensor started, id=29, parent=0, distance=1
    send: 29-29-0-0 s=255,c=3,t=11,pt=0,l=10,sg=0,st=ok:Rain Gauge
    send: 29-29-0-0 s=255,c=3,t=12,pt=0,l=4,sg=0,st=ok:1.83
    send: 29-29-0-0 s=1,c=0,t=10,pt=0,l=0,sg=0,st=ok:
    send: 29-29-0-0 s=2,c=0,t=30,pt=0,l=0,sg=0,st=ok:
    Startup completed
    send: 29-29-0-0 s=1,c=2,t=24,pt=0,l=0,sg=0,st=ok:
    Request pulsecount
    read: 0-0-29 s=1,c=2,t=24,pt=0,l=6,sg=0:125.75
    Received last pulse count from gw: 125.75
    send: 29-29-0-0 s=1,c=1,t=6,pt=7,l=5,sg=0,st=ok:125.75
    readVcc
    send: 29-29-0-0 s=255,c=3,t=0,pt=1,l=1,sg=0,st=ok:6
    send: 29-29-0-0 s=2,c=1,t=38,pt=7,l=5,sg=0,st=ok:3.362
    sleep
    The bucket has tipped over...
    send: 29-29-0-0 s=1,c=1,t=24,pt=7,l=5,sg=0,st=ok:126.00
    send: 29-29-0-0 s=1,c=1,t=6,pt=7,l=5,sg=0,st=ok:126.00
    readVcc
    send: 29-29-0-0 s=255,c=3,t=0,pt=1,l=1,sg=0,st=ok:6
    send: 29-29-0-0 s=2,c=1,t=38,pt=7,l=5,sg=0,st=ok:3.362
    sleep
    The bucket has tipped over...
    send: 29-29-0-0 s=1,c=1,t=24,pt=7,l=5,sg=0,st=ok:126.25
    send: 29-29-0-0 s=1,c=1,t=6,pt=7,l=5,sg=0,st=ok:126.25
    readVcc
    send: 29-29-0-0 s=255,c=3,t=0,pt=1,l=1,sg=0,st=ok:6
    send: 29-29-0-0 s=2,c=1,t=38,pt=7,l=5,sg=0,st=ok:3.362
    sleep
    
    

    If I use gw.wait or gw.sleep between

    lastSend=currentTime;
    gw.wait(1000);
    Serial.println("sleep");
    

    it look like after two tippings

    send: 29-29-0-0 s=255,c=0,t=17,pt=0,l=5,sg=0,st=ok:1.5.1
    send: 29-29-0-0 s=255,c=3,t=6,pt=1,l=1,sg=0,st=ok:0
    read: 0-0-29 s=255,c=3,t=6,pt=0,l=1,sg=0:M
    sensor started, id=29, parent=0, distance=1
    send: 29-29-0-0 s=255,c=3,t=11,pt=0,l=10,sg=0,st=ok:Rain Gauge
    send: 29-29-0-0 s=255,c=3,t=12,pt=0,l=4,sg=0,st=ok:1.83
    send: 29-29-0-0 s=1,c=0,t=10,pt=0,l=0,sg=0,st=ok:
    send: 29-29-0-0 s=2,c=0,t=30,pt=0,l=0,sg=0,st=ok:
    Startup completed
    send: 29-29-0-0 s=1,c=2,t=24,pt=0,l=0,sg=0,st=ok:
    Request pulsecount
    read: 0-0-29 s=1,c=2,t=24,pt=0,l=6,sg=0:126.25
    Received last pulse count from gw: 126.25
    send: 29-29-0-0 s=1,c=1,t=6,pt=7,l=5,sg=0,st=ok:126.25
    readVcc
    send: 29-29-0-0 s=255,c=3,t=0,pt=1,l=1,sg=0,st=ok:6
    send: 29-29-0-0 s=2,c=1,t=38,pt=7,l=5,sg=0,st=ok:3.362
    sleep
    The bucket has tipped over...
    send: 29-29-0-0 s=1,c=1,t=24,pt=7,l=5,sg=0,st=ok:126.50
    send: 29-29-0-0 s=1,c=1,t=6,pt=7,l=5,sg=0,st=ok:126.50
    readVcc
    send: 29-29-0-0 s=255,c=3,t=0,pt=1,l=1,sg=0,st=ok:6
    send: 29-29-0-0 s=2,c=1,t=38,pt=7,l=5,sg=0,st=ok:3.362
    sleep
    send: 29-29-0-0 s=1,c=1,t=6,pt=7,l=5,sg=0,st=ok:126.50
    readVcc
    send: 29-29-0-0 s=255,c=3,t=0,pt=1,l=1,sg=0,st=ok:6
    send: 29-29-0-0 s=2,c=1,t=38,pt=7,l=5,sg=0,st=ok:3.362
    sleep
    
    

    This is the code

    #include <SPI.h>
    #include <MySensor.h>  
    
    #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.83"                    // Your version
    //1.8 tipping = 0.5mm
    //1.81 tipping = 0.8mm
    //1.82 tipping = 0.25mm
    //1.83 send VAR1 and volt every 2 h
    
    unsigned long SLEEP_TIME = 120*60000;            // Sleep time (in milliseconds).
    //unsigned long SLEEP_TIME = 20000;             // use this instead for debug
    
    float hwRainVolume = 0;                         // Current rainvolume calculated in hardware.
    float bucketSize = 0.25;                           // 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);
    
    long result;
    float batteryPcnt;
    float batteryVolt;
    
    void setup()  
    {  
      
      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()     
    { 
      
    gw.process();
    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.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) {
        Serial.println("The bucket has tipped over...");
        oldReedState = reedState;
        hwRainVolume = hwRainVolume + bucketSize;
        resend((lastCounterMsg.set(hwRainVolume,2)),10);
        }
    
    resend((volumeMsg.set((float)hwRainVolume,2)),10);
    readVcc(); 
    
    lastSend=currentTime;
    
    Serial.println("sleep");
    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 = message.getFloat();
        pcReceived = true;
        Serial.print("Received last pulse count from gw: ");
        Serial.println(hwRainVolume,2);   
      }
    }
    
    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);
      resend((battMsg.set(batteryVolt, 3)),10);
    }
    
    void resend(MyMessage &msg, int repeats)
    {
      int repeat = 1;
      int repeatdelay = 0;
      boolean sendOK = false;
    
      while ((sendOK == false) and (repeat < repeats)) {
        if (gw.send(msg)) {
          sendOK = true;
        } else {
          sendOK = false;
          Serial.print("Error ");
          Serial.println(repeat);
          repeatdelay += 500;
        } repeat++; delay(repeatdelay);
      }
    }
    
    1 Reply Last reply
    0
    • F Offline
      F Offline
      flopp
      wrote on last edited by flopp
      #2

      Debounce is the name for this kind of problem.
      I tried this to add delay after gw.sleep, didn't help. It doesn't "see" that the Interrupt PIN has been HIGH, so it doesn't send to my controller that it has tipped once. This is the code thats get pasted with delay(1000);

      if (tipped==true) {
          Serial.println("The bucket has tipped over...");
          oldReedState = reedState;
          hwRainVolume = hwRainVolume + bucketSize;
          resend((lastCounterMsg.set(hwRainVolume,2)),10);
          }
      

      https://forum.mysensors.org/topic/2625/hardware-debounce/4

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

        SOLVED
        I added delay(1000); here

        resend((lastCounterMsg.set(hwRainVolume,2)),10);
        delay(1000);   
         }
        
        1 Reply Last reply
        0
        Reply
        • Reply as topic
        Log in to reply
        • Oldest to Newest
        • Newest to Oldest
        • Most Votes


        18

        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