The rain gauge to me was one of the easiest to do, mostly because I kind of cheated a bit. Since I didn’t think I could create a sensor for cheaper than I could buy one, I spent $20 and bought the Acu-Rite gauge at Wal-Mart and modified it to my needs.
To start off, you’ll need to take apart the “gauge” piece and set the wireless display aside. This is fairly easy, as the main cover and tipping part comes off fairly easy. Next, you’ll need to remove the screws under the battery compartment to remove the circuit board. There are two wires coming out of the circuit board that go to the reed switch within the gauge that need to be clipped.
The reed switch is set within the tipping part, so carefully pull it out and strip the wires. You’ll need to attach wires to each of these. I use some telephone cable/cat3. I usually start with attaching about 10 feet of wire just in case. When attaching, make sure you solder the wires and use shrink tube to protect the connection.
Next, carefully slide the reed switch back into the tipping piece. Real quick explanation of how this works….A reed switch “closes” when a magnetic field is near. So we run current through the reed switch and place a magnet in the tipping mechanism to pass over the reed switch when it tips. When rain fills up a side of the gauge it tips over and the magnet causes the reed switch to complete the circuit for a brief period, which we can count….
We then need to drill a hole in the battery compartment and in the bottom piece to allow the wire to go through. Make sure to put a little hot glue in the hole in the bottom to protect against the elements a bit.
For testing, plug the two wires into a breadboard, one needs to run to power and the other to one of the pins on the Raspberry Pi (I believe I use number 17). In order to count how many times the gauge tips, we have to use GPIO interrupts. Before I forget, each tip is .02 inches of rain….
To keep count, I use a script that runs when the Pi starts up and monitors that pin. When the gauge tips and it detects a voltage “spike” it opens a file, takes the number, adds 1 to it and then rewrites the file with that number. (When I run the script that gets the current weather, I access this file and multiply by .02) At midnight every night, I also run a script that resets the number in the file to 0.
Here is the file I use to monitor the pin…
#!/usr/bin/env python2.7
import time
import os
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
First bit is to set up the normal stuff…I have to give some credit to Alex Eames @ http://RasPi.tv/ for the pieces of interrupt code. http://raspi.tv/2013/how-to-use-interrupts-with-python-on-the-raspberry-pi-and-rpi-gpio
# GPIO 17 set up as input. It is pulled up to stop false signals
GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
Next we need to set up the pin for interrupts. We’re setting up pin 17 as an input and using an internal resistor to pull it down to 0 when there is no current.
def my_callback(channel):
tfile = open("/home/pi/rain_count.txt")
text = tfile.readline()
tfile.close()
rain_count = int(text)
rain_count += 1
tfile = open("/home/pi/rain_count.txt", "w")
tfile.write(str(rain_count))
tfile.close()
Now we create the function that gets called when a “spike” is detected. This function opens the file called “rain_count.txt” and reads the number, adds one and then writes the new number to the file. When doing this, don’t forget to create the rain_count.txt file prior to running this and place a 0 in it.
GPIO.add_event_detect(17, GPIO.RISING, callback=my_callback, bouncetime=300)
Now we add the interrupt event that monitors pin 17 and says that we want to monitor it for a rising event (I call a spike). When it is detected it calls the function “my_callback” and then waits 300 milliseconds before it will try to detect another one. (The bounce time is necessary to keep from getting false positives.)
while True:
time.sleep(60)
The last bit is just an infinite loop to keep the script running. To run this at startup of the Pi, you’ll need to add a line to the crontab file:
@reboot python /home/pi/rain-gauge.py &
The clearing file is fairly easy too….
#!/usr/bin/env python2.7
import time
import os
tfile = open("/home/pi/rain_count.txt", "w")
rain_count = 0
tfile.write(str(rain_count))
tfile.close()
And add this to your crontab file to run at midnight…
* 0 * * * /home/pi/rain-clear.py
The last bit is grabbing the count when you run the the weather script…
#get rain amount
rain_file = open("/home/pi/rain_count.txt")
rain_gauge = rain_file.readline()
rain_file.close()
rain_count = int(rain_gauge)
rain_count =float(rain_count) * .02
rain_count = round(rain_count, 1)
The only thing I’ll mention here since it’s pretty straight forward is that you’ll notice I do a round at the end. I’ve experienced some false positives during the day when it’s sunny (usually 1 or 2 a day), so I just get rid of them by rounding to the nearest 10th.