Untersuchung und Verbesserung des Timings bei der Ansteuerung der DS18B20 Sensoren unter MicroPython

Summary from https://forum.pycom.io/topic/2570/solved-onewire-ds18x20-reading-not-stable-with-lopy4-no-problem-with-lopy/19:

  • LoPy4 runs much more stable with the new onewire.py library [1], no misreadings anymore.
  • @robert-hh acknowledged that:

    Looking at the data sheet, that seems OK. Faster is better. For reading, it says:

    “Output data from the DS18B20 is valid for 15μs after the falling edge that initiated the read time slot. Therefore, the master must release the bus and then sample the bus state within 15μs from the start of the slot.”

However, also note that


  1. That means 4x sleep_us(1) removed from the actual onewire.py library. 2 from read_bit() and 2 from write_bit(). ↩︎

Zur Verbesserung des Verhaltens schlage ich folgende Dinge vor.

  • Nach start_conversion() länger warten. 1 Sekunde statt 0.75.
  • Ohne den ersten sleep_us(1) bei read_bit() und ggf. write_bit() in onewire.py testen.
  • Effizienz erhöhen durch paralleles Lesen der Sensoren – start_conversion() zuerst an alle versenden. Oder ist das Quatsch?
1 Like

Der DS18B20 kann eine checksumme mitliefern und sagt, ob der Wert gültig ist. Habe das hier nur für den RasPi ausbuchstabiert gefunden:

Die Datei besteht aus zwei Zeilen, die jeweils den hexadezimalen Registerdump des Sensor-ICs enthalten. Am Ende der ersten Zeile steht die Prüfsumme (CRC) und die Information, ob es sich um einen gültigen Messwert handelt (YES). Die zweite Zeile endet mit dem Temperaturmesswert in tausendstel Grad Celsius. Im Beispiel beträgt die Temperatur also 7,375 °C. Die Genauigkeit auf drei Stellen hinter dem Komma ist natürlich nur scheinbar; dem Datenblatt des DS18S20 entnimmt man zum Beispiel, dass die Messgenauigkeit ±0,5 °C beträgt. Die tatsächliche Temperatur liegt also irgendwo zwischen 6,8 und 7,9 °C.

Vielleicht gibt es in MicroPython auch eine lib, die das macht?

Habe gestern Nacht noch ein Mal genauer hingeschaut, indem ich die Sensoren Mal in Grafana angeschaut habe. Bei Beep gibt es ja keine Möglichkeit sich einzelne Messungen anzuschauen oder näher rein zu Zoomen.

Dabei ist mir auch aufgefallen, das ab und an auch gar keine Werte von den Sensoren kommen.
Könnte das auch Live im Log beobachten. Dort werden dann keine oder nur 2 der Sensoren gefunden.
Die fehlerhaften Werte weichen dort aber noch extremer ab, teilweise mehrere 100°C. Bei Beep werden anscheinend die Werte bereits durch Mittelwerte geglättet.

Danke für die Nachforschungen, @MKO! Habe meine Daten daraufhin auch inspiziert und ähnliches gefunden:

Rohdaten exportieren

Da Grafana je nach Zoomlevel (für mich) nicht eindeutig nachvolliehbare Mittelwertsbildung / magic macht habe ich versucht die Rohdaten zu exportieren. Afaik bekommt man mit den unten gewählten Parametern nur die Rohdaten wie sie von den nodes gekommen sind ohne irgendwelche “Nachbereitung” / Extremwertbereinigung / Missingsubstitution usw. @Andreas ist das so korrekt oder werden die Daten dort schon irgendwie aufbereitet / gefiltert / manipuliert? Für mich, für die Analyse der Daten ob für später oder hier zur Verbesserung und zum debuggen ist es essentiell, dass user die Möglichkeit haben auf die ungefilterten Rohdaten zuzugreifen!

https://swarm.hiveeyes.org/api/hiveeyes/testdrive/area-005/fipy-cg-01/data.txt?from=2019-07-08T15:27:05&to=now

Diese habe ich dann in Excel importiert und nur die DS18B20- und BME-Temperaturdaten im Datensatz gelassen.

Beobachtete Ausfälle / unplausible Werte

Damit habe ich 1531 Datensätze in knapp 7 Tagen (2019-07-08, 15:27h bis 2019-07-15, 08:01h).

Bei den DS18B20 gab es diesw Ausfälle in Form von keinen Daten, d.h. missings im Datensatz:

  • Sensor 1: 35x keine Daten
  • Sensor 2: 35x keine Daten
  • Sensor 3: 39x keine Daten
  • Sensor 4: 38x keine Daten
  • Sensor 5: 35x keine Daten

Es gab 2x Abweichungen von ein mal ca. 18 °C und ein mal 16 °C nach oben im
Vergleich zum BME was mit ziemlicher Sicherheit nicht der Realität entspricht, alle anderen Abweichungen waren um die 2 °C. Nach unten waren es maximal -4 °C zum BME, was tatsächlich real sein kann, da die Sensoren unter einem Blumentopf draußen waren und der Tontopf auch direkte Sonne abbekommen hat. Der BME hatte keine Ausfälle.

Die verwendete Datei mit den Beobachtungswerten

ausfaelle-DS18B20-vs-bme280_2019-07.xlsx (167.7 KB)

1 Like

A post was merged into an existing topic: Stabilität und längere Testzeiträume der neuen Micropython-Firmware

Was mich etwas wundert, dass die Ausreißer nach oben immer dann auftreten, wenn die anderen Sensoren auch ein Maximum haben.

Gab es direkte Sonne auf einzelne Sensoren? Könnten es doch reale Werte sein?

Nein Sonne ist an dieser Stelle nur ganz früh am Morgen und das 100W Solarpanel liegt als zusätzlicher Sonnenschutz direkt darüber und erzeugt nur aus dem indirektem licht den benötigten Strom.
Sonne gab es hier im Norden auch nicht wirklich.
hier mal das Grafana Panel von den Sensoren des anderen FiPy.
https://swarm.hiveeyes.org/grafana/d/rgD4TVIZz/mko-teststand?orgId=2&from=1562339643166&to=1563108111823&var-STATION=AACHEN-ORSBACH&panelId=16&fullscreen

Ok, da wurde es richtig heiß! :-) also tatsächlich falsche, nicht reale Werte und nicht nur “ein bisserl drüber”. Danke!

das macht Sinn, denn bei der 12bit Auflösung braucht der Chipp alleine 750ms zum Rechnen. Kann gut gehen mit 0.75s muss aber nicht.
Runter auf 11bit denke ich würde auch dem gelieferten Aergebnis bei 0,5 Grad Abweichung noch genüge tun.

1 Like

Ich vermute ein Zeit-Problem im Treiber ds18x20.py, da (zufällig) ein oder mehrere Bit abgeschnitten werden und dadurch absurde Messwerte entstehen. Ich habe mein Programm ohne Korrektur eine halbe Stunde laufen lassen: es gab 2 Fehler

a: 6. korr> 4. Temp.: 278.1 C -> old: 22.1 C
2019-07-16 18:50:18 BME: 23.6 C 1017.6 mbar 51.2 % HX : 9.4 kg DS: 22.1 C 23.6 C 22.1 C 278.1 C 23.5 C 0.0 C

b:118. korr> 1. Temp.: 2070.1 C -> old: 22.1 C
2019-07-16 19:08:58 BME: 23.5 C 1017.6 mbar 50.5 % HX : 9.7 kg DS: 2070.1 C 23.8 C 22.1 C 22.1 C 23.6 C 0.0 C

Da alle 10 sec gemessen, aber nur alle 20 sec auf der Webseite angezeigt und alle 2 min der Graph neu gezeichnet wird, wird kräftig gemittelt, so dass man im Graph nicht den eigentlichen Fehler erkennen kann.
image
Der Fehler b war um 19:08:58 Kanal 1 Wert 2070.1 °C ; im Graph um 21:08 Wert 192.8°C

Da mir solche Fehler auf dem RaspberryPi mit Python 2.7 nicht aufgefallen sind, vermute ich den Fehler im MicroPython-Treiber.

1 Like

Wir haben jetzt kürzlich folgendes gemacht:

Weitere Details wie oben bei fiddling with the timing in onewire.py werden folgen, vielleicht kannst Du hier schon einmal vorfühlen?

Leider sind die Treiber

  • ds1x20.py in hiverize/FiPy-master und
  • sensor_ds18x20.py in hiveeyes-micropython-firmware-master

so unterschiedlich, dass ich (noch) nicht daran etwas ändern könnte.

Hi Didi,

es gibt überall tiefere Treiberschichten. Die Datei FiPy/ds18x20.py at master · Hiverize/FiPy · GitHub enspricht der pycom-libraries/onewire.py at master · pycom/pycom-libraries · GitHub, dort aber ohne die class OneWire, an der die Änderungen vorzunehmen sind.

Im Gegensatz dazu hat hiveeyes-micropython-firmware/sensor_ds18x20.py at master · hiveeyes/hiveeyes-micropython-firmware · GitHub mit dem Sensor-Auslesen selbst überhaupt nichts zu tun, das ist nur ein kleiner Wrapper.

Viele Grüße,
Andreas.

DS18B20 recap re. timing and beyond

Wir haben hier nochmal eine Bestandsaufnahme gemacht, um welche Aspekte wir uns kümmern wollen. Das Timing in den Griff kriegen führt die Liste eindeutig an.

Drüben bei Timing things on MicroPython for ESP32 findet man weitere Details zu den Hintergründen der Timing-Probleme aus nächster Nähe.

Backlog

CRC-Checks überprüfen

Q: Srsly?
A: Ja, die Funktion def crc8 wird nämlich nirgends innerhalb der Bibliothek gerufen.


Meiomei.
image

I will check that again, but haven’t come across it yet.

Apart from following the guidelines you outlined at Timing things on MicroPython for ESP32 - #4 by roh, I really would love to have a mature system-level DS18B20 library available for Pycom MicroPython, effectively written in C or C++ and made available through safe API calls from the MicroPython runtime.

Research

onewire.py at Pycom

It looks like tuning onewire.py already has a dedicated thread on the Pycom Forum.

Pure-Python Drivers

The first version of the library by Damien George.

The vanilla MicroPython drivers.

The vanilla Pycom drivers.

The OneWire library ported to MicroPython by Jason Hildebrand looks promising. It does

Another guy of Jason Hildebrand fame.

The RMT RAM variant by Yann Vernier also looks very interesting, see GitHub - lonetech/LoPy: LoPy code (MicroPython on ESP32 module). This probably works around the indeterministic timing induced by the serial RAM.

# RMT RAM is divided into 8 blocks of 64 words, each holding 2 entries. 
ram = uctypes.struct(RMT_BASE+0x800, (uctypes.ARRAY | 0x0, uctypes.UINT32 | 64*8))

Drivers written in C

Looking under the hood of the vanilla MicroPython core also brings up some things.

Miscellaneous

Some arbitrary resources about reading the DS18B20 from MicroPython.

Zu diesem Thema lief uns gerade noch die esponewire.c für ESP32 aus dem ESP32-Port des aktuellen Genuine MicroPython über den Weg, die dort timing-kritische Dinge maschinennah implementiert – gerade das Lesen und Schreiben von Bits auf den Bus und die Einhaltung des Protokolls und der Contenance.

Dass diese Angelegenheit beim Pycom MicroPython in pure-Python per onewire.py implementiert ist, mag man zwar fast nicht glauben :woman_facepalming:, zeigt aber umso deutlicher, dass diese Geräte vom Hersteller nicht unbedingt dafür ausgelegt wurden, Meßdatenlogger zu sein, sondern eher, um ihren Dienst als universelle Telemetriemodembausteine zu tun.

Auch hier wäre es nett, wenn wir bei Gelegenheit auch auf die maschinennahe Programmierung der Pycom-Geräte zugehen würden. Vielleicht ist es machbar, fehlende Funktionalitäten ggf. selbst nachzurüsten.

Meow.

1 Like

momentan patchen wir das mpy von pycom noch garnicht, korrekt?
ich befuerchte wenn wir da anfassen wollen kommen wir nicht dran vorbei.

wenn ich micropython/onewire.py at v1.11 · micropython/micropython · GitHub mit o.g. python code vergleiche, denke ich das es moeglich sein sollte den pycom kram auf den c write/reset/readbit/byte umzustellen.

das generische onewire ist auch da python, nur der lowlevel kram ist c

leider schmeisst pycom den ds18x20 support mit in das gleiche file.
bei mpy liegt das daneben als eigenes file das auf den onewire funktionen aufbaut

Genau. Irgendwann werden wir das machen und können uns dann vielleicht bessere Sachen zusammenklauben.

Ja, gerade dieses Beispiel spricht schon Bände darüber, dass das bestimmt nur eine notdürftige Lösung war, weil der echte ESP32-Port in dieser Zeit vermutlich noch gar nicht ordentlich fertig war.

1 Like