Raspberry Pi Weather Station in Python

PiUPDATE: Source code added to TCC GitLab

Building a Raspberry Pi Weather station with Python.

I’ve used Python before but not extensively or terribly in depth, just bits and pieces here and there. Just enough to get by.
And since I’m the kind who learns by doing I decided that, I would find a way to put this Raspberry Pi Model B that I’ve had lying around to use.

So I read around some forums for some project ideas and a common theme always seemed to be these Weather stations.
People have built some great stations but clearly had a far larger budget than I.

So I set out to see what was available to the budget conscious hardware hacker.

Adafruit and many other such companies had some great offerings, but were quite pricey and Amazon and weren’t available on Prime delivery.
Now, I’m fully aware of the proverb “You get what you pay for”, but I was quite happy to buy the sensors and solder them myself.
With a little digging I came across this Sensor kit from Kookye for about £20 on Amazon.co.uk that included a wide variety of things to do.
But what I was most interested in was the DS18B20, the DHT11 and the BMP180.

The DS18B20 is a digital 1-wire thermometer that was made by Maxim Integrated. Datasheet here.
The DHT11 is a digital temperature and humidity sensor which has many clones and originated from Aosong Electronics Co. Translated datasheet here.
The BMP180 is a digital barometer, altitude and temperature sensor which uses the I2C Bus, made by electronics giant Bosch. Datasheet here.

So I had my sensors, but a couple of things needed to be done before I could use them.

Before soldering, the battery and soldering iron tip are for scale.


The other two sensors came pre-soldered on board but the BMP180 lacked header pins.
This was super fiddly as the contact pads were so small and even though the soldering iron tip I used was the smallest I had it still made the job a bit of a pain.
Like me, you’ll probably need a clamp stand to hold it steady as you should not keep heat near it for long.


The raspi-config advanced menu.

Secondly, I needed to enable the I2C bus and 1 wire interfaces on the Raspberry Pi, Fortunately this is made very simple by the Raspberry team and raspi-config.

Pull up your SSH or local terminal and switch to root, then type  raspi-config  and press enter,

Enter the “Advanced” menu and choose I2C, answer yes to enable and no to rebooting.

Exit raspi-config and at the terminal do:

Then use your favourite text edit to edit /boot/config.txt  and add: dtoverlay=w1-gpio
Save and shutdown.


Next up was cabling, The kit I purchased had a 16 pin, 30 cm ribbon cable inside.

WARNING: In the following pin numbers I state the actual header pin number for my Pi!
Please see this guide for your Pi’s header layout.
Please check your own datasheets, wiring and diagrams to see how to cable the sensors,
Always turn off the Pi before adjusting cables, Not doing so could destroy the sensor(s) and your Pi.
I cannot be held responsible for any damage from the guide below.

Sensors in my make shift housing.

My DS18B20 had the pins, marked “+”, “-” and “S”. Making it fairly easy to wire, Plus went to 3.3V (pin 1), Minus to GND (pin 9) and S to GPIO 4 (pin 7).

The BMP180 uses I2C, so it needs 4 pins, In my case the board supported 5v, so the pins were; VCC to 5v (pin 2), GND to GND (pin 6), SCL to SCL (pin 5) and SDA to SDA (pin 3).

Lastly was the DHT11, this sensor uses a non-standard protocol so I opted to use GPIO 23 (pin 16) for DATA, GND to GND (pin 20) and VCC to 3.3v (pin 17).

There are some great websites with header diagrams for all versions of the RPi available here and here

Great, so I had the sensors cabled, now it was time to find if they worked.

Test the sensors at CLI

They did! The BMP180 was show at address 0x77 with i2cdetect and the 1-wire DS18B20 gave a reading of 8.875 degrees C.


For reading the data from the sensors I used 2 Python libraries from Adafruit;
Adafruit_DHT and Adafruit_BMP.

Both of which can be installed through Python PIP.

The source can be found on GitHub here and here

The DHT library implements the sensors protocol by bit-banging on the GPIO pin.

For reading the DS18B20 I used a great library from Timo Furrer called w1thermsensor (source) and can installed via PIP.

For acquiring the sensor data, I used Python to query the sensors every 5 seconds and looks a little something like this:

In my complete acquisition script there is a lot more code, for computing averages and saving the database etc but you get the idea.

UPDATE: Source code added to TCC GitLab

As for the Web “App” side of things I took a lot of inspiration from Brett DangerField (website) who used Flask, The Python Web Micro framework to serve the content and the Twitter Bootstrap CSS template.

I opted for gunicorn, A Python WSGI HTTP Server, Flask, Graph.js and jQuery to liven things up.

I’ve added many additional features such as:

  • Ability to view not just a single sensor but all three or one at a time,
  • Real-time data from sensors every 5 seconds,
  • Graphs and Real-time update using AJAX and not page refreshes,
  • Supports HTML5 and Mobile devices,
  • Multiple duration periods, 6 hours to 1 week of data,
  • Multiple granularity levels for data points, 1 minute, 15 minute or 30 minutes.

Page load times are about 1 second without caching.

Next I plan to add a dashboard with Gauge widgets, pressure forecasting and possibly add Wind Speed/Direction and Sunlight if I can find the right sensors.

Even with all that going on with including polling sensors, the CPU is barely touched and there is still plenty of free RAM.

Please Share!Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedIn