Introduction: NodeMCU Hall Effect Rain Gauge

This will show you how to make your own "tipping bucket" rain gauge with a NodeMCU, that makes it easy to send data to an online service of your choice. In this tutorial we are going to collect data from the rain gauge and then transmit it every 30 minutes to the service.

The nodeMCU uses the ESP8266 Chip from Espressif. It has built-in Wifi and is compatible with the Arduino IDE. If you haven't used a NodeMCU before check out this quick start guide.

Step 1: Components

Step 2: Building a Tipping Bucket

Tipping buckets are a fairly common tool for measuring rainfall. It is a simple device that consists of a funnel which directs the water into a bucket. Once the bucket fills up it tips over activating a switch, tipping out the water and begins filling up the bucket on the other side. - See wikipedia for more info

For your own rain gauge the simplest option is to buy one. Something like this or this would work with our setup. If you do buy one - you don't need to worry about the Hall effect sensor or magnet. If you're looking for something a bit more agricultural you can out one together from parts you can pick up at your local hardware store. Check out the design from these guys

In our case we've 3D printed one. We've based ours on this one by BulldogLowell. We've modified it slightly to fit our sensor and magnet.

The STL files can be found in our Github repository


Every time the the bucket tips, the switch registers one count, which we can convert into a height of rainfall. The height of rainfall can be determined by the ratio of the volume of rain collected to the collection area:

rainfall height (cm) = volume collected (mL) / collection area (cm2)

For our collector we have a collection area of 5.5cm x 3.5cm (19.25cm2) and a collection per tip of the bucket of 2.5mL. This gives us a rainfall height of 0.1298cm or 1.298mm per tip.


A couple of notes when installing the unit

  • Ensure that the unit is completely level - if not the buckets won’t collect the same volume for each tip - and your results won’t be accurate
  • Install it off the ground - at least a metre high. This is to reduce the likelihood of anything being accidentally tipped into it (like dirt).
  • Ensure that there is nothing above the gauge. It might seem obvious but its important there there isn’t anything like tree branches or leaves within a few feet of it to ensure nothing can interfere with the rain. (And remember tree branches grow over time.)

Step 3: Wiring It Up

Here is the basic wiring diagram for the device. You can see what the final version looks like at the end of this instructable and how to connect it up to you tipping bucket.

The LED and push button aren't necessarily required but are useful to publish a manual reading and check that its working.

Step 4: Source Code

For the rain gauge we will be posting the data every 30 minutes to the service. We'll be using the library that manages the wifi and service connections. We've also split out all of the configuration variables in a separate .h file.

Within the RainGauge.ino code we have three interrupts performing the key functions

  • Rain Interrupt - detects when the bucket is tipped and adds it to the collected rain height
  • Timer Interrupt - which periodically (we've used 30min) takes the rain height and sends it to the server and then resets the height.
  • Push Button Interrupt - which performs the same function as the timer manually (we've used this mostly for testing is optional)

You can download the full source code here


const String CHANNEL_ID = "XXXXXXXXXXXXXX"; // The channel ID
const String SENSOR_ID = "XXXXXXXXXXXXXXX"; // Your AgriWebb or made up sensor ID
const String TOPIC = "rain-gauge"; // The type of sensor or name of the data your sending
const String VERSION = "1";
const String FORMAT = "";
constchar* WIFI_SSID = "XXXXXXX"; // Your WiFi SSID / name
constchar* WIFI_PASS = "XXXXXXX"; // Your WiFi password
constuint16_t UPDATE_RATE = 120; // How long to wait between sending data back (in seconds)
constuint8_t TIMEZONE_OFFSET = 10; // The timezone the sensor is located in (eg. 10 for GMT)
constdouble BUCKETTIP_HEIGHT = 0.1298; // Don't forget to change this for your own tipping bucket.
// The height of rain collected by a single bucket tip (in millimietre)
// determined by the volume of water collection in a single bucket tip (mL
// divided by the collection area
view rawconfig.h hosted with ❤ by GitHub


constint LED_PIN = 0; // The pin connecting the LED (D3)
constint INTERRUPT_PIN = 14; // The pin connect the test button (D5)
volatiledouble RAIN_HEIGHT = 0; // variable for storing the rain_height
volatile byte interrupt = 0;
Ticker timer;
/* Interrupt for counting the number of clicks of the rain gauge */
voidrainInterrupt() {
RAIN_HEIGHT += BUCKETTIP_HEIGHT; // takes the current rain height and add the amount of the bucket
Serial.print("Curent Rain Height Collected (mm): ");
voidhandleInterrupt() {
/* Interrupt timer for sending data to the server */
voidsetup() {
digitalWrite(BUILTIN_LED, HIGH); // internal LED is switched on when low - so we have to switch it off/
while(!Serial) { } // Wait for serial to initialize.
Serial.println("Device Started");
Serial.print("Connecting to ");
client.wifiConnection(WIFI_SSID, WIFI_PASS);
pinMode(INTERRUPT_PIN, INPUT_PULLUP); // Set the interrupt pin for the reed/hall effect
attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), rainInterrupt, RISING); // Attach the interrupt.
timer.attach(UPDATE_RATE, writeToServer);
voidloop() {
view rawrainGauge.ino hosted with ❤ by GitHub

Step 5: The Finished Product

Here is the final rain gauge. The nodeMCU is housed in the enclosure with the wires for the tipping bucket entering through the cable gland to ensure that its water tight and safe to be install outside. Our wires are fairly should but you can make them as long as you need.

You can also see the inside of the tipping bucket. The sensor is attached to the wall, whilst the magnet is fixed to the swing arm of the tipping bucket, so that every time it fills up and tips over it registers a reading. The hardest part of assembling the tipping bucket it positioning the sensor and magnet correctly. Just close enough to take a reading but not tool close that it always remains on.