The weather station works. I want to be clear about that before I spend several hundred words on the ways it does not, because "mostly works" is, for a garden hardware project, a genuine win. It has been sitting on a fence post for three weeks reporting temperature, humidity and pressure to Home Assistant every thirty seconds, and the graphs are smooth and plausible. Right up until about two o'clock on a sunny afternoon, when it confidently announces it is 41 degrees in suburban England.
It is not 41 degrees. It is the sensor, baking. A BME280 in a little plastic enclosure with the afternoon sun on it will happily report the temperature of its own micro-greenhouse, which has nothing to do with the air. This is the oldest mistake in amateur weather sensing and I made it anyway, because I was thinking about the firmware and not about physics.
The electronics side went fine, which is what lulled me. An ESP32, a BME280 on I2C, deep sleep between readings so it sips power, and the whole thing runs off a small solar cell and a LiPo. The wiring is nothing.
#include <Wire.h>
#include <Adafruit_BME280.h>
Adafruit_BME280 bme;
void setup() {
Wire.begin();
bme.begin(0x76);
float tempC = bme.readTemperature();
// publish over MQTT, then back to sleep
esp_sleep_enable_timer_wakeup(30 * 1000000ULL);
esp_deep_sleep_start();
}
That part has not missed a reading. Deep sleep behaves, the solar cell keeps the battery topped, MQTT reconnects cleanly after each wake. If the only thing I cared about was humidity and pressure I would call it finished and go inside, because those two are fine; humidity is a bit lazy to respond but it is not lying to me the way the temperature is.
The fix for the temperature is not code, it is a Stevenson screen, which is a fancy name for "put the sensor in a stack of white louvred shields so air moves through it but sunlight does not." Proper ones are a known shape for a known reason. I have a 3D-printed one half-designed and a vague plan to mount the sensor away from the enclosure entirely, on a little arm in the shade, so the electronics can bake in their box while the sensor sits in moving air like it is supposed to.
Until then I have done the lazy thing and told Home Assistant to distrust the daytime temperature, which is to say I added a template that flags any reading climbing faster than the air plausibly can. It does not make the number right. It just stops the heating logic downstream from believing a sensor that is, for a few hours each sunny day, essentially making things up. Which is a fitting summary of the whole build, really: the hard part was never the silicon. It was remembering that the thing lives outdoors, and outdoors does not care how tidy your I2C bus is.