Wednesday, February 5, 2014

Tweet, tweet!

I've relied heavily upon SSH to program and monitor the weather station, but that isn't a very elegant solution and isn't visible to anyone else. Moreover, I can't monitor the station (or even see the data) when I'm away from my home network.

I considered setting up a static IP address for the Pi and essentially having it act like a server, but I was afraid that the extra network traffic (both intended and unintended) could hamper the Pi's performance. I also thought of building a website where the Pi could send its data and then be viewed by anyone online, but I didn't want to pay for the domain, hosting services, etc. For now, I'd just rather have some 3rd party website manage and disseminate my data. That's where Twitter comes in.

I found Twython, which is a Python library for managing a Twitter account. It allows you to post text, pictures, and videos and probably do a bunch of other things that I didn't take time to learn about since I will be just posting text (maybe a webcam later though...).  I signed up for a new Twitter account so that I don't spam my current followers.  Twython requires you to set up a new Twitter application at and record the consumer and access keys in your script.  There is a good tutorial HERE. After that, you can compose a Tweet with a single Python command.

The script that I wrote ingests the current conditions from current.txt and outputs them (nicely formatted) to Twitter.  It serve a few other functions like converting to Fahrenheit, calculating relative humidity, converting to sea-level pressure, and converting wind speeds from rpm to mph.  The script is run every 10 minutes with Cron.
Here's the output. "The View" is the name of my apartment complex. 
Note that the account has a new handle since this screenshot was taken.

Right now it just prints the one-minute average every 10 minutes, so Twitter is essentially ignoring 9 minutes worth of data. I might work to fix this and add 10-minute or 5-minute averages, but it works just fine for me for now.  

For those of you who are interested, my handle is @viewwx (click link for my profile).  I don't regularly check it, so it is still better to contact me via my personal account @aaronmangels.

Station setup

It isn't an ideal situation since I live in an apartment and don't have a nice open place to setup the station. Anyway I decided to test the reliability of the station by setting it up on our balcony.  The wind measurements are obviously incorrect since the building blocks most of the wind, but temperature, humidity, and pressure should be reasonably accurate (at least locally).  The windvane and anemometer move occasionally with wind gusts, so it is still possible to see that they're working.  The wires run under our door so that the Pi can be housed indoors in order to protect it from the weather.
Balcony setup


I've avoided blogging about programming until this point because its been a work in-progress.  I'm finally at a point where I'm happy with the code that is running and the output files.  Here is a brief rundown of the programs that run the weather station.

  • 4 Python scripts to query each sensor once per second (1Hz) and write the output to a temporary text file for later analysis
    • (relies on rpiSht1x python library)
    • (relies on Adafruit I2C libraries)
    • (relies on Adafruit software-level SPI implementation)
    • (uses RPi.GPIO to interrupt and count each pulse)
  • A Fortran (used because of speed and familiarity) program to analyze each of the temporary text files every minute
    • Finds average temperature, dewpoint, pressure, and windspped
    • Finds the maximum 3-second wind gust
    • Uses the Yamartino Method  to calculate average wind direction and standard deviation
    • Generates summary each minute and writes it into the appropriate text file for the day/month/year
    • Generates current.txt which will be used for future projects (updating websites, Twitter, etc.)
  • A scheduling python script to call the Fortran program at XX:XX:00 (better sleep functions than Fortran
  • Cron tasks to call each of the Python scripts at reboot

Interfacing with Raspberry Pi

Up until this point, I had just been using a breadboard to connect the Pi to the sensors so it was time to make something more permanent in the form of an add-on shield.  

I started with a piece of protoboard and some screw terminals from RadioShack and a GPIO header extension from Adafruit.  The analog-digital converter (to read the potentiometer) needs to be incorporated into the board and each of the screw terminals needs to connect to the corresponding GPIO pins.  I'm not terribly confident with my soldering skills, but I decided to give it a shot.  To my surprise, it worked on the first try!
Bottom side of the board

Since the Raspberry Pi doesn't have a real-time clock, I decided to add one onto the shield.  Adafruit has a couple RTCs to choose from, and I chose the cheaper of the two for $9.  See DS1307 HERE.  It easily interfaces via I2C and will keep time when detached from the network and even when powered off.  This one might lose/gain up to 2 seconds per day, but that isn't a huge concern since it can periodically get the time over the Internet.  

Top side of the board plugged into the Pi. 
Real Time Clock is the blue board on the bottom right

Putting It All Together!

Now that all the pieces were complete, I could go about building the support structure for the sensors.  I'll admit that it is rather simple and crude at this point, but it works!

I basically just made a "T" with two old chunks of 2x4, and added some u-bolts to the vertical board so that I can attach it to a fencepost, railing, or elsewhere.  To add rigidity and allow for easier removal, I added a piece of 1x4 to the bottom of the windvane and anemometer and a piece of steel to the top of the radiation shield.  In order to protect the sensitive electronics, I did my best to seal all holes and leaks with silicone adhesive.  
The (almost) finished project. Yes, I know that the wires and duct tape are messy...

Tuesday, February 4, 2014

Anemometer (and calibration)

The last component of the station is the anemometer.  Rather than trying to build a set of anemometer cups (that probably wouldn't be very accurate) I chose to buy a set of Davis cups from eBay (~$15).  I looked at 3D printing the necessary parts, but 3D printing services are too expensive and I don't have my own 3D printer (yet...).  The rest of the setup was relatively easy to put together.
These are similar to the cups that I used

I used 1/8" rod and another old Tupperware container with two ball bearings to allow the shaft to rotate freely.  I actually had to sand down the shaft for it to fit in the bearings.  In order to keep the shaft from sliding out, I didn't sand the ends of the shaft so that the shaft is essentially press-fitted into the bearings.  I glued the magnet onto the shaft vertically and placed the hall sensor next to it on a  piece of perfboard.  The magnet causes the sensor to fall LOW each time it spins, and the Raspberry Pi can easily count each of these pulses.

Its easy to calculate the speed of the anemometer in rotations per unit time, but that is relatively meaningless and there is no way to simply convert from rpm to mph (or kph, kts, m/s, etc.) -- there are simply too many variables (cup size, anemometer weight, friction, etc).  I need to correlate my anemometers rpm with known wind speeds.  I decided the best way to do this and get a good range of wind speeds would be with my car.

I chose a mostly calm day to do the calibration so that ambient winds wouldn't harm my readings.  I wrote a simple python script to log the number of pulses that the anemometer produced.  I plugged the Raspberry Pi into my cigarette lighter and SSH'd into my Pi with my computer to control it.  To further complicate things, I had to create a mobile hotspot on my phone in order to stay connected away from my house.  Luckily, my girlfriend was happy to help out since I don't have enough hands to drive, control the Pi, and hold the sensor at the same time.  I drove and held the sensor out of the window while she ran the python script.  We collected data from 5 mph, 10 mph, 15 mph, etc up to 50 mph.

When we got back, I plotted and graphed the data in Excel and was surprised to find that the relationship was very linear.  The linear regression equation came out to be y = 1.9757x + 0.2395, where x is in rotations/second.  The R-squared statistic was good considering the crude calibration method at 0.9976.  

See the finished pictures to see the anemometer. 

Wind Vane

Next up is the wind vane.  

Although wind vanes are easy to find and relatively inexpensive, I once again decided to make my own rather than just purchase one.  I thought this would be a relatively easy step, but it actually proved to be somewhat tricky.

My primary concern was that the potentiometer requires a non-negligible amount of torque to spin; therefore, my wind vane would need to be larger to allow even small breezes to turn the shaft.  I decided to use a scrap sheet of stainless steel to cut out a standard wing shape, but I found that the end result was very unbalanced and wouldn't rotate smoothly.  To compensate for this, I cut a chunk of 1" steel rod and soldered it to the front edge of the vane.  This moved the center of mass forward far enough that it wouldn't be biased even if the platform isn't completely level.  

I attached the vane to a piece of 1/8" rod and glued it inside of a small plastic tube that fit around the potentiometer shaft perfectly.  I housed the entire assembly inside of an old Tupperware container and added a bearing to the top to allow smoother motion.  

The vane works and reacts to relatively low (~5 MPH) breezes, but it isn't very visibly appealing (see it in the pictures of the finished station in a later post).  I will likely replace it with a vane from Davis (~$15) in the future. 
One of these will make the station look a little more professional