Skip to content

skhg/weather-station

Repository files navigation

weather-station

I wanted to experiment with building environmental sensors, and see if I could make homemade electronics that would survive in the outdoors. So I built a weather station based around the Arduino-compatible ESP8266 platform.


Weather station at work, in a light breeze. Most of the fun stuff is hidden inside that grey pipe.

Overview

There are many possible instruments that can be part of a weather station. For the amateur meteorologist, just a few are needed to make a start. They can all be bought cheaply online, and a weatherproof case can be made out of just a few short lengths of PVC piping. Credit to https://sensor.community for inspiration here - I based the system on this reference design, with some additions for the extra sensors I wanted. The software is custom-made. See the references section at the end for many useful links on how to build something similar yourself.

With this system we can measure:

This is a wall-mounted device so wind direction wasn't really something I cared about for this project.

Materials required

Sensors and electronics:

Case construction:

UV Sensor module:

Circuit

The NodeMCU connects directly to the digital devices, and uses a multiplexer to read from the analog output devices. This diagram represents the anemometer as a "motor" - it generates signal pulses as it rotates on an axis.


Circuit overview - export from fritzing file

The perfboard assembly was a little tricky because everything had to fit into a narrow package, and also be screwed on to the air quality board mounted directly underneath. This diagram shows how the two fit together. Those black squares on the perfboard show areas where holes were drilled to join the two together.


Perfboard and external components - export from fritzing file

The UV sensor is itself mounted on a small perfboard, which terminates the connection from the main case (It's mounted about 5m away and connected over Cat5 cable)


UV sensor mini board - export from fritzing file

Assembly

First step was to make sure all the components were working together. I had tested them individually beforehand. Here they're all mounted on a breadboard with external components wired in too.

Next step was soldering the perfboard and mounting the multiplexer, NodeMCU and wiring. Followed by mounting the air quality sensor underneath - with a layer of plastic and foam in between to prevent any short-circuits between exposed pins on the two devices.

And sliding the complete unit into the case:

It's a tight fit!

For the external UV sensor, I made a flat mount on a piece of board and painted it white, to keep moisture out and keep it cool in the sunshine. The UV sensor is protected from moisture by:

  • A white cap from a jar of skin cream
  • A rubber gasket from a coffee mokka
  • An inverted clock glass (with relatively high UV-transmissivity)
  • Some plastic chair leg-ends to clamp it together with some flexibility

Mounted in place

With everything in place and tightly fit together, it was time to install it in place on the balcony. We have a drainpipe that was a convenient place to attach it, as you can see in the introduction.


View from underneath. Holes for external connections in the middle here.


Views from the ends of either side of the main tube.
Left: air intake tube and BME280 sensor. Right: rear of the SDS011 and exposed cabling.

Onboard software

The onboard software runs in a continuous loop. It captures the data, packages the results in a JSON blob, and sends them to a logging server on the local LAN. In case of any errors connecting to WiFi or to this server, it does a hard reboot. This is sufficient since the data is not time-critical, and up-to-date data is less important than an hourly/daily trend.

Data Capture and Visualisation

Readings are packaged as a JSON blob and sent to a logging server on the local LAN, using a REST POST over HTTP. A sample message looks like:

{
    "temperatureC" : 21.2,
    "humidityPercentage" : 34.2,
    "airPressurePa" : 1001000.2,
    "uvIntensityMilliwattsPerCmSq" : 3.2,
    "rainfallStrengthPercentage" : 10.2,
    "pm25density" : 10.1,
    "pm10density" : 9.8,
    "windSpeedKmPerHour" : 0.67
}

The logging server is a custom Spring Boot application. It logs the data to InfluxDB, a time-series database. Grafana is used for visualising the data.


Screenshots of sample data from the Grafana dashboard.
Left: 24 hours of data. Right: 6 months of data.

Performance over time

It survived its first summer with months of direct sunlight and internal temperatures up to 37°C. Will it survive its first winter, with ice and snow? Time will tell...

As of November 2020 it's been outside for over 6 months and still works, data seems consistent and matches what I see from the official weather reports. The only component that has significantly degraded is the rainfall sensor, which gives junk results now. Constant rainfall has eroded the resistive surface and left some kind of rust all over it. This should be replaced.

Future enhancements

Rainfall sensor:

  • Replace with a better device that will not degrade so much over time. A capacitive option might be a good alternative with no moving parts.

Remove multiplexer:

  • I think I had some issues with analogue data reads the first time around, but it appears that the multiplexer board isn't actually required. I would remove this next time and connect external devices directly to the NodeMCU board.

Submit data online:

Data validation:

  • The onboard software does no sanity checking of the data it reports back to the server. On at least one occasion this meant it reported a temperature of -143°C which was fixed by a hard reboot.
  • The software should include some hardcoded bounds outside which it will report an error status back to the server.

Case construction:

  • The anemometer is mounted into a hole drilled in the pipe cleaning cap. Next time I would rather mount the anemometer into a bracket that clips on top of that cap. Having a hole that has to be sealed with PTFE, right above the electronics, is likely to eventually fail due to water accumulation.
  • All the external connectors (USB power in, rainfall sensor, UV sensor, and anemometer cable) are routed through holes drilled in the bottom of the case. This doesn't look great, and makes it awkward/imposssible to disconnect them without disassembling the whole thing.
  • I would like to build a small "patch panel" with JST connectors for all the external connections, that would be flat-mounted on the bottom of the case. A single USB connection for power/data would also be located here, so everything could be disconnected as needed without needing to open the whole thing up.

Air intake tube mount:

  • A 3D-printed mount for the air intake tube, like this one, would make the case look nicer and more professionally finished.

References