MicroPython OneWire protocol BUG?
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.
OneWire timing issue
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.