# 1-Wire driver for MicroPython # MIT license; Copyright (c) 2016 Damien P. George from micropython import const import _onewire as _ow class OneWireError(Exception): pass class OneWire: SEARCH_ROM = const(0xf0) MATCH_ROM = const(0x55) SKIP_ROM = const(0xcc) def __init__(self, pin): self.pin = pin self.pin.init(pin.OPEN_DRAIN, pin.PULL_UP) def reset(self, required=False): reset = _ow.reset(self.pin) if required and not reset: raise OneWireError return reset def readbit(self): return _ow.readbit(self.pin) def readbyte(self): return _ow.readbyte(self.pin) def readinto(self, buf): for i in range(len(buf)): buf[i] = _ow.readbyte(self.pin) def writebit(self, value): return _ow.writebit(self.pin, value) def writebyte(self, value): return _ow.writebyte(self.pin, value) def write(self, buf): for b in buf: _ow.writebyte(self.pin, b) def select_rom(self, rom): self.reset() self.writebyte(MATCH_ROM) self.write(rom) def scan(self): devices = [] diff = 65 rom = False for i in range(0xff): rom, diff = self._search_rom(rom, diff) if rom: devices += [rom] if diff == 0: break return devices def _search_rom(self, l_rom, diff): if not self.reset(): return None, 0 self.writebyte(SEARCH_ROM) if not l_rom: l_rom = bytearray(8) rom = bytearray(8) next_diff = 0 i = 64 for byte in range(8): r_b = 0 for bit in range(8): b = self.readbit() if self.readbit(): if b: # there are no devices or there is an error on the bus return None, 0 else: if not b: # collision, two devices with different bit meaning if diff > i or ((l_rom[byte] & (1 << bit)) and diff != i): b = 1 next_diff = i self.writebit(b) if b: r_b |= 1 << bit i -= 1 rom[byte] = r_b return rom, next_diff def crc8(self, data): return _ow.crc8(data)