Upload files to ''

This commit is contained in:
Walter Gussmann 2018-06-30 10:52:49 +02:00
parent c71b75b962
commit c9cc243a30
3 changed files with 309 additions and 30 deletions

214
Adafruit_BME280.py Normal file
View File

@ -0,0 +1,214 @@
# Copyright (c) 2014 Adafruit Industries
# Author: Tony DiCola
#
# Based on the BMP280 driver with BME280 changes provided by
# David J Taylor, Edinburgh (www.satsignal.eu)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import logging
import time
# BME280 default address.
BME280_I2CADDR = 0x77
# Operating Modes
BME280_OSAMPLE_1 = 1
BME280_OSAMPLE_2 = 2
BME280_OSAMPLE_4 = 3
BME280_OSAMPLE_8 = 4
BME280_OSAMPLE_16 = 5
# BME280 Registers
BME280_REGISTER_DIG_T1 = 0x88 # Trimming parameter registers
BME280_REGISTER_DIG_T2 = 0x8A
BME280_REGISTER_DIG_T3 = 0x8C
BME280_REGISTER_DIG_P1 = 0x8E
BME280_REGISTER_DIG_P2 = 0x90
BME280_REGISTER_DIG_P3 = 0x92
BME280_REGISTER_DIG_P4 = 0x94
BME280_REGISTER_DIG_P5 = 0x96
BME280_REGISTER_DIG_P6 = 0x98
BME280_REGISTER_DIG_P7 = 0x9A
BME280_REGISTER_DIG_P8 = 0x9C
BME280_REGISTER_DIG_P9 = 0x9E
BME280_REGISTER_DIG_H1 = 0xA1
BME280_REGISTER_DIG_H2 = 0xE1
BME280_REGISTER_DIG_H3 = 0xE3
BME280_REGISTER_DIG_H4 = 0xE4
BME280_REGISTER_DIG_H5 = 0xE5
BME280_REGISTER_DIG_H6 = 0xE6
BME280_REGISTER_DIG_H7 = 0xE7
BME280_REGISTER_CHIPID = 0xD0
BME280_REGISTER_VERSION = 0xD1
BME280_REGISTER_SOFTRESET = 0xE0
BME280_REGISTER_CONTROL_HUM = 0xF2
BME280_REGISTER_CONTROL = 0xF4
BME280_REGISTER_CONFIG = 0xF5
BME280_REGISTER_PRESSURE_DATA = 0xF7
BME280_REGISTER_TEMP_DATA = 0xFA
BME280_REGISTER_HUMIDITY_DATA = 0xFD
class BME280(object):
def __init__(self, mode=BME280_OSAMPLE_1, address=BME280_I2CADDR, i2c=None,
**kwargs):
self._logger = logging.getLogger('Adafruit_BMP.BMP085')
# Check that mode is valid.
if mode not in [BME280_OSAMPLE_1, BME280_OSAMPLE_2, BME280_OSAMPLE_4,
BME280_OSAMPLE_8, BME280_OSAMPLE_16]:
raise ValueError(
'Unexpected mode value {0}. Set mode to one of BME280_ULTRALOWPOWER, BME280_STANDARD, BME280_HIGHRES, or BME280_ULTRAHIGHRES'.format(mode))
self._mode = mode
# Create I2C device.
if i2c is None:
import Adafruit_GPIO.I2C as I2C
i2c = I2C
self._device = i2c.get_i2c_device(address, **kwargs)
# Load calibration values.
self._load_calibration()
self._device.write8(BME280_REGISTER_CONTROL, 0x3F)
self.t_fine = 0.0
def _load_calibration(self):
self.dig_T1 = self._device.readU16LE(BME280_REGISTER_DIG_T1)
self.dig_T2 = self._device.readS16LE(BME280_REGISTER_DIG_T2)
self.dig_T3 = self._device.readS16LE(BME280_REGISTER_DIG_T3)
self.dig_P1 = self._device.readU16LE(BME280_REGISTER_DIG_P1)
self.dig_P2 = self._device.readS16LE(BME280_REGISTER_DIG_P2)
self.dig_P3 = self._device.readS16LE(BME280_REGISTER_DIG_P3)
self.dig_P4 = self._device.readS16LE(BME280_REGISTER_DIG_P4)
self.dig_P5 = self._device.readS16LE(BME280_REGISTER_DIG_P5)
self.dig_P6 = self._device.readS16LE(BME280_REGISTER_DIG_P6)
self.dig_P7 = self._device.readS16LE(BME280_REGISTER_DIG_P7)
self.dig_P8 = self._device.readS16LE(BME280_REGISTER_DIG_P8)
self.dig_P9 = self._device.readS16LE(BME280_REGISTER_DIG_P9)
self.dig_H1 = self._device.readU8(BME280_REGISTER_DIG_H1)
self.dig_H2 = self._device.readS16LE(BME280_REGISTER_DIG_H2)
self.dig_H3 = self._device.readU8(BME280_REGISTER_DIG_H3)
self.dig_H6 = self._device.readS8(BME280_REGISTER_DIG_H7)
h4 = self._device.readS8(BME280_REGISTER_DIG_H4)
h4 = (h4 << 24) >> 20
self.dig_H4 = h4 | (self._device.readU8(BME280_REGISTER_DIG_H5) & 0x0F)
h5 = self._device.readS8(BME280_REGISTER_DIG_H6)
h5 = (h5 << 24) >> 20
self.dig_H5 = h5 | (
self._device.readU8(BME280_REGISTER_DIG_H5) >> 4 & 0x0F)
'''
print '0xE4 = {0:2x}'.format (self._device.readU8 (BME280_REGISTER_DIG_H4))
print '0xE5 = {0:2x}'.format (self._device.readU8 (BME280_REGISTER_DIG_H5))
print '0xE6 = {0:2x}'.format (self._device.readU8 (BME280_REGISTER_DIG_H6))
print 'dig_H1 = {0:d}'.format (self.dig_H1)
print 'dig_H2 = {0:d}'.format (self.dig_H2)
print 'dig_H3 = {0:d}'.format (self.dig_H3)
print 'dig_H4 = {0:d}'.format (self.dig_H4)
print 'dig_H5 = {0:d}'.format (self.dig_H5)
print 'dig_H6 = {0:d}'.format (self.dig_H6)
'''
def read_raw_temp(self):
"""Reads the raw (uncompensated) temperature from the sensor."""
meas = self._mode
self._device.write8(BME280_REGISTER_CONTROL_HUM, meas)
meas = self._mode << 5 | self._mode << 2 | 1
self._device.write8(BME280_REGISTER_CONTROL, meas)
sleep_time = 0.00125 + 0.0023 * (1 << self._mode)
sleep_time = sleep_time + 0.0023 * (1 << self._mode) + 0.000575
sleep_time = sleep_time + 0.0023 * (1 << self._mode) + 0.000575
time.sleep(sleep_time) # Wait the required time
msb = self._device.readU8(BME280_REGISTER_TEMP_DATA)
lsb = self._device.readU8(BME280_REGISTER_TEMP_DATA + 1)
xlsb = self._device.readU8(BME280_REGISTER_TEMP_DATA + 2)
raw = ((msb << 16) | (lsb << 8) | xlsb) >> 4
return raw
def read_raw_pressure(self):
"""Reads the raw (uncompensated) pressure level from the sensor."""
"""Assumes that the temperature has already been read """
"""i.e. that enough delay has been provided"""
msb = self._device.readU8(BME280_REGISTER_PRESSURE_DATA)
lsb = self._device.readU8(BME280_REGISTER_PRESSURE_DATA + 1)
xlsb = self._device.readU8(BME280_REGISTER_PRESSURE_DATA + 2)
raw = ((msb << 16) | (lsb << 8) | xlsb) >> 4
return raw
def read_raw_humidity(self):
"""Assumes that the temperature has already been read """
"""i.e. that enough delay has been provided"""
msb = self._device.readU8(BME280_REGISTER_HUMIDITY_DATA)
lsb = self._device.readU8(BME280_REGISTER_HUMIDITY_DATA + 1)
raw = (msb << 8) | lsb
return raw
def read_temperature(self):
"""Gets the compensated temperature in degrees celsius."""
# float in Python is double precision
UT = float(self.read_raw_temp())
var1 = (UT / 16384.0 - self.dig_T1 / 1024.0) * float(self.dig_T2)
var2 = ((UT / 131072.0 - self.dig_T1 / 8192.0) * (
UT / 131072.0 - self.dig_T1 / 8192.0)) * float(self.dig_T3)
self.t_fine = int(var1 + var2)
temp = (var1 + var2) / 5120.0
return temp
def read_pressure(self):
"""Gets the compensated pressure in Pascals."""
adc = self.read_raw_pressure()
var1 = self.t_fine / 2.0 - 64000.0
var2 = var1 * var1 * self.dig_P6 / 32768.0
var2 = var2 + var1 * self.dig_P5 * 2.0
var2 = var2 / 4.0 + self.dig_P4 * 65536.0
var1 = (
self.dig_P3 * var1 * var1 / 524288.0 + self.dig_P2 * var1) / 524288.0
var1 = (1.0 + var1 / 32768.0) * self.dig_P1
if var1 == 0:
return 0
p = 1048576.0 - adc
p = ((p - var2 / 4096.0) * 6250.0) / var1
var1 = self.dig_P9 * p * p / 2147483648.0
var2 = p * self.dig_P8 / 32768.0
p = p + (var1 + var2 + self.dig_P7) / 16.0
return p
def read_humidity(self):
adc = self.read_raw_humidity()
# print 'Raw humidity = {0:d}'.format (adc)
h = self.t_fine - 76800.0
h = (adc - (self.dig_H4 * 64.0 + self.dig_H5 / 16384.8 * h)) * (
self.dig_H2 / 65536.0 * (1.0 + self.dig_H6 / 67108864.0 * h * (
1.0 + self.dig_H3 / 67108864.0 * h)))
h = h * (1.0 - self.dig_H1 * h / 524288.0)
if h > 100:
h = 100
elif h < 0:
h = 0
return h

104
README.md
View File

@ -1,30 +1,74 @@
# Wetterstation
Aufbau einer Wetterstation mit Raspberry Pi und mehreren Sensoren - Programmiersprache: Python
## Bauteile:
Raspberry Pi 3 (funktioniert auch mit Version 2)
BME280 - Sensor zur Erfassung von Temperatur, Druck, Luftfeuchtigkeit (Bezug: Watterott.com)
BMP280 - Sensor zur Erfassung von Temperatur, Druck (Bezugs: Adafruit)
Die Sensoren gibt es auch sehr preisgünstig über ebay aus China
## Messung
Die Wetterdaten werden alle 15 Minuten gemessen und in einer externen MySQL-Datenbank gespeichert. Ein Webserver liest diese Daten aus und stellt die Daten grafisch dar.
Beispiel: https://gussmann-berlin.de/wetter/wetterhome.php
![Example](img/wetter.png)
## Ergänzungen
1. Über einen kleinen OLED-Screen sollen auf Tastendruck die aktuellen Werte
angezeigt werden.
2. Ergänzung um einen Feinstaubsensor
3. Ergänzung um den günstigeren Chip BMP280 mit angepasster Bibliothek
# Wetterdaten mit dem Raspberry Pi messen
**Ziel:** Mit zwei Sensoren und einem Raspberry Pi soll die Temperatur,
Luftdruck und Luftfeuchtigkeit an zwei Stellen (outdoor/indoor9 gemessen werden.
## Hardware
- Raspberry Pi 3 (geht auch mit älteren Modellen + WLAN-Modul)
- BOSCH BME280 (Bezugsquelle: watterott.com)
- Adafruit BMP280 (Versuchsweise, ohne Luftfeuchtigkeit)
![Sensor BME280](../img/bme280.png)
## Anschluss der Sensoren
```
Sensor Raspberry Pi
GND ------- GND
NC -------
VCC ------- +3.3V
SCL/SCK ------- SCL
SDA/SDI ------- SDA
SD0 ------- *
CS -------
```
Mit SD0 kann die I2C-Adresse geändert werden. Standardmäißg besitzt der Chip
die Adresse 0x77. Wird SD0 auf HIGH gelegt, so ändert sich die Adresse zu 0x76.
## Software
Über Adafruit kann eine Bibliothek zu diesem Chip installiert werden. Diese
Bibliothek setzt die Installation von Adafruit_GPIO voraus. Weitere
Informationen über https://github.com/adafruit.
Mit dieser Bibliothek können die Messdaten einfach eingelesen werden:
```
#!/usr/bin/python
# -*- coding: utf-8 -*-
from Adafruit_BME280 import *
import time
import urllib
sensor = BME280(mode=BME280_OSAMPLE_8)
degrees = sensor.read_temperature()
pascals = sensor.read_pressure()
hectopascals = pascals / 100
humidity = sensor.read_humidity()
print ("Temperatur (in C) = {0:0.3f} C".format(degrees))
print ("Luftdruck (in hPa) = {0:0.2f} hPa".format(hectopascals))
print ("Luftfeuchtigkeit = {0:0.2f} %".format(humidity))
```
## Speicherung der Messdaten auf (externer) Datenbank
Die gemessenen Werten sollen in einer Datenbank gespeichert werden, die sich
irgendwo auf einem Server befindet. Dazu wird auf diesem Server eine
upload-php-Seite angelegt, über die mit angehängten Parametern die Speicherung
erfolgt (näheres unter mysql).
Ergänzungen des Pythonprogramms:
```
import urllib
url = "http://<server>/upload.php?m=outdoor&t=" +str(round(degrees, 2)) + "&p=" +str(round(hectopascals, 2)) + "&f=" + str(round(humidity, 2))
urllib.urlopen(url)
```

21
bme280-messen.py Normal file
View File

@ -0,0 +1,21 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
from Adafruit_BME280 import *
import urllib
sensor = BME280(mode=BME280_OSAMPLE_8)
degrees = sensor.read_temperature()
pascals = sensor.read_pressure()
hectopascals = pascals / 100
humidity = sensor.read_humidity()
url = "http://<server>/upload.php?m=outdoor&t=" +str(round(degrees, 2)) + "&p=" +str(round(hectopascals, 2)) + "&f=" + str(round(humidity, 2))
urllib.urlopen(url)
print ("Temperatur (in C) = {0:0.3f} C".format(degrees))
print ("Luftdruck (in hPa) = {0:0.2f} hPa".format(hectopascals))
print ("Luftfeuchtigkeit = {0:0.2f} %".format(humidity))