logzly. Pi Projects Hub

Build a Standalone Weather Station with a Raspberry Pi and Open‑Source Sensors

Read this article in clean Markdown format for LLMs and AI context.

Ever looked out the window and wondered why the forecast keeps missing the mark? A personal weather station lets you collect the data you actually care about, right from your backyard. Plus, it’s a great excuse to dust off that Pi you’ve been hoarding for “later.” In this post I’ll walk you through a simple, low‑cost setup that runs on a Raspberry Pi, a few open‑source sensors, and a bit of code you can tweak as you like.

What You’ll Need

The Pi

Any model that has GPIO pins will do, but I recommend a Pi 4 with at least 2 GB RAM. The extra RAM helps when you start logging data to a local database or serving a web page. If you’re tight on budget, a Pi Zero W works fine – just remember the Wi‑Fi antenna is a bit weaker.

Sensors

Sensor What it measures Typical price
BME280 Temperature, humidity, pressure $8‑$12
Anemometer (DIY or commercial) Wind speed $10‑$20
Rain gauge (tipping bucket) Rainfall amount $5‑$10
Light sensor (TSL2591) Ambient light $4‑$6

All of these have open‑source libraries for Python, which keeps the code tidy. You can start with just the BME280 and add the others later.

Other Bits

  • Micro‑SD card (16 GB or more) with Raspberry Pi OS Lite
  • Power supply (5 V 2.5 A for Pi 4, 5 V 1.2 A for Pi Zero)
  • Small enclosure or weatherproof box – I used a recycled plastic storage bin and drilled holes for the sensors.
  • Jumper wires, breadboard, and a few zip ties

Wiring the Sensors

BME280

The BME280 talks over I²C, which means you only need two wires: SDA (data) and SCL (clock). Connect SDA to GPIO 2 (pin 3) and SCL to GPIO 3 (pin 5). Power the sensor with 3.3 V (pin 1) and ground to any GND pin.

Anemometer

Most hobby anemometers output a pulse each time the cup spins. Hook the pulse wire to a GPIO pin set as input (I use GPIO 17). Add a 10 kΩ pull‑down resistor to keep the line low when there’s no pulse.

Rain Gauge

A tipping‑bucket gauge works the same way as the anemometer – each tip generates a pulse. I wired it to GPIO 27 with the same pull‑down setup.

Light Sensor

The TSL2591 also uses I²C, so you can share the SDA and SCL lines with the BME280. Just make sure each device has a unique address; the libraries handle that automatically.

Setting Up the Software

1. Install the OS

Flash Raspberry Pi OS Lite onto the SD card, boot the Pi, and run sudo raspi-config to enable I²C and SSH. I like to give the Pi a static IP so I can reach it easily from my laptop.

2. Install Python Libraries

sudo apt update
sudo apt install -y python3-pip i2c-tools
pip3 install adafruit-circuitpython-bme280 adafruit-circuitpython-tslpython-tsl2591 RPi.GPIO

The RPi.GPIO library lets us count pulses from the anemometer and rain gauge.

3. Write a Simple Data Logger

Create a file called weather_station.py. Below is a stripped‑down version that reads all sensors and writes a CSV line every minute.

#!/usr/bin/env python3
import time, csv, datetime
import board, busio
import adafruit_bme280
import adafruit_tsl2591
import RPi.GPIO as GPIO

# --- GPIO setup ---
ANEMO_PIN = 17
RAIN_PIN  = 27
GPIO.setmode(GPIO.BCM)
GPIO.setup(ANEMO_PIN, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(RAIN_PIN,  GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

# counters
wind_count = 0
rain_count = 0

def anemo_callback(channel):
    global wind_count
    wind_count += 1

def rain_callback(channel):
    global rain_count
    rain_count += 1

GPIO.add_event_detect(ANEMO_PIN, GPIO.RISING, callback=anemo_callback, bouncetime=10)
GPIO.add_event_detect(RAIN_PIN,  GPIO.RISING, callback=rain_callback,  bouncetime=10)

# --- I2C sensors ---
i2c = busio.I2C(board.SCL, board.SDA)
bme = adafruit_bme280.Adafruit_BME280_I2C(i2c)
light = adafruit_tsl2591.TSL2591(i2c)

# calibration constants
WIND_FACTOR = 2.4   # km/h per pulse (depends on your anemometer)
RAIN_FACTOR = 0.279 # mm per tip (depends on gauge)

def log_data():
    global wind_count, rain_count
    now = datetime.datetime.utcnow().isoformat()
    temperature = bme.temperature
    humidity    = bme.relative_humidity
    pressure    = bme.pressure
    lux         = light.lux
    wind_speed  = wind_count * WIND_FACTOR
    rain_mm     = rain_count * RAIN_FACTOR

    row = [now, temperature, humidity, pressure, lux, wind_speed, rain_mm]
    with open('weather_log.csv', 'a', newline='') as f:
        writer = csv.writer(f)
        writer.writerow(row)

    # reset counters for next interval
    wind_count = 0
    rain_count = 0

if __name__ == '__main__':
    # write header once
    with open('weather_log.csv', 'w', newline='') as f:
        writer = csv.writer(f)
        writer.writerow(['timestamp','temp_C','humidity_%','pressure_hPa','lux','wind_kmh','rain_mm'])

    while True:
        log_data()
        time.sleep(60)   # wait one minute

The script does three things:

  1. Counts pulses from the wind and rain sensors.
  2. Reads temperature, humidity, pressure, and light.
  3. Writes everything to a CSV file that you can later import into Excel or Grafana.

4. Run It as a Service

You don’t want to have to log in and start the script every time the Pi boots. Create a systemd service:

[Unit]
Description=Raspberry Pi Weather Station
After=network.target

[Service]
ExecStart=/usr/bin/python3 /home/pi/weather_station.py
WorkingDirectory=/home/pi
StandardOutput=inherit
StandardError=inherit
Restart=always
User=pi

[Install]
WantedBy=multi-user.target

Save this as /etc/systemd/system/weather.service, then enable it:

sudo systemctl daemon-reload
sudo systemctl enable weather.service
sudo systemctl start weather.service

Now the station runs in the background, even after a power cut.

Visualizing the Data

If you’re comfortable with a bit of web work, I like to throw the CSV into Grafana using the built‑in SimpleJSON data source. For a quick look, you can also install flask and serve a tiny page that reads the latest line and shows a pretty chart with Chart.js. The code is a few dozen lines and lives in the same repo as the logger.

Protecting Your Hardware

A weather station lives outside, so waterproofing is key. I used silicone sealant around every wire entry point and added a small vent with a breathable membrane to let pressure equalize without letting water in. The BME280 is rated for outdoor use, but the PCB can still corrode over time, so a thin layer of conformal coating helps.

Don’t forget to give the Pi some ventilation. A small heat‑sink on the CPU and a tiny fan (powered from the Pi’s 5 V rail) keep the board from throttling on hot summer days.

Going Further

  • Add a solar panel – a 5 V panel with a charge controller can keep the Pi running forever, even on cloudy days.
  • Push data to an online service – Thingspeak or InfluxDB Cloud let you see your station alongside others worldwide.
  • Add alerts – Use smtplib to email you when temperature drops below a threshold, or when rain starts. Pair this with a smart plant care system to also monitor soil moisture.

Building a weather station is a perfect blend of hardware tinkering and software fun. You get instant feedback, you learn how to read sensor data, and you end up with a useful tool that beats any generic forecast. Grab that Pi, solder a few pins, and let the sky be your lab.

Reactions
Do you have any feedback or ideas on how we can improve this page?