Projekt Wetterstation und Umweltmessungen

Ja. Donnerstag ist in Ordnung

Dann machen wir die Session am Donnerstag, um 17 Uhr.

Treffen können wir uns hier: https://bbb.teckids.org/b/ann-hx2-xc3 .

Bericht von der Session am Donnerstag, 5. November

Was wir machen wollen

Wir wollen eine Wetterstation bauen, die folgendes kann:

  • Temperatur messen
  • Luftfeuchtigkeit messen
  • Luftqualität messen
  • Generell Wettermessungen
  • Luftdruck

Das müssen wir nicht alles auf Anhieb einbauen, aber nach und nach kann man Sensoren ergänzen.

Welche Teile wir benutzen wollen

  • ESP
  • LoRaWAN
  • Sensoren
  • Breadboard, später Platine
  • Gehäuse aus einer Box oder Rohr beispielsweise

Außerdem müssen wir beachten, dass die Stromversorgung geregelt werden muss.

Wie wir die Arbeit einteilen und wie wir weiter vorgehen

  • Input: Sensorik, Hardware
  • Putput: LoRaWAN und Sensoren ansteuern
  • Output: Die gesammelten Daten auf einer Website anzeigen

Dazu wollen wir wöchentlich Donnerstags um 17 Uhr Sessions machen. Die erste findet nächste Woche zum Thema Hardware und Sensorik auf BigBlueButton statt.

1 „Gefällt mir“

Sessionbericht vom 12. November: Input (Hardware und Sensorik)

In dieser Session haben wir über die Input-Komponente unserer Wetterstation geredet, also Hardware und Sensorik. Dabei haben wir überlegt, welche Sensoren man benutzen könnte:

  • Feinstaubsensor: sds011
  • Gassensor: MQ135 (CO2, Alkohol, Benzene, NOx, NH3)
  • Luftfeuchtigkeit/Temperatur: DHT 22/11
  • Luftfeuchtigkeit/Temperatur/Luftdruck: BME280
  • LoRa-Modul: Seeed Studio Grove - LoRa Radio 868 MHz (RFM95)

Weiteres Vorgehen

Unser weiterer Plan ist nun, dass die Sensoren bestellt werden, der Code für LoRaWAN und Sensoren vorbereitet wird. Zudem wird die Website vorbereitet. Wenn der Code für Sensoren getestet ist, wird alles zusammengeführt. Auch das LoRa-Modul wird entsprechend fertig gemacht, damit bei einer Session zur Putput-Komponente alles besprochen werden kann.

Beim Barcamp könnte man außerdem eine längere Session machen, wo man sich mit dem LoRaWAN beschäftigen könnte.

Klingt insgesamt ziemlich interessant. Ich kann mir aber leider aktuell nicht vorstellen, dass ich noch eine weitere Session in meinen Zeitplan unterkriege. Ich bleib aber auf dem Stand der Dinge und melde mich, wenn ich irgendwie irgendwo was beitragen könnte.

Zur Info: Ich habe mal einen Satz Sensoren bestellt. LoRaWAN-Module haben gerade einen längere Lieferzeit, daher kann mit dem Bestandteil erst etwas später begonnen werden, falls nicht irgendwer so etwas zu Hause rumliegen hat. (werde ich die Tage aber auch Mal noch bestellen)

Sessionbericht vom 19. November (Vorbereitung putput)

Am großen Barcamp wollen wir zwei Session machen, bei der wir für die Sensoren den Code schreiben wollen und die Website für die Daten basteln.
In Kleingruppen werden dann die Sensoren behandelt.

Sessionbericht vom 21. und 22. November

Beim Barcamp gab es mehrere Sessions zum Thema Wetterstation und Umweltmessungen. Wir haben uns mit der Ansteuerung der unterschiedlichen Sensoren auseinander gesetzt und einen ersten Probeaufbauf auf einem Steckbrett gemacht.
Der Aufbau auf dem Steckbrett sieht wie folgt aus:


Der dazugehörige Quellcode um die Sensoren auszulesen ist der folgende:

import time
from dht import DHT22
from machine import Pin, I2C
from MQ135 import MQ135
import BME280

# setup
dht = DHT22(Pin(16)) #D0
mq135 = MQ135(0) # analog PIN 0

i2c = I2C(scl=Pin(5), sda=Pin(4), freq=10000) #D1 D2
bme = BME280.BME280(i2c=i2c)

# loop
while True:
    #DHT22 Sensor auslesen
    dht.measure()
    dht_temp = dht.temperature()
    dht_hum = dht.humidity()
    
    #BME-Sensor auslesen
    bme_temp = bme.temperature
    bme_hum = bme.humidity
    bme_pres = bme.pressure

    #MQ135-Sensor auslesen
    rzero = mq135.get_rzero()
    corrected_rzero = mq135.get_corrected_rzero(dht_temp, dht_hum)
    resistance = mq135.get_resistance()
    ppm = mq135.get_ppm()
    corrected_ppm = mq135.get_corrected_ppm(dht_temp, dht_hum)
    
    # Werte auf Konsole ausgeben
    print("DHT22 Temperature: " + str(dht_temp) +"\t Humidity: "+ str(dht_hum))
    print("BME Temperature: " + str(bme_temp) +"\t Humidity: " + str(bme_hum) + "\t Pressure: " + str(bme_pres))
    print("MQ135 RZero: " + str(rzero) +"\t Corrected RZero: "+ str(corrected_rzero)+
          "\t Resistance: "+ str(resistance) +"\t PPM: "+ str(ppm)+
          "\t Corrected PPM: "+str(corrected_ppm)+"ppm\n")
    
    time.sleep(3)

Für den BME-Sensor wurde die Bibliothek von catdog2 verwendet.
Bibliothek für den BME280 von catdog2
Für den MQ135-Sensor haben wir die Bibliothek von rubfi verwendet.
Bibliothek für den MQ135

Da BBB momentan nicht funktioniert, benutzen wir für die heutige Session Jitsi.

Sessionbericht vom 26. November

Bei der gestrigen Session haben wir vor allem darüber gesprochen, wie wir weiter vorgehen.

Dabei ist herausgekommen, dass sich jeder für nächste Woche ein wenig mit LoRaWAN beschäftigt, Martin schon einmal den Feinstaubsensor ausprobiert und dass sich der bisherige Programmcode nochmal anschaut wird.

Sessionbericht vom 03. Dezember

In der heutigen Session haben wir uns mit dem Thema LoRaWan auseinandergesetzt und uns nochmal genauer damit auseinander gesetzt, was LoRaWan ist.

  • LoRaWan ist eine Technologie zur drahtlosen Kommunikation
  • Die LoRaWan-Endknoten können mit wenig Energie betrieben werden
  • Die Kommunikation kann bidirektional erfolgen
    • Bei Klasse A können von den Endknoten nur nach dem Senden Daten empfangen werden
    • Bei Klasse B können Daten zusätzlich zu bestimmten festgelegten Zeitpunkten empfangen werden
    • Bei Klasse C können immer Daten empfangen werden
  • Module für Europa senden mit einer Frequenz von 868MHz
  • Die Endpoints senden Informationen an alle Gateways, die in Empfangsreichsweite sind
  • Die Gateways kommunizieren mit einem LoRaWan-Server
  • Das LoRaWan-Protokoll bietet die Möglichkeit der Verschlüsselung
  • Die Spezifikation für die Geräte werden durch die LoRa-Alliance festgelegt

Hallo! Ich möchte eine erste Session für Freedombox planen, in der wir organisatorisches klären wollen. Da viele, die sich für Freedombox interessieren, auch bei Projekt Wetterstation mitmachen, wollt ich fragen, wann ihr denn in “Winterpause” geht.

Hallo Kirill,
wir haben uns bei unserem letzten Treffen mit der Wetterstation abgestimmt und gehen ab dem 14.01.2021 in die Pause. Das heißt, dass ab dem 15.01.2021 Sessions zum Theme Freedombox stattfinden können.

Die nächste Session wird im Rahmen der Campdays Campdays stattfinden. Der genaue Zeitpunkt wird am Samstag-Morgen festgelegt.

Sessionbericht vom 27.11.2021

Teilnehmende

Inhalte

Die Session hat zweigeteilt. Die beiden Teile haben parallel stattgefunden.
In dem einen Teil hat @benni einen kurzen Elektronik- und MicroPython-Workshop gehalten.
Der andere Teil hat sich damit beschäftigt, das CC1101-Modul anzusteuern. Als Ergebnis wurde eine Bibliothek für den Raspberry PI geforkt und sie für den ESP8266 umgeschrieben. Das Ergebnis ist du auf edugit zu finden.

Nik hatte vorgeschlagen, dass wir die Credentials per Bluetooth konfigurierbar machen.
Dafür habe ich mich ein wenig mit der Bluetooth-Schnittstelle des ESP32 auseinandergesetzt.

MircoPython stellt dafür die Klasse BLE in der Bibliothek “bluetooth” zur Verfügung.
Des weiteren bin ich dabei auf folgendes YouTube-Tutorial gestoßen. Leider hat er nicht dazu geschrieben unter welcher Lizenz sein Code steht.
Aber sein Code ist relativ ähnlich zu dem von 2black0. Und dieser Code steht unter der MIT-Lizenz.
Der einzige Unterschied ist, dass im YouTube-Tutorial in der main zwischen den Messages unterschieden wird und bei 2black0 innerhalb der BLE-Klasse.

Zum Testen habe ich die App “Serial Bluetooth Terminal” verwendet. Wobei ich nicht ganz erkennen kann, in wie weit sich die freie App von der im Play-Store unterscheidet. Und leider gibt es in F-Droid keine APK zum Download.

Hier ist mein aktueller Testcode:

from machine import Pin, Timer
from time import sleep_ms
import ubluetooth

message = ""

class ESP32_BLE():
    def __init__(self, name, statuspin = 2):
        # Create internal objects for the onboard LED
        # blinking when no BLE device is connected
        # stable ON when connected
        self.led = Pin(statuspin, Pin.OUT)
        self.timer1 = Timer(0)
        
        self.name = name
        self.ble = ubluetooth.BLE()
        self.ble.active(True)
        self.disconnected()
        self.ble.irq(self.ble_irq)
        self.register()
        self.advertiser()

    def connected(self):
        self.led.value(1)
        self.timer1.deinit()

    def disconnected(self):        
        self.timer1.init(period=100, mode=Timer.PERIODIC, callback=lambda t: self.led.value(not self.led.value()))

    def ble_irq(self, event, data):
        global message
        
        if event == 1: #_IRQ_CENTRAL_CONNECT:
                       # A central has connected to this peripheral
            self.connected()

        elif event == 2: #_IRQ_CENTRAL_DISCONNECT:
                         # A central has disconnected from this peripheral.
            self.advertiser()
            self.disconnected()
        
        elif event == 3: #_IRQ_GATTS_WRITE:
                         # A client has written to this characteristic or descriptor.          
            buffer = self.ble.gatts_read(self.rx)
            message = buffer.decode('UTF-8').strip()
            print(message)
            
    def register(self):        
        # Nordic UART Service (NUS)
        NUS_UUID = '6E400001-B5A3-F393-E0A9-E50E24DCCA9E'
        RX_UUID = '6E400002-B5A3-F393-E0A9-E50E24DCCA9E'
        TX_UUID = '6E400003-B5A3-F393-E0A9-E50E24DCCA9E'
            
        BLE_NUS = ubluetooth.UUID(NUS_UUID)
        BLE_RX = (ubluetooth.UUID(RX_UUID), ubluetooth.FLAG_WRITE)
        BLE_TX = (ubluetooth.UUID(TX_UUID), ubluetooth.FLAG_NOTIFY)
            
        BLE_UART = (BLE_NUS, (BLE_TX, BLE_RX,))
        SERVICES = (BLE_UART, )
        ((self.tx, self.rx,), ) = self.ble.gatts_register_services(SERVICES)

    def send(self, data):
        self.ble.gatts_notify(0, self.tx, data + '\n')

    def advertiser(self):
        name = bytes(self.name, 'UTF-8')
        adv_data = bytearray('\x02\x01\x02') + bytearray((len(name) + 1, 0x09)) + name
        self.ble.gap_advertise(100, adv_data)
        print(adv_data)
        print("\r\n")
                # adv_data
                # raw: 0x02010209094553503332424C45
                # b'\x02\x01\x02\t\tESP32BLE'
                #
                # 0x02 - General discoverable mode
                # 0x01 - AD Type = 0x01
                # 0x02 - value = 0x02
                
                # https://jimmywongiot.com/2019/08/13/advertising-payload-format-on-ble/
                # https://docs.silabs.com/bluetooth/latest/general/adv-and-scanning/bluetooth-adv-data-basics

led = Pin(2, Pin.OUT)
but = Pin(0, Pin.IN)
ble = ESP32_BLE("ESP32")

def button_irq(pin):
    led.value(not led.value())
    ble.send("LED state will be toggled.")
    print("LED state will be toggled.")

but.irq(trigger=Pin.IRQ_FALLING, handler=button_irq)

while True:
    if message == "STATUS":
        message = ""
        print('LED is ON. ' if led.value() else 'LED is  OFF')
        ble.send('LED is ON. ' if led.value() else 'LED is  OFF')
    elif message == "ON":
        message = ""
        led.on()
        print('LED is ON. ')
        ble.send('LED is ON.')
    elif message == "OFF":
        message = ""
        led.off()
        print('LED is OFF. ')
        ble.send('LED is OFF.')
    sleep_ms(100)

Das Projekt ist quasi zu Ende. Hier müsste noch ein abschließender Bericht verfasst werden.