← index #8325Issue #4116
Related · medium · value 1.511
QUERY · ISSUE

MicroPython OneWire protocol BUG?

openby beyonloopened 2022-02-18updated 2024-09-08
enhancement

Hello!

I'm using the onewire CI DS28E05 (https://datasheets.maximintegrated.com/en/ds/DS28E05.pdf) but Micropython ow.scan() show nothing. That is a onewire chip, so it use/works with the onewire protocol, of course. Well, if it is onewire protocol, the CI address need to be shown on the ow.scan() right?

>>> os.uname()
(sysname='esp32', nodename='esp32', release='1.18.0', version='v1.18 on 2022-01-17', machine='ESP32 module (spiram) with ESP32')
>>> from machine import Pin
>>> import onewire
>>> ow = onewire.OneWire(Pin(25))
>>> ow.scan()
[]
>>>

Just to you know that onewire pin are working, if I use another onewire chip, the DS18b20 CI, it shows the address on the ow.scan() as follow bellow:


>>> os.uname()
(sysname='esp32', nodename='esp32', release='1.18.0', version='v1.18 on 2022-01-17', machine='ESP32 module (spiram) with ESP32')
>>> from machine import Pin
>>> import onewire
>>> ow = onewire.OneWire(Pin(25))
>>> ow.scan()
[bytearray(b'(\xa7I\xf0\x0c\x00\x00\x17')]
>>>

Any idea what is wrong? Is it a MicroPython OneWire protocol BUG or what I need to do to works the ow.scan()?

Thank you in advance.

CANDIDATE · ISSUE

OneWire timing issue

closedby rnovacekopened 2018-09-10updated 2018-10-17

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.

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied