So one of my last projects was adding a weather vane to my Arduino weather station.

This Lazy Old Geek decided to add a rain gauge to it even though we don’t get much rain in the high desert. Most digital rain gauges are based on something called a tipping bucket. Here is a good diagram complements of:

There are actually a lot of rain gauges for sale. has some tipping buckets for around $20. But I’m a Geek where’s the challenge in that, so I decided to build my own.
Remove these adsRemove these ads by Signing Up

Step 1: Parts List

Parts List:

USB Freeduino (Arduino-clone) $22.50
Adafruit Data logging shield $19.50

SD Card $ 6

Aluminum NoTrespassing Sign $ 2
2 Ethernet Couplers                       $1.40 (

1 empty Cashew nut plastic jar
1 Funnel (5.5" diameter)                 dollar store
1 ¾” pipe strap                                  $ 0.59
2 #8 nylon washers                          $ 0.17 @
1 small magnet (10 for $1 at Harbor Freight)
Honeywell SS461C Hall Effect IC $1.86 Digikey

Prices US dollars March 2011

Useful Tools:

Drill/drill press
Rotary tool (Dremel/clone)
Syringe ($0.99)

Any USB Arduino should work but it is easier to wire it up to an Arduino shield so the clone would have to be shield compatible. There are some good deals on ebay for Arduino Duemilanove 2009 for about $18.
The syringe is actually a cattle syringe for veterinarian use. I am a vet, close enough. Actually, this worked pretty good for calibrating my rain gauge.


1-40 of 49Next »
MarkAndrewLim3 months ago

If I have a different diameter for my collecting funnel, can i still use these formula to calculate the amount of rainfall?

jolomedina3 months ago

Do anybody know how to do the GUI in MATLAB or can you please help or teach me how to do it in VB? Need help! :( Thank you!

msuzuki777 (author)  jolomedina3 months ago

Learning VB Express is pretty hard. I've been programming VB for probably 20 years and still have trouble. There are some tutorials but I doubt if they would help. E.g.,

I think you can do it if MATLAB but I don't have any experience with it.

AdityaB14 months ago

Really excited with this project.

Anyway, i'm going to integrate this system with a server. it was located miles away from the place where i place this system. So how can i do that?

Is it possible to send the read data using GSM modem and log it every 10 minutes?

Or maybe is there another way to do that?

thank you

msuzuki777 (author)  AdityaB14 months ago

I don't know how you could transmit/receive over several miles. You're probably right about using a GSM module but I have no experience for doing that.

You will also have to have a power source at the weather station.


ruben199755 months ago

Nice project ! I'm going to use this project for school :)

AnasP6 months ago

this is great inspiration .. i have been duin it as a part of my final year project..

can u please post or send me the new code u use...

thank you..........

msuzuki777 (author)  AnasP6 months ago

Sorry, I don't have any newer code that will work with this setup.


jim5150jvc7 months ago

That mountain in the background looks very familar. Might that be somewhere near the Coachella Valley in California?

msuzuki777 (author)  jim5150jvc7 months ago

No, it's in Colorado.


naught1011 year ago

5mm seems like quite a large step - it must be quite common in a lot of areas to just get 1-5mm, and then have a sunny day. Since your remaining moisture is sitting in a metal cup in a greenhouse, I imagine a lot of it would evaporate in that situation, and you'd get a bias against low rainfall days. I imagine you could go a *lot* smaller without many problems cropping up.

msuzuki777 (author)  naught1011 year ago

I'm not sure where you got 5mm. I know I talked about 5mL as my bucket volume. But rain is measured in length(height) like inches or mm. The way I calculated it is that the volume of water hitting the bucket is the diameter of the funnel times the height of water.

As shown in step 8, the 5mL bucketful translates to 0.0128 inches of rain which is about 0.325 mm.

This is plenty accurate for me.

But you are correct that the accuracy could be increased with a smaller bucket size or what I would do would be to increase the funnel diameter.


Vinskeet1 year ago


Your design is great, nice work! I'm working on a similar project but I'm a little strapped for time so I am trying to avoid ordering parts. Right now I'm working on the rain station and I'm wondering if you think that the SS345PT/SS445P is a suitable replacement for the SS361? the 361s are designed to respond to alternating North and South poles while the 345/445 responds to a single pole. I don't think I should have to change your design at all.. Any ideas?
I was also considering using a Hall Effect Sensor, but I'm not sure.
Much appreciated,

msuzuki777 (author)  Vinskeet1 year ago

My concern is that I don't think the SS345PT/SS445P are latching sensors. My sketch is designed to look for a high state than count only when it sees a low state. I believe these sensors only transition when the magnet is near but then returns to it's inactive state.

If my sketch was able to catch every toggle, then I suspect the count would be doubled actually. If it missed some toggles than the rain count would be less than actual.


A quick question. In all three parts, a few of the same parts. Did you purchase three sets of these, or are you listing them for people who only want to make the one part?

msuzuki777 (author)  PatrickDickey527611 year ago

The parts lists are confusing if you read all of my Weather Station Instructables. Some, mainly the Arduino and data shield are duplicated. Only one of each is needed.

By the way, I'm still using my weather station but replaced the data logging shield with a custom PCB and eliminated the SD card as I never used it that much.


fmbfla1 year ago
(removed by author or community request)
msuzuki777 (author)  fmbfla1 year ago
Wow! You are obviously a much better programmer than I am.
So I am assuming that you are getting extra rain counts when you should be getting none.
I don't think it's a problem with using two interrupts but one way to test would be to comment out the Anemometer Interrupt and see if you are still getting extra rain counts.

What I most suspect is a hardware problem on the Rain pin. Do you have a pullup resistor on the hall effect?
I would also measure the voltage on D3 and make sure it goes from close to 5V to close to ground when toggling it. It could be that the hall effect is too close to the magnet and the voltage is not going all the way high or low.

Hope this helps.

I do have a 10k on the rain pin the anemeom has it built in (Davis) I didnt think of commenting out the wind ( My eyes are hurting and affecting my thought processes). I have had an LED connected from time to time on the pin and it blinks when triggered but It still might be enough to trigger the interrupt but not light the LED.
Your incite has me thinking on track once again.
I will let you know how it turns out in a few days(if I'm sober enough to remember LOL).
. Thank you for your input.
fmbfla fmbfla1 year ago
*************** YA'PAWS "Yet Another Personal Arduino Weather Station" ***************
* * 369 lines of code below the boilerplate *
* Brought to you by, ****The Drunkin Programer!****
* Binary sketch size: bytes (of a 32,256 byte maximum) on the UNO 328PU)
* RePurposed Anemometer/weather vane
* Repurposed Rain Tipping bucket(modified with an Adafruit Hall effect switch
* Adafruit DHT 22 (AM2302)
* (2) radioshack 6 volt 1.5 watt Solar panles(Parallel)
* Remote volatge regulator panel for charging 4 AA NiMH batts
* Atmel 328PU on perf board with regulated 5 volt power on board
* Xbee S1 for simple serial data transfer
* Run's in a six second LOOP (const int period = 5000 is the sampling time in millis)
* the rest of the time is from delays for the Xbee TX/RX and the Serial printing.
#include "RTClib.h"
//#include // 9600, xbee default
//SoftwareSerial mySerial(A0,A1); // (TX/RX)Pins that are connected to DFrobot Xbee Usb BoB
// Constants definitions
String id = "xxxxxxx"; //ToDo
String PASSWORD = "xxxxxxx"; //ToDo
const float pi = 3.14159265; // pi, not apple, not pumpkin, not pizza, not even related to Raspberry Pi. This is the REAL PI for Wind speed calculations

const int period = 4000; // Measurement period (miliseconds)
const int DHTPIN = A0 ; // DHT 22 (AM2302)
const int voltPin = A1; // Reading the RAW solar voltage
const int winDir = A2; // Wind direction
const int anemometer = 2; // Digital 2, Receive the pulse from Anemometer REED sensor on pin 2/Interupt 0
const int rainTip = 3; // Digital 3, Receive the pulse from Rain HALL EFFECT sensor on pin 3/Interupt 1
const int xBeeswitch = 8; // Transistor control pin for appling/disconecting power to the XBEE
const int radio = 65; // Radius from vertical anemometer axis to a cup center (mm)

int readVolts = 0; // Reading the RAW solar voltage
int maxVolts = 15; // Must match voltage circuit resistors
int startMonth = 0;
int startDay = 0;
int startHour = 0; // Start Time Hour
int startMinute = 0; // Start Time Minute
int startSecond = 0; // Start Time Second
int Hour = 0; // Starting hour
int Minute = 0; // Starting minute
int Second = 0; // Starting second
int hr = 0; // Am or PM

char* winds[] = {
"Calm", "a Light air", "a Light breeze", "a Gentle breeze", "a Moderate breeze", "a Fresh breeze", "a Strong breeze", "a Moderate gale", "a Fresh gale", "a Strong gale", "a Storm", "a Violent storm", "a Hurricane"};
// First Char is empty for it is considered a Zero placemark, and there are no zeros in the date
char* Month[] = {
"Leave empty! ", "January", "Febuary", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
// First Char is empty for it is considered a Zero placemark, and there are no zeros in the date
char* weekDays[] = {
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Satuday"};
char* Hr[] = {
" ", " AM", " PM"};
// Variable definitions
unsigned short windforce = 0; // Beaufort Wind Force Scale
unsigned int Sample = 0; // Sample number
unsigned int weekDay = 0; // Day of the week
unsigned int months = 0; // ToDo!
unsigned int Week = 0; // Every 7 days add one week
unsigned int counter = 0; // pulse count for sensor
unsigned int RPM = 0; // Revolutions per minute

float voltageFactor = 0; // Reading the solar voltage
float voltage = 0; // Reading the solar voltage
float current = 0; // Reading the solar voltage
float power = 0; // Reading the solar voltage
float speedwind = 0; // Wind speed (m/s)
float maxwind = 0; // Wind Gust
//float rainCount = 0; // pulse count for sensor
float totalRain = 0; // Total Rain count
float rainQuarter = 0; // Rain count for 1/4 hour
float rainHalf = 0; // Rain count for 1/2 hour
float rainHour = 0; // Rain count for 1 hour
float rainDaily = 0; // Rain count for 24 hours
float rainWeek = 0; // Rain count for 1 week
float rainMonth = 0; // Rain count for 1 Month

RTC_DS1307 rtc; // DS1307 Real Time Clock(RTC)
#define DHTTYPE DHT22 // DHT 22 (AM2302)
DHT dht(DHTPIN, DHTTYPE); // DHT 22 (AM2302)
void setup()

// Adjust the clock in Neccesary!
//rtc.adjust(DateTime(__DATE__, __TIME__));
DateTime now =; //Start he Clock!
pinMode(xBeeswitch, OUTPUT); // Set the Transistor PIN as an OUTPUT
digitalWrite(xBeeswitch, HIGH); // Set the Transistor PIN to HIGH so that the Xbee can begin connecting to the reciever at first boot
delay(100); //give it time to find the reciever
pinMode(anemometer, INPUT);
digitalWrite(anemometer, HIGH); // the hall switch goes LOW when magnetized so we set it PIN HIGH
pinMode(rainTip, INPUT);
digitalWrite(rainTip, HIGH); // the hall switch goes LOW when magnetized so we set it PIN HIGH
Serial.begin(9600); //Start the serial connection with the computer
//mySerial.begin(9600); //9600, xbee default. Start the serial connection with the Xbee
Serial.println("Xbee Arduino Weather Station");
delay(1); //give a liitle time for the transfer to complete
digitalWrite(xBeeswitch, LOW); // Set the Xbee Transistor PIN to LOW after initial connection
startMonth = (now.month());
startDay = (;
if(now.hour() < 10){
startHour = ((now.hour() > 12) ? now.hour() - 12 : ((now.hour() == 0) ? 12 : now.hour()));
hr = 1;
startHour = ((now.hour() > 12) ? now.hour() - 12 : ((now.hour() == 0) ? 12 : now.hour())); // Conversion to AM/PM
hr = 2;
startMinute = (now.minute() );
startSecond = (now.second());
void loop() // run over and over again===================================================================================
DateTime now =;
Sample++; //Start counting the Sample's (LOOPS)
wind_rain(); //run the wind and rain calculations
RPMcalc(); //run RPM calculations
WindSpeed(); //run WindSpeed calculations
if (speedwind > maxwind) {
maxwind = speedwind;
float heading = (analogRead(winDir)* 5.00 / 1023.0);//Wind direction, Tweek the voltage returns below to match your resistor
float h = dht.readHumidity();
float t = dht.readTemperature();
readVolts = analogRead(voltPin);
if (readVolts > 0)
//Reading the solar voltage
readVolts = analogRead(voltPin);
voltageFactor = 1024 / maxVolts;
voltage = readVolts / voltageFactor;
digitalWrite(xBeeswitch, HIGH); //put this here so that the switch will only trip AFTER all of the calculations are done.
delay(100); //give a liitle time for connection to complete
Serial.print("Sample # ");
Serial.print("Start Time: ");
Serial.print(", ");
Serial.print(" ");
if(now.hour() < 10){
// Hour = 0;
Serial.print(" "); // Zero padding if value less than 10 ie."09" instead of "9"
if(startMinute < 10){ // Zero padding if value less than 10 ie."09" instead of "9"
Minute = 0;
if(startSecond < 10){ // Zero padding if value less than 10 ie."09" instead of "9"
Second = 0;
//Serial.print("Current Time: ");
Serial.print("Now: ");
Serial.print(", ");
Serial.print(", ");
Serial.print(, DEC);
Serial.print(" ");
if(now.hour() < 10){ // Zero padding if value less than 10 ie."09" instead of "9"
Serial.print(" ");
Serial.print((now.hour() > 12) ? now.hour() - 12 : ((now.hour() == 0) ? 12 : now.hour()), DEC); // Conversion to AM/PM
Serial.print((now.hour() > 12) ? now.hour() - 12 : ((now.hour() == 0) ? 12 : now.hour()), DEC); // Conversion to AM/PM
if(now.minute() < 10){ // Adds a Zero if value less than 10 ie."09" instead of "9"
Serial.print(now.minute(), DEC);
Serial.print(now.minute(), DEC);
if(now.second() < 10){ // Adds a Zero if value less than 10 ie."09" instead of "9"
Serial.print(now.second(), DEC);
Serial.print(now.second(), DEC);
if(now.hour() < 12){ // Adding the AM/PM sufffix
Serial.println(" AM"); // ie; if less than 12, say AM
Serial.println(" PM"); //If more than 12, then say PM
Serial.print("Winds "); //"Winds are from the"
if ((heading > 4.94)||(heading < 0.01))
Serial.print(" N ");
if ((heading >= 0.02)&&(heading < 0.30))
Serial.print(" NNE");
if ((heading >= 0.31)&&(heading < 0.72))
Serial.print(" NE ");
if ((heading >= 0.72)&&(heading < 0.99))
Serial.print(" ENE");
if ((heading >= 1.00)&&(heading < 1.25))
Serial.print(" E ");
if ((heading >= 1.26)&&(heading < 1.52))
Serial.print(" ESE");
if ((heading >= 1.53)&&(heading < 1.91))
Serial.print(" SE ");
if ((heading >= 1.92)&&(heading < 2.40))
Serial.print(" SSE");
if ((heading >= 2.41)&&(heading < 2.73))
Serial.print(" S ");
if ((heading >= 2.74)&&(heading < 2.96))
Serial.print(" SSW");
if ((heading >= 2.97)&&(heading < 3.37))
Serial.print(" SW ");
if ((heading >= 3.38)&&(heading < 3.55))
Serial.print(" WSW");
if ((heading >= 3.56)&&(heading < 3.85))
Serial.print(" W ");
if ((heading >= 4.13)&&(heading < 4.06))
Serial.print(" WNW");
if ((heading >= 4.07)&&(heading < 4.32))
Serial.print(" NW ");
if ((heading >= 4.33)&&(heading < 4.93))
Serial.print(" NNW");
Serial.print(" ");
Serial.println(" : MPH ");
//Serial.print(" and is ");
// Serial.println(winds[windforce]);
Serial.print("Wind Gust ");
Serial.println(maxwind / 0.445); //convertion to MPH
Serial.print("Temperature: ");
Serial.println(" *F");
Serial.print("Humidity: ");
Serial.println(" %");
Serial.print("Total Rain: ");
// the Rain Switch goes from HIGH to LOW to HIGH again each TIP so we divied it by 2
// and then by 10 and again by 10, so that we report Tenth's of an inch for each tip ( as per my tip bucket size, Yours may vary)
Serial.println(totalRain / 2 / 10.0/10.0);
Serial.print(" Past 15 Minutes ");
Serial.println(rainQuarter / 2 / 10.0/10.0);
Serial.print(" Past Half Hour ");
Serial.println(rainHalf / 2 / 10.0/10.0);
Serial.print(" Past Hour ");
Serial.println(rainHour / 2 / 10.0/10.0);
Serial.print(" Past 24 Hours ");
Serial.println(rainDaily / 2 / 10.0/10.0);
Serial.print(" Past Week ");
Serial.println(rainWeek / 2 / 10.0/10.0);
Serial.print("Solar Volt's: ");
Serial.println(" V");
delay(1); //give a liitle time for the transfer to complet
digitalWrite(xBeeswitch, LOW);// After sending the data Turn the Xbee Switch off to save power
}//End LOOP==========================================================================================================
// Mesure the rain Bucket TIP's and the RPM's for the Anemometer
void wind_rain(){//combined the rain and wind interupts
speedwind = 0;
counter = 0;
attachInterrupt(0, addcount, CHANGE);
unsigned long millis();
long startTime = millis();
while(millis() < startTime + period) {
//save the RPM's and add them up
void addcount(){
// save the tips and add them up
void addRain(){
//calculate the RPM's
void RPMcalc(){
RPM=((counter)*60)/(period/1000); // Calculate revolutions per minute (RPM)
//calculate the windSpeed based on the RPM's
void WindSpeed(){
speedwind = ((2 * pi * radio * RPM)/60) / 1000; // Calculate wind speed on m/s
// Calculate Wind force depending of wind velocity
if (speedwind <= 0.3){
windforce = 0; // Calm
else if (speedwind <= 1.5){
windforce = 1; // Light air
else if (speedwind <= 3.4){
windforce = 2; // Light breeze
else if (speedwind <= 5.4){
windforce = 3; // Gentle breeze
else if (speedwind <= 7.9){
windforce = 4; // Moderate breeze
else if (speedwind <= 10.7){
windforce = 5; // Fresh breeze
else if (speedwind <= 13.8){
windforce = 6; // Strong breeze
else if (speedwind <= 17.1){
windforce = 7; // High wind, Moderate gale, Near gale
else if (speedwind <= 20.7){
windforce = 8; // Gale, Fresh gale
else if (speedwind <= 24.4){
windforce = 9; // Strong gale
else if (speedwind <= 28.4){
windforce = 10; // Storm, Whole gale
else if (speedwind <= 32.6){
windforce = 11; // Violent storm
else {
windforce = 12; // Hurricane (from this point, apply the Fujita Scale)
void RainAmount(){
DateTime now =;
//Clear the rain results for rainQuarter every 15 minutes
if ((now.minute() == 15) && (now.second() <= 5)) {
rainQuarter = 0;
//Clear the rain results for rainQuarter every 15 minutes
if ((now.minute() == 30) && (now.second() <= 5)) {
rainQuarter = 0;
rainHalf = 0;
//Clear the rain results for rainQuarter every 15 minutes
if ((now.minute() == 45) && (now.second() <= 5)) {
rainQuarter = 0;
//Clear the rain results for rainQuarter, rainHalf and rainHour every Hour
if ((now.minute() == 59) && (now.second() >= 59)) {
rainQuarter = 0;
rainHalf = 0;
rainHour = 0;
//Clear the rain results for rainQuarter, rainHalf, rainHour, rainDaily and maxwind every 24 hr
/* if ((now.hour() == 24) && (now.minute() == 00) && (now.second() <= 5)){
rainQuarter = 0;
rainHalf = 0;
rainHour = 0;
rainDaily = 0;
maxwind = 0;
//Clear the rain results for rainWeek every 7 Day's (Day == 7)
if ((now.dayOfWeek() ==7 ) && (now.hour() == 24) && (now.minute() == 00) && (now.second() <= 5)){
rainQuarter = 0;
rainHalf = 0;
rainHour = 0;
rainDaily = 0;
rainWeek = 0;
maxwind = 0;

usephotep1 year ago
we only making in our project just for rain.....
usephotep1 year ago
are there any additional codes f we use ethernet shield or SD shield??because we're not using a data shield....
usephotep1 year ago
Mr. msuzuki,can i know f you have using a software in this project and may i know what is it??thank you sir...
msuzuki777 (author)  usephotep1 year ago
Yes, the Arduino sketch is in a zip file Step 8. The Arduino talks to a PC with USB. The PC is running a VBExpress program which is in a zip file Step 9.

beaumont41 year ago
Hi I have been inspired by your weather station enough to embark on a project of my own, however I am an hobby para-glider and have removed some elements such as the rain gauge and wind chill in favour of elements such as Air pressure and humidity which I have done successfully. I would be very pleased if you could provide the VB source code so I could make customizations. P.s would be pleased to provide photos of my weather station attempt, regards John
msuzuki777 (author)  beaumont41 year ago
Great. I'm trying to figure out how to attach a file. So there should be a attached.

What did you use for an air pressure sensor?

Hope this helps. I am using VBExpress2010.

karlitoboi2 years ago
mr. lazy old geek... we did your project as our inspiration to our project(THESIS project actually), but we use EW-512 hall effect ic (since yours is not available in our country) and we directly connect it to our pic16f877a we have our own program but we have not tested it. in your own view, do you think it will work? and one more thing we don't have shield, but we have our data transceiver for our wireless transmission...does the hall effect still effective in our project since we directly connect it to our pic without your shield?
msuzuki777 (author)  karlitoboi2 years ago
As far as I can tell, the EW-512 will work okay. You will still need a pullup resistor. And it should work fine connecting it directly to the PIC. In this Instructable, I used the shield as it has a Real Time Clock and the SD data storage. But in my current weather station, I don't use a shield.

I like your plan of using wireless transmission. Hope it works for you.

thank you very much sir!
so, where should i put the pull up resistor, in the red wire of the EW-512?
thank you sir!
msuzuki777 (author)  karlitoboi2 years ago
I do not have any EW-512s so am not familiar with them. I looked at a several datasheets. One of them said a pullup was required but a couple of others said you don't. So you probably won't need one but I don't know for sure without more information on the particular EW-512 that you have. I guess I would try it without a pullup and see if it works.

usephotep2 years ago
can we still apply the circuit diagram even without using shield? if it's not applicable, what changes do we have to make?
msuzuki777 (author)  usephotep2 years ago
Yes, modify sketch. See other comments.

usephotep2 years ago
can we connect the sensors directly to the arduino, instead of the shield since we won't be using it?
msuzuki777 (author)  usephotep2 years ago

ozmahades2 years ago
we won't be using datalogger shield but is it possible to directly store the data to pc
msuzuki777 (author)  ozmahades2 years ago
Yes, The Arduino sketch sends weather data to the serial port. In my last step, there is a Visual Basic Express program that accepts this data, fills in the PC display and also writes the data to a CSV file. Now that I took a quick look at the VB Express program I doubt it would work on anybody's PC as it has some specific references to my PC.

I use my weather station daily. In my current version, I am no longer using the datalogger or Real Time Clock. The VB Express program puts a timestamp on the serial data before writing it to a CSV file.

usephotep2 years ago
where do we connect the sensor terminals if there's no shield used?

msuzuki777 (author)  usephotep2 years ago
You will have to duplicate the schematic in the Instructable on a proto board or breadboard. This will have to be interfaced with the Arduino (Atmega328). The sketch will have to be modified to remove references to the real time clock and SD card.

usephotep2 years ago
is it ok if we use a 328 microcontroller for the arduino that we are going to use?????
msuzuki777 (author)  usephotep2 years ago
Yes, that is what I used.

1-40 of 49Next »