PicoW oneWire MQTT code

OP #7589032
Lesenswert?

Hallo Foren Mitglieder, ich habe mit einem Raspberry Pico W und DS18X20 Sensoren vor, meine Fußboden Heizungstemperaturen auszulesen. Leider bekomme ich nach Tagen bis zu Wochen irgendwann keine Daten mehr über MQTT gesendet, nur weiß ich nicht warum...

Kann da jemand drüber schauen, wo der Fehler liegt?

1
# Bibliotheken laden
2
import network
3
from utime import sleep
4
from machine import Pin
5
from umqtt_simple import MQTTClient
6
from onewire import OneWire
7
from ds18x20 import DS18X20
8
# WLAN-Konfiguration
9
wlanSSID = 'meineWlanSSID'
10
wlanPW = 'meinWlanPW'
11
network.country('AT')
12
# MQTT-Konfiguration
13
mqttBroker = '192.168.0.1'
14
mqttClient = 'heizung_mqtt'
15
mqttUser = 'meinMqttUser'
16
mqttPW = 'meinMqttPW'
17
mqttTopic = b"heizung/"
18
# Temperatursensoren
19
sensAdr = [
20
    '28ff640e6a4c9e44',
21
    '28ff640e7835905a',
22
    '28ff640e75f829d9',
23
    '28ff640e69dd768c',
24
    '28ff640e6f21398e',
25
    '28ff640e69c8315a',
26
    '28ff640e780e35c4',
27
    '28ff640e75285fa4',
28
    '28ff640e7559c4e7']
29
sensNam = [
30
    b"BH-Az",
31
    b"BH-Sz",
32
    b"BH-WcArVr",
33
    b"BH-Bd",
34
    b"BH-WkFe",
35
    b"BH-WkKu",
36
    b"BH-WkWz",
37
    b"Vorlauf",
38
    b"Zuleitung"]
39
sensOfs = [
40
    -0.0625,
41
    +0.0625,
42
    -0.0625,
43
    -0.0000,
44
    -0.0625,
45
    -0.3125,
46
    +0.1250,
47
    +0.1250,
48
    +0.0625]
49
sensErr = 0
50
# Status-LED für die WLAN-Verbindung
51
led_onboard = Pin('LED', Pin.OUT, value=0)
52
# Initialisierung GPIO, OneWire und DS18B20
53
one_wire_bus = Pin(16)
54
sensor_ds = DS18X20(OneWire(one_wire_bus))
55
# One-Wire-Geräte ermitteln
56
devices = sensor_ds.scan()
57
# Funktion: Temperaturen messen
58
def getTemp():
59
    # Temperatur messen
60
    try:
61
        sensor_ds.convert_temp()
62
    except:
63
        client = mqttConnect()
64
        sensErr += 1
65
        client.publish(mqttTopic+str("ERROR"), str(sensErr))
66
        client.disconnect()
67
    sleep(1)
68
    # Werte vorbelegen
69
    sensTmp = [-999 for x in range(10)]
70
    # Sensoren abfragen
71
    for device in devices:
72
        for adr in range(len(sensAdr)):
73
            if sensAdr[adr] == device.hex():
74
                sensTmp[adr] = sensor_ds.read_temp(device) + sensOfs[adr]
75
    return sensTmp
76
# Funktion: WLAN-Verbindung herstellen
77
def wlanConnect():
78
    wlan = network.WLAN(network.STA_IF)
79
    if not wlan.isconnected():
80
        wlan.active(True)
81
        wlan.connect(wlanSSID, wlanPW)
82
        for i in range(10):
83
            if wlan.status() < 0 or wlan.status() >= 3:
84
                break
85
            led_onboard.toggle()
86
            sleep(1)
87
    if wlan.isconnected():
88
        led_onboard.off()
89
    else:
90
        led_onboard.on()
91
# Funktion: Verbindung zum MQTT-Server herstellen
92
def mqttConnect():
93
    client = MQTTClient(mqttClient, mqttBroker, user=mqttUser, password=mqttPW)
94
    client.connect()
95
    return client
96

97
### PROGRAMM
98
# WLAN-Verbindung herstellen
99
wlanConnect()
100
# Programm: Sensordaten an MQTT übergeben
101
while True:
102
    getTemp()
103
    myTmpArray = getTemp()
104
    led_onboard.on()
105
    client = mqttConnect()
106
    for dev in range(len(sensAdr)):
107
        client.publish(mqttTopic+sensNam[dev], str(myTmpArray[dev]))
108
    client.disconnect()
109
    led_onboard.off()
110
    sleep(300)

geschrieben mit Micropython. Verbindung zum "ioBroker" Wenn keine Daten mehr kommen, bleibt die WLan Verbindung aufrecht. Google-Bard meinte ich solle in der Funktion getTemp() try & except einfügen. hat aber auch nicht geholfen...

Bitte um Hilfe. Dank & Gruß, Jack

OP #7589052
Lesenswert?

Darf ich anfügen, dass das mein erster Mikrocontroller mit "meinem" -aus allen möglichen Codeteilen zusammen gebasteltes- erstes Programm ist? Und ich keine Ahnung habe WIE ich den Fehler finden soll, wenn ich so manches an Code noch gar nicht verstehe?

Darf ich wenigstens um einen Hinweis bitten?

#7589113
Lesenswert?

Jack schrieb:

Darf ich anfügen, dass das mein erster Mikrocontroller mit "meinem" -aus allen möglichen Codeteilen zusammen gebasteltes- erstes Programm ist? Und ich keine Ahnung habe WIE ich den Fehler finden soll, wenn ich so manches an Code noch gar nicht verstehe?

Wissen wir ja nicht. Unsere diversen Glaskugeln sind gerade alle beim Polieren und bekommen Updates.

Ein gutes Hilfsmittel sind z.B. Debugausgaben auf der seriellen Schnittstelle. Das bedeutet allerdings, dass immer ein Terminal mitlaufen muss. Oder du lässt die Wlan-Verbindung immer stehen und gibst dort deine Meldungen aus. Irgendeinen Tod musst du halt sterben. Und 9 Onewire-Sensoren sind auch eine Menge. Wenn einer nicht mehr mag, geht nichts mehr. Wie sieht's mit EMV aus? Wie lange ist die Leitung zu den Sensoren. Ist sie geschirmt oder nicht. Welche Geräte sind in der Nähe, die Störungen verursachen können? Wie gesagt, unsere Glaskugeln sind momentan nicht verfügbar!

#7589131
Lesenswert?

Helmut -. schrieb:

Ein gutes Hilfsmittel sind z.B. Debugausgaben auf der seriellen Schnittstelle. Das bedeutet allerdings, dass immer ein Terminal mitlaufen muss. Oder du lässt die Wlan-Verbindung immer stehen und gibst dort deine Meldungen aus. Irgendeinen Tod musst du halt sterben.

Die DS18x20 sind auch bei mir manchmal bockig, gerade bei längeren Leitungen (bei mir sind es 3 Sensoren über ca 8 m). Deswegen würde ich zum debuggen Fehler provozieren, lass z.B. eine serielle Konsole mitlaufen und mach mal absichtlich Wackelprobleme an der Sensorleitung. Du kannst auch zusätzliche LEDs an die GPIOs hängen und die vor und nach einem Berfehl ein- und ausschalten, dann siehst Du, wo es hängt. Und schliess die DS18x20 3-polig an, nicht 2-polig im parasite-Modus

#7590801
Lesenswert?

Joe G. schrieb:

Norbert schrieb:

Google-Bard meinte ich solle in der Funktion getTemp() try & except einfügen.

Das ist schon die richtige Stelle, um festzustellen, ob sich ein Sensor verabschiedet hat. Wird den ein "ERROR" über MQTT gesendet, wenn du einen Sensor testweise abklemmst?

Lüge nicht so dreist und zitiere mich richtig oder zitiere mich gar nicht.

Was soll diese Frechheit?

OP #7603391
Lesenswert?

Hallo, ich habe dieses Forum über Google Einträge entdeckt -no na ned- , und empfand es "damals" als sehr hilfreich. Leider bin ich heute mit der Situation in diesem Forum nicht ganz glücklich...

Helmut -. schrieb:

Und du solltest das beachten:

Wichtige Regeln - erst lesen, dann posten!

1
Groß- und Kleinschreibung verwenden
2
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Ja, nach einem Punkt schreibt man mit einem Groß-Buch-Staben weiter. Hab wohl die Shift-Taste nicht richtig erwischt. (nur wegen dem "h"?) Findest Du dieses Bischen Code echt lang? - Eine genauere Angabe "Bitte ab 5 Zeilen nicht mehr als Text einfügen" hab ich nicht gelesen.

Norbert schrieb:

Wie haben wir das früher nur gemacht? Moment … ja … genau … so war das … viel gelesen und gelernt. Im Kleinen verschiedene Dinge ausprobiert, wie funktioniert dieser Maschinenbefehl, wie reagiert jenes Flag.

Heute ist das alles viel einfacher, Google-Copy-Paste-Ask-Wait.

Ich weis nicht wie alt Du bist, aber als ich anfing Logik zu programmieren, hatten die auf CERN auch noch keine Ahnung vom Internet.

Norbert schrieb:

Joe G. schrieb:

Norbert schrieb:

Google-Bard meinte ich solle in der Funktion getTemp() try & except einfügen.

Das ist schon die richtige Stelle, um festzustellen, ob sich ein Sensor verabschiedet hat. Wird den ein "ERROR" über MQTT gesendet, wenn du einen Sensor testweise abklemmst?

Lüge nicht so dreist und zitiere mich richtig oder zitiere mich gar nicht.

Was soll diese Frechheit?

Was hat das mit meinem Beitrag zu tun? In Foren wird geholfen, oder?

Benedikt L. schrieb:

Da reicht doch ein ESP8266 mit Tasmota oder ESPeasy.

Findest Du wirklich, das das mein Problem löst?

In "guten" Foren, schreibt, wer eine Idee oder einen Hinweis hat. Wer nicht, der schreibt auch nichts.

Übrigens lag der Fehler an der Codezeile 64.

1
sensErr += 1

Es hätte davor die Variable aus Zeile 49 noch global deklariert werden müssen. Seither läuft der Code.

Gruß, Jack

#7604930
Lesenswert?

Jack schrieb:

Leider bekomme ich nach Tagen bis zu Wochen irgendwann keine Daten mehr über MQTT gesendet

Bei einem so sporadisch auftretenden Fehler willst Du nach max. 3 fehlerfreien Wochen schon wissen, daß Du den Fehler gefunden hast?

Jack schrieb:

Übrigens lag der Fehler an der Codezeile 64.sensErr += 1 Es hätte davor die Variable aus Zeile 49 noch global deklariert werden müssen.

Ja, wenn das über die gesamte Laufzeit alle Fehler zählen soll, dann war das wohl ein Fehler. Statt die Fehler mitzuzählen liefert er Dir sonst halt immer ERROR 1 - das wars aber auch schon.

Seither läuft der Code.

Das ist inzwischen wie lange?

Jack schrieb:

Wenn keine Daten mehr kommen, bleibt die WLan Verbindung aufrecht.

Das weist Du ganz sicher, weil ??

Deine LED blinkt dann nach wie vor für 1 Sekunde alle 3 Minuten? Falls nicht hängt sich Dein Programm irgendwo komplett auf.

Aber Du könntest z.B. mal in Deiner Hauptschleife jedesmal eine MQTT Msg. absetzen oder Deine onboard LED abhängig vom WLAN-Status (dazu mußt Du halt wlan aus Deiner wlanConnect()-Funktion zurückliefern, damit Du auf den Status in der Hauptschleife zugreifen kannst) setzen, dann wüßtest Du mehr.

Im Wesentlichen gibts zwei Möglichkeiten das Dein beschriebenes Verhalten erklären könnte: ein abreißen der WLAN-Verbindung oder ein (dauerhaftes) Scheitern des MQTT-Connect; vor allem auf g Grund der großen zeitlichen Variation, wie lange es bis zum Auftreten des Fehlers dauert, tippe ich stark auf ersteres, denn WLAN Verbindungen sind nicht wirklich langzeitstabil, selbst wenn man die Störungen normalerweise nicht bemerkt da normale Geräte die Verbindung einfach neu aufbauen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren