In this Instructable we 'construct' a rain gauge with Arduino and calibrate it to report daily and hourly rainfall. The rain collector I am using is a re-purposed rain gauge of the tipping bucket type. It came from a damaged personal weather station. However there are a lot of great Instructables on how to make one from scratch.

This Instructable is a part of a weather station I am making and is a documentation of my learning process disguised as a tutorial:)

Characteristics of the Rain Gauge:

  • measurements of daily and hourly rainfall is in inches for easy upload to Weather Underground.
  • debouncing code for the magnetic switch is not included to keep the code simple.
  • being more of a tutorial the finished product is more of a prototype of a prototype.

Step 1: Some Theory

Rainfall is reported/measured in millimeters or inches which has the dimension of length. It is indicative of how high, every portion of rain area got the rain, if the rain water had not dissipated and drained away. So, a 1.63 mm of rainfall would mean that if I had a flat leveled tank of any shape the rain water collected would be of a height 1.63 mm from the tanks bottom.

All rain gauges have a rainfall catchment area and a rainfall amount measurement. The catchment area is the region over which the rain is collected. The measuring object would be some kind of volume measurement for a liquid.

So the rainfall in mm or inches would be

rainfall height = volume of rain collected / catchment area

In my rain collector, the length and breadth were 11 cm by 5 cm respectively giving a catchment area of 55 sq.cm. So a collection of 9 milliliters of rain would mean 9 cc/55 sq.cm = 0.16363... cm = 1.6363... mm = 0.394 inches.

In the tipping bucket rain gauge, the bucket tips 4 times for 9 ml (or 0.394... inches of rain) and so a single tip is for (9/4) ml = 2.25ml (or 0.0161059413027953.. inches). If we take hourly readings (24 readings per day before resets) keeping three significant digit accuracy is decent enough.

Thus, at each bucket tip/tumble, the code accesses it as 1 on-off-on sequence or one click. Yes, we have reported 0.0161 inches of rain. To repeat, from the Arduino point of view

one click = 0.0161 inches of rain

Note 1: I prefer the International System of Units, but Weather Underground prefers the Imperial/US units and so this conversion into inches.

Note 2: If calculations are not your cup of tea, head over to Volume of Rainfall which provides perfect help for such matters.

Step 2: Parts for This Project

Most of the parts were lying around and a fair listing (for formality) is

  1. Arduino Uno (or any other compatible)
  2. Rain Gauge from old damaged weather station.
  3. Breadboard.
  4. RJ11 to connect my Rain Gauge to the breadboard.
  5. 10K or higher resistor to act as a pull up resistor. I have used 15K.
  6. 2 pieces of male-to-female jumper wires
  7. 2 male-to-male jumper wire.
  8. USB Cable; A Male to B Male


  • Syringe (12 ml capacity was used).

Step 3: The Rain Collector

The photos of my rain collector should make thing clear to many. Anyway, the rain that falls on its catchment area gets channeled to one of the two tipping-buckets inside it. The two tipping-buckets are connected like a see-saw and as the rain water weight ( 0.0161 inches of rain for mine ) tips one bucket down it gets emptied and the other buckets goes up and positions itself to collect the next rain water. The tipping motion moves a magnet over a 'magnetic-switch' and the circuit gets electrically connected.

Step 4: Circuit

To make the circuit

  1. Connect digital pin #2 of Arduino to one end of the resistor.
  2. Connect the other end of the resistor to the Ground pin (GND).
  3. Connect one end of the RJ11 jack to the digital pin #2 of Arduino.
  4. Connect the other end of the RJ11 jack to the +5V pin of Arduino (5V).
  5. Plug the rain gauge to the RJ11.

The circuit is complete. Jumper wires and breadboard make the connections easier to make.

To complete the project connect the Arduino to the PC using the USB cable and load the sketch provided below.

Step 5: The Code

The sketch RainGauge.ino (embedded at the end of this step) is well commented and so I shall point out three sections only.

One part counts the number of tipping-bucket tips.

if(bucketPositionA==false && digitalRead(RainPin) == HIGH){

Another part checks time and computes the rain amount

if(now.minute()==0 && first == true){
	hourlyRain = dailyRain - dailyRain_till_LastHour;

and another part clears the rain for the day, at midnight.

if(now.hour() == 0){
	dailyRain = 0;

Step 6: Calibration & Testing

Disconnect the Rain Collector from the rest of the circuit and perform the following steps.

  1. Fill up the syringe with water. I fill mine with 10 ml.
  2. Keep the Rain Collector on a level surface and pour out the water from the syringe bit by bit.
  3. I keep a count of the tipping buckets. Four tips were enough for me, and drained 9 ml from the syringe. According to calculations (see theory section) I got the amount of 0.0161 inches of rain per tip.
  4. I include this information into my code in the beginning.
const double bucketAmount = 0.0161;

That's all to it. For more accuracy, one can include more digits like 0.01610595. Of course your calculated numbers are expected to vary if your Rain Collector is not identical to mine.

For testing purposes

  1. Connect the Rain Collector to the RJ11 socket.
  2. Connect the Arduino to the PC using the USB cable.
  3. Open the serial monitor.
  4. Pour previously measured amounts of water and observe the output when the hour completes.
  5. Do not pour any water but wait for the next hour to complete. The hourly rain must be zero in this case.
  6. Keep the PC with the connected circuit powered overnight and see if the daily rain and hourly rain get reset to zero at midnight. For this step, one can also change the PC's clock to a suitable value (to watch the outputs on the serial monitor live).

Step 7: Afterthoughts & Acknowledgements

The resolution of the rainfall readings in my case is 0.0161 inches and cannot be made more accurate. Practical circumstances may decrease the accuracy further. Weather measurements do not have the accuracy of quantum mechanics.

Part of the code was borrowed from Lazy Old Geek's Instructable.

<p>Nice to see you re-purpose the rain gauge. I have one in my parts bin for future use.</p><p>Thanks.</p>
<p>Much obliged. </p>
<p>Can you provide the RTC library you are using?</p>
<p>Hi Ahmad,</p><p>Thank you for taking an interest in this Instructable. </p><p>1. I used the adafruit library from github, the link is below. </p><p> <a href="https://github.com/adafruit/RTClib"> https://github.com/adafruit/RTClib</a></p><p>In that page, there is a <em>pink-horizontal-bar</em>. Just below that to the right is the &quot;<strong>Download ZIP</strong>&quot; button. Click there to get the RTC library.</p><p>2. The Wire.h library as seen in <a href="https://www.arduino.cc/en/Reference/Wire"> https://www.arduino.cc/en/Reference/Wire</a><br> has been used to provide connection to the RTC using the two <br>connections SDA and SDC. It is called the I2C protocol. It reduces the <br>connecting wires specially if you have many I2C devices like LCD display<br> with I2C, RTC with I2C, etc. Any device that has pins labelled SDA and <br>SDC uses I2C protocol/procedure 'usually' and for using them the wire.h <br>library must be included in the sketch.</p><p>Do let me know if you need any further clarifications.</p><p>Abhijit</p>
<p>Thank you for the reply.</p><p>For the RJ11, which the one I think been using the Wire.h library, I don't have to use a separate wire to connect the reed sensor to the arduino. I directly connect the wire to 2 digital input terminal. For that, I managed to get the 1 and 0 in the serial monitor of arduino or is this an incomplete step?</p><p>In the response above you said &quot;Wire.h has been used to provide connection to the RTC using the two connections SDA and SDC.&quot; However you are not using any external RTC devices. So do you mean has been used to provide connection to the Arduino using the two connections SDA and SDC?</p><p>If possible, can we communicate in other kind of medium, perhaps email or facebook? I'm in the middle of doing this kind of project and would like to ask your guidance along the way. Here is my email in advance, ahmadizham0108@gmail.com</p><p>Thanks</p>
<p>Thank you for coming forward and raising your much justified queries. </p><p>1.<br> I used the RJ11 for connecting/disconnecting the my rain collector <br>conveniently, nothing else. As you have meant, you can connect the <br>arduino directly to the reed sensor/magnetic switch.</p><p>2. One more <br>point (maybe you already know) about the magnetic switch connection. You<br> would observe that whenever the switch gets connected, +5V lands <br>directly on D2 of arduino and it interprets the signal as 1. On the <br>other hand if the same switch is open, the D2 gets a voltage of 0V from <br>the ground (GND) via the 15K resistor. The interpretation is 0. The 15K <br>resistor ensures that there is no short between the +5V and GND when the<br> switch is closed. Without this extra bit of connection the arduino's D2<br> pin may be puzzled as to what is the input whenever the switch is open.</p><p>3. I am truly sorry that I limited my clarification about RTC (which I looked up from another sketch, my bad). <strong>This particular sketch used the RTC library to keep time, it was &quot;software form&quot;</strong>. <strong>And wire.h followed</strong>.<br> (other times you may use an actual RTC to keep the time and yet other <br>times an ntp via internet can keep the time). It uses the clock of the arduino to <br>give us the time (i think) and gets reset every time the arduino is <br>powered off. I think I may have exhausted my knowledge about RTC:) Time keeping was required to measure rainfall during the last <br>hour or total rain for the day. They both get reset every hour and every<br> night respectively.</p><p>4. Like you<em> I am also a newbie</em> and self <br>taught. If you want to show your data over the internet, you may like to <br>use some sort of Ethernet shield like <a href="https://www.arduino.cc/en/Main/ArduinoEthernetShield">https://www.arduino.cc/en/Main/ArduinoEthernetShie...</a><br> or GSM shield for SMS (i declare ignorance). At present I am using an <br>Ethernet Shield for my weather station which is still in trouble <br>shooting phase. <a href="https://www.wunderground.com/personal-weather-station/dashboard?ID=INAGALAN3#history">My weather station reports.</a></p><p>For facebook (i declare ignorance again) some sort of FTP should be done, but I am not the guy:)</p>
<p>This is a neat project. Thanks for sharing!</p>
<p>Very nicely done. I like the well-written thorough documentation. </p><p>By the way, I am currently rebuilding my weather station. After many years of use, the ethernet cable has deteriorated and was no longer functional. (I did not use outdoor cable and it was out in the weather. Anyway, my basic sensors will be the same but am hoping to make it wireless. </p><p>Be interested to see how your weather station progresses.</p><p>Lazy Old Geek.</p>
<p>Looking forward to see it.</p>

About This Instructable



Bio: Recovering Physicist.
More by Abhijit Borah:Arduino Rain Gauge Calibration 
Add instructable to: