---
title: Build a Standalone Weather Station with a Raspberry Pi and Open‑Source Sensors
siteUrl: https://logzly.com/piprojectshub
author: piprojectshub (Pi Projects Hub)
date: 2026-06-16T15:21:50.526543
tags: [weather, raspberrypi, diyelectronics]
url: https://logzly.com/piprojectshub/build-a-standalone-weather-station-with-a-raspberry-pi-and-opensource-sensors
---


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](/piprojectshub/turning-a-raspberry-pi-zero-into-a-lowpower-home-automation-hub) 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

```bash
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.

```python
#!/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:

```ini
[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:

```bash
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](/piprojectshub/create-a-raspberry-pi-based-smart-plant-care-system-in-a-weekend) 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.