Reading a tipping bucket rain gauge

I have a tipping bucket rain gauge (similar to that pictured) that sends a pulse to ESP8266 every time the bucket fills and seesaws past the reed switch. My problem is that Blynk only catches the pulse randomly even though I have a timer set to fire every 10 ms. This is the part of the code that controls it.

timer.setInterval(10L,rain); // set interval to read rain gauge

void rain(){
    int buttonState = digitalRead(rainGauge);
  // print out the state of the button:
//  Serial.println(buttonState);
  if(buttonState==LOW) // it is raining
  { 
      rainAmount = .3; //amount of rain with each bucket tip in gauge
      totalAmount += rainAmount; //running total of rain that has fallen
      Blynk.virtualWrite(V13,totalAmount); // send rain amount to Blynk app
      Serial.print("this is the total rain that has fallen ");
      Serial.print(totalAmount);
      Serial.println(" mm");
  }

It seems like the Blynk app is not quick enough to catch all the pulses as the magnet swings past the reed switch. How fast can I set the timer before problems arise or am I going about it the wrong way?

move the reed switch seems like a simple solution…

Not sure I follow you. The reed switch is encapsulated in a fixed position, the magnet is the moving part.

move the “fixed position” to a side - not the centre.

then when the magnet stops there, it stays 100% on, you can read it much better if it is stationary when it sends the signal.

then when it is off, it means the magnet has moved (to the other side)

you could also consider using a Hall effect sensor…

OK, I see what you mean now but those solutions come with more problems. The rain gauge is from a weather station that is no longer in use and I was hoping to be able to use it as is. To try and move the reed switch or change it to a Hall Effect sensor means that I would have to break open the compartment holding the reed switch as it is totally sealed against the weather. Before connecting it to Blynk I had it running on a Nano and it was able to read every pulse perfectly so I was hoping for an easy changeover to Blynk. Thanks for your suggestions though, I will have a think about what you say and see if it is doable.

Why not use an interrupt? https://www.arduino.cc/en/Reference/AttachInterrupt it’s the go-to solution for a setup like this.

Your issue has nothing to do with Blynk itself. First of all - sending 100 req/sec for ESP8266 is very hard task, it will drop connection because ESP cannot handle such high (and that’s why we have limit in blynk library) request rate (yes, we did tests). ESP8266 can send ~10-20 req/sec only. No more. So recommended interval for timer would be 100. Or change your hardware.

@Dmitriy
I realise that sending 100 req/sec is too many, that was simply there for testing purposes. Although the connection never dropped at that timing rate I also tried various other rates including 10 req/sec but none have so far worked. An interrupt as @Nanite suggested might work so will give that a try. Not sure why I would want to change my hardware at this early stage, not ready to give up on it yet.

Because we have limit in library as I said before.

If you need to send 100 req/sec you have to. But I don’t know your needs.

I thought I had explained that in my first post. However from your answers it is clear that my rain gauge probably won’t work with Blynk but I will keep trying :slight_smile:

Why is that?

The gauge doesn’t work reliably with the recommended interval so your advice was to change my hardware. I take that to mean that my rain gauge probably won’t work with Blynk.

Because this is hardware issue. You can’t send 100 req/sec from your hardware. So it is logical that gague can’t show 100 req/sec as you don’t send 100 req/sec :slight_smile:.

I think the problem here is that I’m talking about data you try send to blynk and you are talking about reading rain gauge value. If you’ll separate this functions it would be easier to follow.

Set your polling timer as short as you need it to be - how about 1ms? 100us? But don’t send the rain-gauge triggers; count them.

Create a Blynk-update timer and set to say, 3 seconds. When ever it fires, send and clear the trigger count.

Adjust the times to suit your application and the flooding-limits of Blynk.

1 Like

You don’t have to send values with this resolution. Have 2 functions: one detects events and counts them, second updates the data in the cloud and in the app.

Think like an engineer :wink:

1 Like

And debounce your reed switch. I’ve been using reed switches for the past year for a couple different projects (driving very small 1:87 scale cars for one …) and I’ve found out you gonna need at least a simple debounce circuit with a capacitor and one or two resistors. An added diode would makes things even more reliable. Connect the whole bunch to a setup with interrupts and you are good to go.

Why are you even using a timer?

This hall sensor isnt sending a tonne of data…the bucket takes a few seconds to a few minutes to fill up?

void setup(){
  int prevButtonState = HIGH; // not sure if you have NO/NC type sensor but assuming its NC
rainAmount = .3; // put this here to make the function a teeny bit faster
}

void rain(){
  int buttonState = digitalRead(rainGauge);
  
  if(buttonState == LOW && prevButtonState == HIGH) // it just went passed the sensor and tipped the bucket so now do one action only so you dont cause a flood error on Blynk
  { 
      prevButtonState = LOW;
      totalAmount += rainAmount; //running total of rain that has fallen
      Blynk.virtualWrite(V13,totalAmount); // send rain amount to Blynk app
  }

if(buttonState == HIGH && prevButtonState == LOW) { //reset for next bucket tip or send a secondary virtWrite or slow serial commands
     
     prevButtonState = HIGH;
     Serial.print("this is the total rain that has fallen ");
      Serial.print(totalAmount);
      Serial.println(" mm");
}


void loop(){
  rain(); // add this in to the loop
}

This will probably go wrong if you do it like this. That’s why he’s using a timer.

You either use a timer or use an interrupt with debouncing.

Could you explain why? Maybe my understanding of the way the hardware works is incorrect.

Shamelessly added in from the original WIMP station - more on that here for reference: https://github.com/sparkfun/Wimp_Weather_Station

This was one of the few sections of code that i hardly touched, it just works - you may need to read up on the available interrupts on the ESP8266’es.

here is the code i use for my rain bucket - I use an Arduino to process the data and an ESP to send it via MQTT to blynk, but there is no reason this will not work directly on the ESP.

 >    //Interrupt routines (these are called by the hardware interrupts, not by the main code)
>     //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
>     void rainIRQ()
>     // Count rain gauge bucket tips as they occur
>     // Activated by the magnet and reed switch in the rain gauge, attached to input D2
>     {
>       raintime = millis(); // grab current time
>       raininterval = raintime - rainlast; // calculate interval between this and last event

>       if (raininterval > 10) // ignore switch-bounce glitches less than 10mS after initial edge
>       {
>         dailyrainin += 0.2794; //Each dump is 0.011" of water
>         rainHour[minutes] += 0.011; //Increase this minute's amount of rain

>         rainlast = raintime; // set up for next event
>       }
>     }

The int is called later in the code as follows:

attachInterrupt(0, rainIRQ, FALLING);

Only reason i moved this off the ESP was trying to keep track of windspeed, DHT22, BMP085, rain bucket and RTC was too much for it to handle.

2 Likes