Skip to content
This repository was archived by the owner on Sep 10, 2024. It is now read-only.

onewire.py: Optimize timing, enable CRC check and slim the code #62

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 31 additions & 26 deletions examples/DS18X20/onewire.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#!/usr/bin/env python3

#
# The crc8 implementation is a Python port of the C code published here:
# http://lentz.com.au/blog/tag/crc-table-generator
# As far as suitable, the copyrigth notice and the disclaimer of the link apply
#
"""
OneWire library for MicroPython
"""
Expand All @@ -16,40 +20,44 @@ class OneWire:
def __init__(self, pin):
self.pin = pin
self.pin.init(pin.OPEN_DRAIN, pin.PULL_UP)
self.disable_irq = machine.disable_irq
self.enable_irq = machine.enable_irq
self.crctab1 = (b"\x00\x5E\xBC\xE2\x61\x3F\xDD\x83"
b"\xC2\x9C\x7E\x20\xA3\xFD\x1F\x41")
self.crctab2 = (b"\x00\x9D\x23\xBE\x46\xDB\x65\xF8"
b"\x8C\x11\xAF\x32\xCA\x57\xE9\x74")


def reset(self):
"""
Perform the onewire reset function.
Returns True if a device asserted a presence pulse, False otherwise.
"""
sleep_us = time.sleep_us
disable_irq = machine.disable_irq
enable_irq = machine.enable_irq
pin = self.pin

pin(0)
sleep_us(480)
i = disable_irq()
i = self.disable_irq()
pin(1)
sleep_us(60)
status = not pin()
enable_irq(i)
self.enable_irq(i)
sleep_us(420)
return status

def read_bit(self):
sleep_us = time.sleep_us
enable_irq = machine.enable_irq
pin = self.pin

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

Expand All @@ -69,14 +77,14 @@ def write_bit(self, value):
sleep_us = time.sleep_us
pin = self.pin

i = machine.disable_irq()
i = self.disable_irq()
pin(0)
sleep_us(1)
pin(value)
sleep_us(60)
pin(1)
sleep_us(1)
machine.enable_irq(i)
self.enable_irq(i)

def write_byte(self, value):
for i in range(8):
Expand All @@ -97,19 +105,13 @@ def select_rom(self, rom):

def crc8(self, data):
"""
Compute CRC
Compute CRC, based on tables
"""
crc = 0
for i in range(len(data)):
byte = data[i]
for b in range(8):
fb_bit = (crc ^ byte) & 0x01
if fb_bit == 0x01:
crc = crc ^ 0x18
crc = (crc >> 1) & 0x7f
if fb_bit == 0x01:
crc = crc | 0x80
byte = byte >> 1
for byte in data:
crc ^= byte ## just re-using crc as intermediate
crc = (self.crctab1[crc & 0x0f] ^
self.crctab2[(crc >> 4) & 0x0f])
return crc

def scan(self):
Expand Down Expand Up @@ -181,7 +183,7 @@ def start_conversion(self, rom=None):
"""
if (rom==None) and (len(self.roms)>0):
rom=self.roms[0]
if rom!=None:
if rom!=None:
rom = rom or self.roms[0]
ow = self.ow
ow.reset()
Expand All @@ -197,15 +199,18 @@ def read_temp_async(self, rom=None):
return None
if (rom==None) and (len(self.roms)>0):
rom=self.roms[0]
if rom==None:
if rom==None:
return None
else:
ow = self.ow
ow.reset()
ow.select_rom(rom)
ow.write_byte(0xbe) # Read scratch
data = ow.read_bytes(9)
return self.convert_temp(rom[0], data)
if ow.crc8(data) == 0:
return self.convert_temp(rom[0], data)
else:
return None

def convert_temp(self, rom0, data):
"""
Expand Down
2 changes: 1 addition & 1 deletion examples/lorawan-nano-gateway/nanogateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ def _udp_thread(self):
except usocket.timeout:
pass
except OSError as ex:
if ex.errno != errno.EAGAIN:
if ex.args[0] != errno.EAGAIN:
self._log('UDP recv OSError Exception: {}', ex)
except Exception as ex:
self._log('UDP recv Exception: {}', ex)
Expand Down