Skip to content

OneWire timing issue #4116

@rnovacek

Description

@rnovacek

I'm trying to use MicroPython on Wemos D1 mini (esp8266) to read temperature from DS18b20 sensor.

Reading values from this sensor is very unreliable for me. I get the temperature like once in 20 attempts to read the temperature. Other reads thrown an OneWireError exception during OneWire.reset(True) method or no device was found. This is the code I used (from the MicroPython docs):

import time
import machine
import onewire, ds18x20

# the device is on GPIO12
dat = machine.Pin(12)

# create the onewire object
ds = ds18x20.DS18X20(onewire.OneWire(dat))

# scan for devices on the bus
roms = ds.scan()
print('found devices:', roms)

# loop 10 times and print all temperatures
for i in range(10):
    print('temperatures:', end=' ')
    ds.convert_temp()
    time.sleep_ms(750)
    for rom in roms:
        print(ds.read_temp(rom), end=' ')
    print()

I tried flashing Arduino to the same board with same sensor and it worked flawlessly.

I compared source codes for both 1-wire libraries and discovered one difference:
The second sleep in the reset function is 40us for MicroPython, but 70us for Arduino.

Sources:
Arduino: https://github.com/PaulStoffregen/OneWire/blob/master/OneWire.cpp#L187
MicroPython: https://github.com/micropython/micropython/blob/master/extmod/modonewire.c#L37

So I tried following monkeypatch to use the timings from Arduino:

import onewire
def reset(self, required=False):
    self.pin.value(0)
    time.sleep_us(480)
    self.pin.value(1)
    time.sleep_us(70)
    status = self.pin.value()
    time.sleep_us(420)
    return status

onewire.OneWire.reset = reset

With this, I get the correct readings every time. There's also different number for the 3rd sleep, but that doesn't seem to matter.

I found that master should wait 15-60us after reset before reading slave presence signal:
https://datasheets.maximintegrated.com/en/ds/DS18B20-PAR.pdf (page 13) and then it has 60-240us to read the presence (I hope I interpreted the datasheet correctly).

TLDR: I think the second sleep time should be changed from 40us to 70us.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions