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

Ich versuche, die DS18B20-Treiberprobleme mit einem AZ-Delivery LogicAnalyzer einzukreisen.Dazu habe ich kleine Testprogramme geschrieben:

  1. DS18B20-A2.py mit lib/onewire_a.py und sensors/ds18x20_a.py von @vinz und
  2. DS18B20-B2.py mit lib/onewire_b.py und sensors/ds18x20_b.py von @robert-hh

und beobachte den Onewire-Bus mit dem LogicAnalyzer.
Erste Erkenntnisse:
Prog A2 startet das Messen für jeden Sensor einzeln

Prog B2 startet das Messen mit einem Befehl und ist damit schneller:
image
Leider tauchen die Messfehler in beiden Programmen auf:
Bei Prog A2 willkürliche Werte (88.6)
12. 24.6 24.6 24.6 24.6 24.6 24.7
13. 24.6 88.6 24.6 24.6 24.6 24.7
14. 24.6 24.6 24.6 24.6 24.6 24.7

Bei Prog B2 erkennt der CRC-Check den Fehler und gibt “None” aus ( bei mir ersetzt durch 999999 )
19. 24.7 24.8 24.5 24.7 24.8 24.8 err: 0
20. 24.7 24.8 24.5 24.7 999999 24.8 err: 1 rate: 120.0
21. 24.7 24.8 24.5 24.7 24.8 24.8 err: 1 rate: 126.0
22. 24.7 24.8 24.6 24.7 24.8 24.8 err: 1 rate: 132.0
23. 24.7 24.8 24.6 24.7 24.8 24.8 err: 1 rate: 138.0
24. 24.7 24.8 24.6 24.8 24.8 24.8 err: 1 rate: 144.0
25. 24.7 24.8 999999 24.8 24.8 24.8 err: 2 rate: 75.0
26. 24.7 24.8 24.6 24.8 24.8 24.8 err: 2 rate: 78.0

Die Fehler tauchen extrem unterschiedlich häufig auf, manchmal gibt es 100 x 6 Messungen keinen Fehler, oben gab es bei der 20. und 25. Messung Fehler.

Ich muss weiter forschen.

1 Like

Hi Didi,

Mit der neuen Basisfirmware von [1]

https://packages.hiveeyes.org/hiveeyes/foss/pycom/vanilla/FiPy-1.20.1.r1-0.7.0-vanilla-dragonfly-onewire-i2s.tar.gz

und diesen Treibern…

… bekommst Du bestimmt bessere Ergebnisse.

Viele Grüße,
Andreas.


  1. Dragonfly firmware for Pycom/ESP32 ↩︎

2 Likes

Danke @Andreas, werde ich testen.

Das scheint es gewesen zu sein: 1000 x 6 = 6000 Messungen ohne CRC-Fehler:

997. Werte: DS: 23.1 23.1 23.7 23.1 23.3 23.2 err: 0
998. Werte: DS: 23.1 23.1 23.7 23.1 23.3 23.2 err: 0
999. Werte: DS: 23.1 23.1 23.7 23.0 23.3 23.2 err: 0
1000. Werte: DS: 23.1 23.1 23.7 23.1 23.3 23.2 err: 0

Pycom MicroPython 1.20.1.r1-0.7.0-vanilla-dragonfly-onewire-i2s [daf40f36-dirty] on 2019-12-04; FiPy with ESP32

Auch das Timing ist OK:


kurzer Befehl convert_temp

750 msec warten
Daten von 6 Sensoren

130 msec Ausgabe auf OLED
nächster Befehl convert_temp

2 Likes

Super! Braucht es für die “neuen” onewire-Treiber eine spezielle Konfigurationseinstellung in den settings?

Ich werde heute abend versuchen, die neuen Treiber in hiverize/fipy einzubinden.
Z.Z. läuft mein Testprogramm mit 13688 x 6 Messungen ohne CRC-Fehler.

1 Like

Gestern hat uns Guido diese Beobachtung berichtet:

Folgendes ist mir zu den Abbrüchen aufgefallen:
Ich hatte trotz update bjs zum 20.12 regelmässig (fast täglich) Abbrüche.
Am 20.12 wurde nach dem öffnen der Beute die Temperatur der Einzellfühler nicht mehr angezeigt. (Warum have ich nicht nicht geprüft).
Also nur noch Waage, Luftfeuchte inkl. Temperatur.
Interessant ist aber, dass ich seit dem keinen Abbruch mehr hatte.
Vielleicht gibt es einen Zusammenhang

Vielleicht hilft uns die Treiber-Verbesserung der DS18B20-Temperatur-Sensoren auch das gesamte Laufzeitverhalten der BOB-Software zu stabilisieren.

Ich hatte im Herbst den Fall, dass die DS18B20 plötzlich ausfielen, und dann das Wlan. Der Fipy lief dann noch wochenlang ohne Absturz. Die Ursachen konnte ich nicht ermitteln.
Der Test der neuen DS18B20-Treiber verläuft so erfolgreich, dass ich noch keine Fehlmessung beobachten .konnte. Ich befürchte aber, dass ich noch etwas übersehen habe.

1 Like

Für den Einbau der neuen DS18B20-Treiber in hiverize/FiPy brauche ich etwas Hilfe. Die Testprogramme nur mit DS18B20 und OLED laufen, aber in der BOB-Firmware gibt es Instabilitäten.
Im Testprogramm BOB-DS18B20.zip (24,2 KB) gibt es 3 Varianten:
onewire_a.py und ds18x20_a.py von @vinz,häufige Fehlwerte, CRC-Fehler nicht abgefangen
onewire_b.py und ds18x20_b.py von @robert-hh, häufige CRC-Fehler
onewire_c.py und ds18x20_c.py von @andreas, sehr seltene Messfehler, aber häufige Reboots in Hiverize/FiPy.
Leider sind x_c.py nicht ganz softwarekompatibel zu x_a.py und x_b.py

1 Like

Wir haben hier in Berlin ja nen kleinen Labor-Teststand eines Bob-Hats und im Dezember dort mal die neuste Firmware von @Andreas, FiPy-1.20.1.r1-0.7.0-vanilla-dragonfly-onewire-i2s.tar.gz, drauf getan: Das Ding lief 4.5 Wochen ohne Reboot durch! Denn ist vor ca. 2.5 Wochen jemand gegen das Kabel gekommen; seit dem gab es aber auch keinen weiteren Reboot.

ps.: Ja, dashboard-or-it-didn’t-happen: Grafana

1 Like

Bei mir taucht der Fehler auf, wenn ich versuche, die Treiber in hiverize/fipy der Uni Bremen (@Diren, @vinz und @caro ) einzubauen.
Ebenso wenig schaffe ich es, das Webinterface zur Konfiguration anzupassen.
Frage: mit welcher Software bearbeitet man die *.js, *.html und *.css Dateien für den Webserver?
Die *.py bearbeite ich mit Atom und pymkr.

So weit ich das weiß sind die “Webserver-Dateien”, also *.js, *.html und *.css, autogenerated von irgendeinem Framework das @vinz verwendet hat. Die sind nur komisch formatiert, daher doof in Atom zu bearbeiten, aber im Prinzip sollte man Atom dafür genausogut verwenden können. Die Frage ist nur, müssen wir sie händisch anpassen oder sollen / können wir das tool nehmen, da @vinz auch verwendet hat.

Sie sind viel zu unübersichtlich und vermutlich auch aufgebläht mit unnützem Zeug, da sie sehr gross sind.

1 Like

Hatte mir das Mal vor ein paar Monaten angeschaut.

Das verwendete Framework ist vue.
Gibt glaube ich dafür ein Plugin für Atom.
Für VisualStudio auf alle Fälle.
Das meißte davon ist das Framework. Das eigentliche von @vinz geschriebene Teil ist gar nicht so groß aber in unformatierten Text. Gibt aber Tools, die das wieder übersichtlicher und lesbar machen kann.

Gruß Micha

ImTestprogramm nur mit DS18B20 und OLED taucht kein CRC-Fehler auf, in hiverize/fipy dagegen alle paar Minuten:

67 . Messung
   DS18B20: Messung gestartet...
   BME280:  16.4 C 1022.4 mbar 38.8 %
   HX711:   6.7 kg
   DS18B20: 15.6 15.8 15.7 15.7 15.8 16.0
14:14:18 Prep: 3ms Init: 4ms Connect: 34ms SSL: 1797ms Header: 45ms Data: 1798ms Response: 245ms
{'t_i_1': 15.7, 't_i_2': 16.0, 't_i_3': 15.8, 't_i_4': 15.8, 't_i_5': 15.6, 'h': 38.8, 'weight_kg': 6.7, 'p': 1022.4, 't': 16.4, 't_o': 15.7, 'key': 'E421ET8aqCTmPBz2'}
stack: 896 out of 11264
GC: total: 2561344, used: 84912, free: 2476432
 No. of 1-blocks: 1541, 2-blocks: 361, max blk sz: 161, max free sz: 153467
#67, Seconds elapsed: 3.270s,time until next measurement: 1.730s
DS1820: 753ms + 153ms, BME280: 56ms, HX711: 756ms Log: 2970ms, GC: 300ms

68 . Messung
   DS18B20: Messung gestartet...
   BME280:  16.4 C 1022.3 mbar 38.8 %
   HX711:   6.8 kg
   DS18B20: 15.6 15.9 15.8 15.7 Error, dumping memory
### Fehler bei 5. Sensor
(, Exception('CRC error',), None)
stack: 656 out of 11264
GC: total: 2561344, used: 87616, free: 2473728
 No. of 1-blocks: 1689, 2-blocks: 368, max blk sz: 161, max free sz: 153467
GC memory layout; from 3f94eae0:
00000: MDFhhhhhhhh===hh=FFFMDFFFFhFSSSh=======h=====DMDSBMh==Dh==hDFFhS
00400: DDh====DhShSDhSh=======BBBhMDSBBBBShSMSBBhShB=BSDSShBBBh=======S

Der Fehler wird nicht sauber abgefangen in ds18x20_c.py

   def read_temp(self, rom):
        try:
            buf = self.read_scratch(rom)
            if rom[0] == 0x10:
                if buf[1]:
                    t = buf[0] >> 1 | 0x80
                    t = -((~t + 1) & 0xff)
                else:
                    t = buf[0] >> 1
                return t - 0.25 + (buf[7] - buf[6]) / buf[7]
            elif rom[0] in (0x22, 0x28):
                t = buf[1] << 8 | buf[0]
                if t & 0x8000: # sign bit set
                    t = -((t ^ 0xffff) + 1)
                return t / 16
            else:
                return None
        except AssertionError:
            return None

In main.py kommt dann die Fehlermeldung und Abbruch:

log("Starting measurement setup...")
wdt.feed()
try:
    if _config.get_value('networking', 'wlan', 'enabled'):
        log("WLan is enabled, trying to connect.")
        _wm.enable_client()
        _beep = logger.beep

        if _wlan.mode() == network.WLAN.STA and _wlan.isconnected():
            try:
                rtc.ntp_sync("pool.ntp.org")
            except:
                pass

            start_measurement()
        else:
            log("No network connection.")
            if ((_config.get_value('networking', 'accesspoint', 'enabled')
                    or _csv is None)
                    and not _config.get_value('general', 'general', 'button_ap_enabled')):
                enable_ap()
            else:
                start_measurement()
    else:
        log("No network connection.")
        _wlan.deinit()
        start_measurement()

except:
    log("Error, dumping memory")                              ##### hierher springt er
    log(sys.exc_info())
    micropython.mem_info(True)
    #machine.reset()

Software: FiPy-2001test.zip (88,9 KB)

Ich habe die Varianten a), b) und c) untersucht und bin auf folgende Probleme gestossen:

  • Timing:

In Variante a) und b) wird das Timing in onewire.py bestimmt:

def readbit(self):

sleep_us = time.sleep_us
pin = self.pin
pin(1) # half of the devices don't match CRC without this line
i = self.disable_irq()
pin(0)
# skip sleep_us(1) here, results in a 2 us pulse.
pin(1)
sleep_us(5) # 8 us delay in total
value = pin()
self.enable_irq(i)
sleep_us(40)
return value

Das führt zu häufigen Messfehlern.

Variante c) überlässt das Timing dem eingebauten MicroPython:

def readbit(self):
return _ow.readbit(self.pin)
Damit werden die CRC-Fehler sehr viel weniger.

  • Fehler-Erkennung

In Variante a) gibt es keinen CRC-Check. Damit werden auch fehlerhafte Bit weitergereicht und man wundert sich (nicht) über seltsame Messwerte. Das sind keine gültigen Werte.

In Variante b) und c) gibt es einen CRC-Check in ds18x20.py:

if self.ow.crc8(self.buf):
    raise Exception('CRC error')
  • Fehler-Behandlung

In Variante c) gibt es bei CRC-Error eine Exception, die abgefangen wird:

try:
    tmp = ds18b20.read_temp(rom)    # Messwerte auslesen
    ds18b20tmp = int(tmp*10)/10     # 1/10 °C
except:                             # CRC-Fehler
    ds18b20tmp =  9999              # Dummy-Wert

Ein gültiger Wert wird auf 1/10 °C begrenzt, da eine grössere Auflösung unsinnig ist.
Bei CRC-Fehler gibt es einen Dummy-Wert.

Ich habe ein kleines Testprogramm geschrieben :FiPy-DS18B20.zip (9,5 KB)

mit onewire_b.py kann man die CRC-Fehler gut erkennen.

  • Timing


Mit dem LogicAnalyzer erkennt man das
Starten der Messungen
Warten 750 msec
Auslesen von 6 Sensoren

Starten der Messungen : ds18b20.convert_temp()

Auslesen von 6 Sensoren : tmp = ds18b20.read_temp(rom)

Daten von einem Sensor

1 Like

Z.Z. traten im Testprogramm bei 24500 Zyklen * 6 Sensoren = 147000 Messungen ganze 3 CRC-Fehler auf.
nun sind es bei 40000 Zyklen * 6 Sensoren = 240000 Messungen 7 CRC-Fehler

Ergänzung am 1.2.2020

Beim Einbau der Treiber in Hiverize/FiPy erhöht sich die Anzahl der CRC-Fehler deutlich, vermutlich weil der Pozessor noch nebenbei andere Dinge wie WLAN usw. zu tun hat:
bei 7500 Zyklen * 6 Sensoren = 45000 Messungen sind es 97 CRC-Fehler.
Die werden durch eine Exception abgefangen ( siehe oben ).
Es gibt aber noch eine weitere Exception mit (noch) unbekannter Herkunft, die früher zu Reboots geführt hat. Sie taucht bei der Ausgabe bei OLED auf, immer nach einem CRC-Fehler, obwohl DS18B20 mit Onewire-Bus und OLED mit I2C-Bus in Hardware und Software nichts miteinander zu tun haben.
Ich kann sie dort abfangen:

...

         try:
            _oled.fill(0)                                         # alles aus
            _oled.text(str(cycle), 0, 0)
           ....
        except:
            print('OLED Fehler',end=' ')

Erklären kann es nicht.

Ergänzung am 2.2.2020

Die Software läuft ziemlich stabil, aber beim Start kann es vorkommen, dass nicht alle DS18B20 gefunden werden. Vielleicht kann jemand bei der Fehlersuche helfen?
FiPy-2001test.zip (88,9 KB)

2 Likes

Noch was zum 85 °C-Problem gefunden unter GitHub - cpetrich/counterfeit_DS18B20: How to tell original from fake DS18B20 temperature sensors.

Solution to the 85 °C-Problem

There is a simple, undocumented, way to discriminate between the power-up 85 °C-reading and a genuie temperature reading of 85 °C in authentic DS18B20 [5]: <byte 6> of the scratchpad register. If it is 0x0c , then the 85 °C-reading is a power-up reading, otherwise it is a true temperature measurement. Does not work with clones of Families B, C, or D, though.

1 Like

Dieses Problem wird in der Praxis kaum vorkommen: in allen mir bekannten Programmen wird

  1. conversion gestartet
  2. 750 msec gewartet
  3. Werte ausgelesen