Micropython Automation

mumai

Cadet 2nd Year
Registriert
Jan. 2018
Beiträge
28
Mahlzeit an alle,
vorab, bin totaler Anfänger in sachen Python. Verstädnis von PHP, SQL habe ich ausreichend die letzten "Jahrzehnte" angefangen von PHP 3 sammeln können, aber Python ist eine andere "Welt" in "meiner Welt".

Ich möchte die Wetterstation nachbauen, und funktioniert auch super. Die Werte des BME280 werden mit dem Raspberry Pico W hervoragend an meine Webseite per urequest gesendet. Allerdings nur beim starten des Picos. Dieser macht das nur einmal. Daher meine Frage wie ich den Pico dazu bringe, das er dies alle 5 Minuten alleine erledigt. Hier der Code bisher:

Code:
#import modules
import network
import socket
import urequests
from time import sleep
from machine import Pin, I2C
import bme280

ssid = 'XXX' #Your network name
password = 'XXX' #Your WiFi password

#initialize I2C
i2c=I2C(0,sda=Pin(0), scl=Pin(1), freq=400000)

def connect():
    #Connect to WLAN
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.connect(ssid, password)
    while wlan.isconnected() == False:
        print('Waiting for connection...')
        sleep(1)
    ip = wlan.ifconfig()[0]
    print(f'Connected on {ip}')
    return ip

def open_socket(ip):
    # Open a socket
    address = (ip, 80)
    connection = socket.socket()
    connection.bind(address)
    connection.listen(1)
    return connection

def webpage(reading):
    #Template HTML
    html = f"""{reading}"""
    return str(html)
   
def serve(connection):
    #Start a web server
   
    while True:
        bme = bme280.BME280(i2c=i2c)
        temp = bme.values[0]
        pressure = bme.values[1]
        humidity = bme.values[2]
        response = urequests.get('https://www.geheimeseite.de/api_wx.php?temp=' + temp + '&hum=' + humidity + '&pre=' + pressure + '&pico=1')
        response.close()
        #reading = 'Temperature: ' + temp + '. Humidity: ' + humidity + '. Pressure: ' + pressure
        reading = '{"temp":"' + temp + '","humidity":"' + humidity + '","pressure":"' + pressure + '","pico":"1"}'
        client = connection.accept()[0]
        request = client.recv(1024)
        request = str(request)      
        html = webpage(reading)
        client.send(html)
        client.close()

try:
    ip = connect()
    connection = open_socket(ip)
    serve(connection)
except KeyboardInterrupt:
    machine.reset()

Wäre dankbar, wenn das irgendwie automatisiert ohne Eingriff von draußen ausgeführt werden würde. Denn dieser soll im Garten aufgestellt werden.
 
Zuletzt bearbeitet:
Ich bastele gerade an dem gleichen Projekt :)

Dein Code hinter try:
muss mehrfach ausgeführt werden.
Am besten, du definierst eine neue Funktion, die deine anderen Funktionen aufruft.
Python:
def main():

   try:
      ip = connect()
      connection = open_socket(ip)
      serve(connection)


if __name__ == '__main__':

   while True:

       main()
       sleep(300)
 
die werte sollen nur an eine externe seite übermittelt werden? dann brauchst du hier nicht auf eingehende requests reagieren und das sollte reichen:

Python:
import network
import urequests
import time
import machine
import bme280

ssid = 'my_ssid' #Your network name
password = 'my_password' #Your WiFi password

# initialize I2C
i2c=machine.I2C(0,sda=machine.Pin(0), scl=machine.Pin(1), freq=400000)

# initialize wifi
wlan = network.WLAN(network.STA_IF)
wlan.active(True)

def connect():
    # Connect to WLAN
    wlan.connect(ssid, password)
    while wlan.isconnected() == False:
        print('Waiting for connection...')
        time.sleep(1)
    ip = wlan.ifconfig()[0]
    print(f'Connected on {ip}')


while True:
    try:
        if wlan.isconnected() == False:
            connect()

        bme = bme280.BME280(i2c=i2c)
        temp, pressure, humidity = bme.values[0], bme.values[1], bme.values[2]
        request = urequests.get(f'https://www.geheimeseite.de/api_wx.php?temp={temp}&hum={humidity}&pre={pressure}&pico=1')
        request.close()
        time.sleep(300)

    except KeyboardInterrupt:
        machine.reset()

    except Exception as e:
        print(e)
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: madmax2010
Guten abend,
das klingt einleuchtend, aber dennoch verursacht der gepostete Code von dir einen kompletten Abstürz und Thonny hängt sich mit aus. Ich muss dann den kompletten Speicher resetten und neuschreiben.
 
mangels hardware und micropython kann ich leider nicht weiterhelfen. eigentlich ist das nur dein code aufs wesentliche reduziert :)
 
Ja alles klar, dann schauen wir mal was ich noch rausfinden kann. Denn mommentan steht ich auf dem Schlauch, evtl. gibt es jemanden der mir den richtigen Ansatz geben kann. Danke für deine Hilfe.
 
ich hab nochmal editiert. das "machine.reset()" im except block konnte nicht funktionieren, da "machine" selbst nicht importiert war - vielleicht liegts daran?
 
Nachtrag: Habe es hinbekommen. Wußte gar nicht das Python es so streng mit Leerzeichen sieht. Funktioniert hervoragend. Danke! Eine Frage habe ich allerdings dennoch:

Wäre es möglich eine Status Power LED und eine "Gesendete" LED zum lechten zu bringen, damit ich von außen sehen kann, ob die Verbindung klappt? (Status LED's)
 
Im Endeffekt kommt es auf folgendes hinaus:
du brauchst eine Schleife, die deine Funktionen/Befhele immer wieder aufruft, zusammen mit einem Sleep-Befehl, damit nur alle 5 Minuten ausgeführt wird.
Am besten mit kleinerem Intervall testen
 
mumai schrieb:
Nachtrag: Habe es hinbekommen. Wußte gar nicht das Python es so streng mit Leerzeichen sieht.
die formatierung muss stimmen. ist der preis dafür, dass man keine klammern braucht. tipp: den editor so einstellen, dass er auch bei tab leerzeichen einfügt. sonst sieht der code beim mix von tab und spaces zwar gleich aus, funktioniert aber nicht.

mumai schrieb:
Wäre es möglich eine Status Power LED und eine "Gesendete" LED zum lechten zu bringen, damit ich von außen sehen kann, ob die Verbindung klappt? (Status LED's)
ganz bestimmt :) aber in der richtung habe ich noch nichts gemacht. läuft bestimmt auf das schalten von ein paar gpio hinaus?
 
Oje, Python und PHP sind ja welten... Ok, Leerzeichen in Tabs und aufgepasst. Alles klar, dann weiß ich bescheid. Das mit den LED's wird sicherlich eine Kleinigkeit sein. Ich versuche mich mal ran, aber ich sehe jetzt schon schwarz. Glaub mir, PHP/SQL mache ich seit "jahrzehnten" und das sind Welten zwischen dem hier und was soll ich sagen, ich versuche das Prinzip hinter Python zu verstehen, aber es will einfach nicht...
 
schick :) schau bitte nochmal in den code von #3. ich habe noch ein weiteres "except" hinzugefügt. ohne dieses würde das programm sich beenden, wenn es die daten mal nicht an die webseite übertragen kann.

ausserdem ist die "while True" schleife jetzt ganz aussen, so dass bei jedem durchlauf gecheckt wird, ob der raspi auch noch mit dem wlan verbunden ist. das macht das ganze robuster, falls was schiefgeht (wlan oder webseite temporär nicht erreichbar). du willst ja nicht bei jedem kleinen fehler das programm neustarten.
 
Guten morgen, vielen lieben dank! Das einzigste Problem was ich habe ist, wenn die Daten auf dem Pico geschrieben sind, der Pico vom PC getrennt ist, funktioniert das ganze wunderbar. Sobald ich aber sowie jetzt, den Pico wieder an den PC schließe und mit Thonny verbinde, erhalte ich den Fehler Code 22 das das Program den Befehl nicht kennt. Das ganze läßt sich nur beheben, wenn ich den Pico resette und den Code neu aufspiele.

Bei deinem Code kommt:
name 'wlan' isn't defined

Ergänzung ()

sensorlicht.png
Ich habe hier auch noch ein Lichtsensor. Wenn ich den auch noch im Skript verbaut bekomme, wäre das das absolute Highlight.Hast du eine idee wie ich diesen zusätzlich nutzen kann?
 
Zuletzt bearbeitet:
Kannst du mir nochmals bei deinem Codebeispiel #3 rüber schauen, was da der Fehler ist?
Bei deinem Code kommt:
name 'wlan' isn't defined

Mit den Sensor und die LEDs habe ich hinbekommen. Code zeige ich dir gleich.
 
So, nun habe ich den Pico fertig und dieser läuft wunderbar. Nun drucke ich nich ein passendes Gehäuse und dann wäre alles perfekt. Ein Windsensor würde noch hinzukommen und dann wäre es fertig. Hier nun der von dir und zusätzlich von mir angepasste Code (nicht vergessen, bin Anfänger)
:D
Code:
# Bibliothken laden
import network
import urequests
import time
import machine
import bme280
from machine import ADC
from machine import Pin

# WiFi Verbindungsdaten
ssid = 'WiFi_Name' # Netzwerkname
password = 'WiFi_Passwort' # WiFi Passwort

# initialize I2C
i2c=machine.I2C(0,sda=machine.Pin(0), scl=machine.Pin(1), freq=400000)

# Lichtsensor
ldr = ADC(0)

# LED
ledred = Pin(16, Pin.OUT)
ledyellow = Pin(17, Pin.OUT)
ledgreen = Pin(18, Pin.OUT)
ledblue = Pin(19, Pin.OUT)

# initialize WiFi
wlan = network.WLAN(network.STA_IF)
wlan.active(True)

# Pwr LED
ledred.on()

# WiFi Verbindung herstellen
def connect():
    wlan.connect(ssid, password)
    while wlan.isconnected() == False:
        print('Warte auf WiFi Verbindung...')
        ledyellow.toggle()
        time.sleep(1)
    ip = wlan.ifconfig()[0]
    print(f'Verbunden: {ip}')
    ledyellow.off()
    ledgreen.on()

# Sensoren auslesen
while True:
    try:
        if wlan.isconnected() == False:
            connect()

        # Temperatursensor auslesen
        bme = bme280.BME280(i2c=i2c)
        temp, pressure, humidity = bme.values[0], bme.values[1], bme.values[2]
        # Lichtsensor auslesen
        adc = ldr.read_u16()
        # LED Blau (senden, an)
        ledblue.on()
        # LED Gelb (senden, aus)
        ledyellow.off()
        request = urequests.get(f'https://www.geheimeseite.de/api.php?Temp={temp}&Hum={humidity}&Pre={pressure}&Phres={adc}')
        request.close()
        # LED Blau (nicht senden, aus)
        ledblue.off()
        # LED Gelb (nicht senden, an)
        ledyellow.on()
        time.sleep(180)

    except KeyboardInterrupt:
        machine.reset()
        # LED Rot (Fehler, blinken)
        ledred.toggle()

    except Exception as e:
        print(e)
 
Python:
    except KeyboardInterrupt:
        machine.reset()
        # LED Rot (Fehler, blinken)
        ledred.toggle()

bringt das led.toggle() noch was, nachdem machine.reset() aufgerufen wurde? laut doku ist das ein hard-reset, eigentlih sollte man nach dem aufruf von der led nichts mehr sehen. ansonsten sind die led für das darstellen des status natürlich praktisch.
 
Zurück
Oben