Ramblings of an aging IT geek
← Ramblings of an aging IT geek
hardware

the weather station on my shed roof, and the bits that lie to me

Building an ESP32 weather station from a BME280, a reed-switch anemometer and a tipping bucket, and learning which of its readings to trust and which to quietly ignore.

A soldering iron resting next to an ESP32 board and a tangle of jumper wires

There is a weather station bolted to my shed roof. It has been there for three weeks now, and it reports temperature, humidity, pressure, wind speed and rainfall to a little dashboard in my house. About two of those five numbers are trustworthy at any given moment, and the fun of the project has been working out which two, and why the other three lie.

I want to be honest up front: this is not a precision instrument. It is an ESP32, a handful of cheap sensors, and a lot of optimism held together with hot glue. But it works well enough that I now glance at it before deciding whether to cycle to the shops, and that is more than I expected when I started.

The parts

The brain is a bog-standard ESP32 dev board, the kind that costs a couple of quid and has more pins than I will ever use. Around it:

  • A BME280 for temperature, humidity and pressure, over I2C.
  • A reed-switch anemometer and wind vane salvaged from a dead consumer weather station a neighbour was throwing out.
  • A tipping-bucket rain gauge from the same casualty.
  • A small solar panel and a LiPo, because running mains to a shed roof was never going to happen.

The BME280 is the good one. It is genuinely accurate, well behaved, and the libraries for it are mature. If you only want indoor conditions or a rough outdoor temperature, buy one, wire up three pins, and you are done in an afternoon. Mine reads pressure to within a hair of what the Met Office says for my area, which is faintly thrilling the first time you see it.

A close-up of a circuit board with sensors and jumper wires

The temperature lie

Here is the first thing nobody tells you. The BME280 reports temperature beautifully, and that temperature is wrong, because it is sitting in a sealed box in direct sun on a shed roof. By midday the enclosure was reading 41°C on a day that was, generously, 22°C outside. The sensor was not faulty. The sensor was reporting the temperature inside a small black plastic oven, accurately.

The fix is a radiation shield, the stack of white stacked plates you see on proper weather stations, which lets air flow past the sensor whilst keeping sun and rain off it. I printed one. It helped enormously, dropping the midday error from about nineteen degrees to about two. Two degrees is still not great, but it is the difference between "useless" and "roughly right", and roughly right is all I wanted.

The lesson here is older than electronics: the thing you measure is never quite the thing you care about. I wanted air temperature. I was measuring the temperature of a box. Closing that gap was most of the work.

Wind, and the magic of debouncing

The anemometer is a reed switch. It closes once per rotation as a magnet passes. Count the closures over a fixed window, do some arithmetic with the cup radius, and you have wind speed. Simple.

Except a reed switch bounces. Every closure is actually a tiny burst of closures as the contacts chatter, and if you count naively you get wind speeds that would concern a meteorologist. My first run reported a gentle breeze as a category-two hurricane.

volatile unsigned long lastTick = 0;
volatile unsigned int windCount = 0;

void IRAM_ATTR onWindPulse() {
  unsigned long now = millis();
  if (now - lastTick > 15) {   // ignore bounces within 15ms
    windCount++;
    lastTick = now;
  }
}

Fifteen milliseconds of debounce was the magic number for my switch. Below that I caught bounces; above it I started missing genuine fast rotations. I found it by sticking a cheap fan in front of the cups and watching the count, which is not science, but it got me a value that produces believable numbers.

The wind vane is worse. It is a ring of resistors and a wiper, so each direction maps to a voltage you read on an ADC pin. The ESP32's ADC is famously non-linear and noisy, so the boundaries between "north-east" and "east" wander about. I gave up on degrees and now report one of eight compass points, which is all the precision the hardware can honestly support anyway.

Rain, and the bucket that tips

The tipping bucket is my favourite part, because it is delightfully mechanical. Rain fills a tiny see-saw bucket; when it is full enough it tips, dumps the water, and the other side starts filling. Each tip closes a reed switch and corresponds to a known volume of rain, in my case 0.2794mm per tip, a number I had to look up and do not fully trust.

It uses the same debounce trick as the wind, just with a longer window because the bucket physically cannot tip more than a few times a second even in a downpour. I count tips, multiply by the per-tip volume, and accumulate. The only way to check it properly is to pour a measured amount of water through it and count, which I did, on the kitchen table, feeling slightly daft.

A macro shot of a soldered sensor module on a breadboard

Power, and the deep sleep that broke everything

The plan was: read sensors, send data over WiFi, deep sleep for thirty seconds, repeat. Deep sleep is what makes a solar-powered ESP32 viable, because the chip draws milliamps awake and microamps asleep.

The problem is that the anemometer and rain gauge are interrupt-driven and event-based. Wind blows continuously and rain tips at unpredictable moments, and if the chip is asleep it counts nothing. So I cannot deep sleep through wind and rain measurement, but I must deep sleep to survive on solar. These two requirements are in direct opposition, and I have not fully resolved them.

The current compromise is light sleep rather than deep sleep, where the chip stays awake enough to service interrupts but throttles the clock. It uses more power than I would like, and on a string of grey days the battery sags. If we get a properly overcast week I expect it to go dark, and I will have to decide whether to add a bigger panel or accept gaps in the rain record. For now, in June, the sun is doing the work.

What it is actually for

None of this is necessary. There is a weather forecast on my phone, produced by people with supercomputers and actual instruments, and it is better than anything on my shed will ever be. I know this.

But the forecast does not tell me that it is, right now, raining on my shed specifically, which on a British afternoon is a more useful fact than any regional outlook. And more honestly, the point was never the data. The point was the wiring, the debounce hunt, the radiation shield, the slightly absurd evening pouring water through a plastic see-saw on the kitchen table. The weather station mostly works. The me that built it works rather better than it did before, which was the actual goal.