Wettersensor

Nach so viel Theorie zum I²C Bus widmen wir uns jetzt mal einem praktischen Beispiel und schließen einen Wettersensor an den Raspberry Pi an.

Material

  • Raspberry Pi 4B
  • BME280 Wettersensor auf einem Breakoutboard (Waveshare)
  • MicroSD Karte (8-32GB)
  • optional LCD 1602 Modul I²C (Waveshare)

Wettersensor BME280

BME280 Wettersensor auf Waveshare Breakoutboard
BME280 Wettersensor auf Waveshare Breakoutboard

Der BME280 Wettersensor von Bosch ist sehr beliebt, da er sehr klein ist und Daten über Temperatur, Luftfeuchtigkeit und Luftdruck zur Verfügung stellen kann.

Das Breakoutboard von Waveshare integriert den Sensor und stellt uns die Messdaten als I²C Target zur Verfügung. Das Waveshare Board wird komplett mit Kabelsatz geliefert, den du auf der einen Seite nur ins Board stecken musst und auf der anderen Seite mit den GPIO Pins des Raspberry Pi oder Pico verbindest.

Hardwareaufbau

Das Waveshare Breakoutboard hat fünf Anschlüsse. Diese haben mit dem mitgelieferten Kabelsatz folgende Farbcodierung:

  • Masse – schwarz
  • VCC+ – rot
  • SDA – blau
  • SCL – gelb
  • ADDR – orange
  • CS – grün bei I²C nicht belegt, schaltet den Chip auf SPI um, wenn auf Masse gelegt.
Anschluss des BME280 an den Raspberry Pi 4B
Olli Graf -raspithek.de
bme280-rp4Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License . loading=
Anschluss des BME280 an den Raspberry Pi 4B

mit dem orangenen Kabel kannst du die Adresse des Sensors am I²C Bus auswählen. Ist es nicht verbunden, hat er die Adresse 0x77, wird er auf Masse gelegt, wird sie auf 0x76 geändert. Falls bei dir kein anderes Target die 0x77 beanspruchen, musst du das orangene Kabel nicht anschließen. Da wir das grüne Kabel nicht verwenden, habe ich es Schaltbild oben weggelassen.

BME280 am Raspberry Pi 4
Olli Graf - raspithek.de
bme280-rpi4Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License . loading=
BME280 am Raspberry Pi 4

Raspberry Pi konfigurieren

Um den Sensor verwenden zu können, musst du zunächst das Betriebssystem konfigurieren. Bei Raspberry Pi OS

geht das über sudo raspi-config im Menüpunkt „Interface Options/I2C„.

Bei DietPi über sudo dietpi-config mit „Advanced Options/I2C State„.

Ich verwende meinen DietPi Raspi, der zur besseren Erkennbarkeit mit einem farbcodierten GPIO Header bestückt ist. Über pip installierst du jetzt die Library zu Kommunikation mit dem Sensor. Außerdem brauchen wir noch das i2c-tools Package

pip install RPi.bme280
sudo apt install i2c-tools

I²C Bus scannen

Wenn du den BME280 wie oben angeschlossen hast, kannst du mit

i2cdetect -y 1

den Bus scannen. Die Ausgabe müsste dann so sein:

Ausgabe von i2detect zeigt den Wettersensor mit der Adresse 0x76 am Bus
Olli Graf -raspithek.de
i2cdetect-bme280Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License . loading=
Ausgabe von i2detect zeigt den Wettersensor mit der Adresse 0x76 am Bus

Der Wettersensor ist jetzt einsatzbereit und unter der Adresse 0x76 am Bus erreichbar. Wenn du das orangefarbene Kabel jetzt von GND am Raspi abziehst, wechselt die Adresse auf 0x77.

Wir wollen im weiteren mit einem kleinen Pythonprogramm die Daten für Temperatur, Luftdruck und -feuchtigkeit auslesen und in einer Datenbanktabelle speichern.

Datenbank einrichten

In der MariaDB erstellst du eine Datenbank für die Wetterdaten

create user 'ploeger'@'192.168.178.%' identified by '<passwort>';
create database weather;
grant all privileges on weather.* to 'ploeger'@'192.168.178.%';
flush privileges;

Für <passwort> setzt du bitte dein eigenes sicheres Passwort ein. Ggf. musst du auch die IP Adresse an dein Heimnetz anpassen. Den Usernamen kannst du frei wählen.

Als nächstes benötigst du eine Tabelle, die die Messwerte des Sensors aufnimmt.

CREATE TABLE `stats` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `datum` datetime DEFAULT NULL,
  `temperature` float DEFAULT NULL,
  `humidity` float DEFAULT NULL,
  `pressure` float DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci;

Datenbankparameter

Die Parameter, die unser Programm für die Verbindung zur Datenbank benötigt, lege ich, wie schonmal gezeigt in eine externe Datei db.ini

[weatherdb]
host=database
user=ploeger
password=<passwort>
database=weather

Im Repository liegt sie unter db.ini.sample, die du für dich anpassen und nach db.ini umbenennen musst.

Python

Das Programm soll alle 10 Sekunden die Sensordaten auslesen und dann in den Jogger und in die Datenbanktabelle schreiben. Falls du die DB nicht benutzen möchtest, lass diese Programmzeilen einfach weg.

#!/usr/bin/env python3

import time
import configparser
import logging
import bme280
try:
    import smbus2
except ImportError: # Wenn smbus2 nicht zu importieren ist, nehmen wir smbus
    from smbus import SMBus
import mysql.connector

port = 1
# Der BME280 ist auf Meerehöhe kalibriert, so dass der gelieferte Luftdruck
# vom tatsächlichen Druck am Ort abweicht. Dies müssen wir hier ausgleichen.
__luftdruck_kalibrierung__ = 296	# Kalibrierung auf ortsbezogenen Luftdruck

adresse_bme280 = 0x76
adresse_lcd1602 = 0x25

logging.basicConfig( format='%(asctime)s [%(levelname)s] %(funcName)s: %(message)s', level=logging.DEBUG)


def info(msg):
  logging.info(msg)

def debug(msg):
  logging.debug(msg)

# Datenbankverbindung herstellen.
config = configparser.ConfigParser()
config.read('db.ini')
mydb = mysql.connector.connect(host=config['weatherdb']['host'], user=config['weatherdb']['user'],password=config['weatherdb']['password'],database =config['weatherdb']['database'])
mycursor = mydb.cursor()
debug('Datenverbindung hergestellt.')


# BME280 initialisieren
bus = smbus2.SMBus(port)
calibration_params = bme280.load_calibration_params(bus, adresse_bme280)
debug('Sensor kalibriert.')
while True:
 data = bme280.sample(bus, adresse_bme280, calibration_params)
 

 temperature = data.temperature
 pressure = data.pressure + __luftdruck_kalibrierung__
 humidity = data.humidity
 info('{:05.2f}°C {:05.2f}hPa {:05.2f}%'.format(temperature, pressure, humidity))

 sql = 'INSERT into stats (datum,temperature, humidity, pressure) VALUES(now(), %s, %s, %s)'
 val = (temperature, humidity, pressure)

 mycursor.execute(sql, val)
 mydb.commit()
 time.sleep(10)

Herausheben möchte ich nur die Zeile

calibration_params = bme280.load_calibration_params(bus, adresse_bme280)

Sie dient dazu, die Messgenauigkeit des BME280 zu verbessern, in dem er auf die aktuelle Situation kalibriert wird. Solltest du eine BME280 Library verwenden, die diese Methode nicht zur Verfügung stellt, kannst du dich damit behelfen, das erste Messwert-Tupel zu überlesen.

Da der BME280 auf Meereshöhe kalibriert ist, weicht der gemessene Wert für den Luftdruck vermutlich vom tatsächlichen Wert ab. Du musst für deinen Ort den aktuellen Luftdruck ermitteln und die Differenz zwischen diesem und dem Sensorwert in die Variable luftdruck_kalibrierung eintragen. Je höher du über Normal Null (NN) wohnst, desto höher ist dieser Korrekturwert, da der Luftdruck mit zunehmender Höhe abnimmt (um etwa 1hPa pro 8m).

LCD1602 Display

Ich wollte dir in diesem Post noch zeigen, wie du ein LC-Display zur Ausgabe der Wetterdaten anschließt, aber daraus mache ich besser einen eigenständigen Post.

Hier noch fix der URL zum GIT Repo.

Schreibe einen Kommentar

Creative Commons License
Except where otherwise noted, the content on this site is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
Olli Graf - raspithek.de
WordPress Cookie Hinweis von Real Cookie Banner