Mini-weerstation

      3 reacties op Mini-weerstation

Een derde weerstationproject, maar ditmaal met data van OpenWeatherMap in plaats van data van eigen sensoren, zoals in weerstation-2; en geen database en grafieken zoals in weerstation-1.

weerstation

Het idee

Het idee was om oude en nieuwe techniek op een zinvolle manier te combineren tot een ‘kunstzinnig’ gebruiksvoorwerp, dat opvallend genoeg is om de aandacht te trekken. Het werd een soort ‘black box’ van het weer. Ik heb hiervoor gekozen omdat ik bepaalde weerdata zoals de temperatuur en de windrichting en -snelheid altijd meteen wil kunnen zien, zonder dat ik daarvoor een smartphone moet gaan ontgrendelen of zo.

De mini-oledschermpjes zijn goedkoop en hebben een helder scherm. Een oud vergrootglas dat permanent bevestigd is, is dan handig om de tekst beter te kunnen bekijken. Het idee is een beetje ontleend aan de Monty Python film ‘Brazil’ uit 1985 waarin kleine beeldschermen voorzien waren van een fresnel lens.

weerstation_loep

Het vergrootglas bovenop het houten doosje vergroot de tekst op het scherm maximaal, zodat hij makkelijk leesbaar is.

Black box

Als behuizing dient een oud theedoosje van balsahout. Het schuifdekseltje werd voorzien van een rond gat waarboven het vergrootglas gemonteerd werd. Het oledscherm moest zo dicht mogelijk op de bodem van de box komen, om voldoende afstand tot de lens te hebben.

Het doosje is hoog genoeg, zodat het mini-schermpje op de bodem maximaal vergroot wordt door de loep bovenop het doosje.

Benodigdheden:

  • Raspberry Pi Zero W (+ voeding)
  • Oled-display: SSD1306 (128 x 64 pixels)
  • mini-breadboard
  • jumperkabels
  • klein houten doosje als behuizing
  • vergrootglas
  • API-key bij OpenWeatherMap (free versie)

Bedrading

Vergeet niet om via sudo raspi_config I2C op de Pi Zero te activeren

aansluitingen

Aansluittabel voor I2C OLED mini-display

Code

De code, weerstation.py, is een (niet zo fraaie) combinatie van twee Python3-scripts, maar het werkt. In de eerste plaats is er het officiële voorbeeldscript van Adafruit voor het aansturen van het SSD1306-display en het weergeven van de tekst. Het tweede is een script dat ik vond op geeksforgeeks.org voor het ophalen van de weerdata voor een willekeurige stad van OpenWeatherMap.
De opzet is simpel: cron start ieder kwartier het script om de data op te halen en weer te geven (*/15 * * * *).
NB: Om het script te laten werken is de pigpio-daemon nodig. Die kun je ook weer met cron via @reboot sudo pigpiod automatisch laten starten.

Enkele stukken uit de code van weerstation.py

# import modules
import requests, json
import Adafruit_SSD1306
import Adafruit_GPIO.SPI as SPI
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
[...]

# Load default font.
font = ImageFont.load_default()

### OpenWeatherMap 
api_key = "xxxxxxxxxxxxxxxx"
base_url = "http://api.openweathermap.org/data/2.5/weather?" # base_url variable to store url
city_name = "xxxxx"
units = "metric" # Units: kies standard, metric of imperial (metric levert Celsius op)
language = "nl" # in code van 2 letters

# store complete url address in variable
complete_url = base_url + "appid=" + api_key + "&q=" + city_name + "&units=" + units + "&lang=" + language
[...]

# Storing the weather data in variables
# store the value of "main" key in variable s
s = r["main"]
# store the value of "temp" key of s
current_temperature = s["temp"]
# store the value of "temp_max" key of s
temp_max = s["temp_max"]
# store the value of "temp_min" key of s
temp_min = s["temp_min"]
[...]
######################

# Write lines of text to image buffer of OLED-display.
draw.text((x, top+0), "temperatuur C. = " + str(round(current_temperature, 1)), font=font, fill=255)
[...]

Aanvulling

Voor het omrekenen van de windrichting in graden naar de meer gebruikelijke letteraanduidingen heb ik deze oplossing gevonden op StackOverflow:

def wind_deg_to_str2(deg):
    arr = ['NNO', 'NO', 'ONO', 'O', 'OZO', 'ZO', 'ZZO', 'Z', 'ZZW', 'ZW', 'WZW', 'W', 'WNW', 'NW', 'NNW', 'N']
    return arr[int(abs((deg - 11.25) % 360)/ 22.5)]