2016-04-28 13:33:55 +01:00
|
|
|
# 1-Wire driver for MicroPython on ESP8266
|
|
|
|
# MIT license; Copyright (c) 2016 Damien P. George
|
|
|
|
|
2016-11-03 01:41:11 +00:00
|
|
|
from micropython import const
|
2015-12-29 00:22:51 +00:00
|
|
|
import _onewire as _ow
|
|
|
|
|
2016-04-28 13:33:55 +01:00
|
|
|
class OneWireError(Exception):
|
|
|
|
pass
|
|
|
|
|
2015-12-29 00:22:51 +00:00
|
|
|
class OneWire:
|
2016-04-28 13:33:55 +01:00
|
|
|
SEARCH_ROM = const(0xf0)
|
|
|
|
MATCH_ROM = const(0x55)
|
|
|
|
SKIP_ROM = const(0xcc)
|
2015-12-29 00:22:51 +00:00
|
|
|
|
|
|
|
def __init__(self, pin):
|
|
|
|
self.pin = pin
|
2016-05-05 21:47:37 +01:00
|
|
|
self.pin.init(pin.OPEN_DRAIN)
|
2015-12-29 00:22:51 +00:00
|
|
|
|
2016-08-29 03:12:49 +01:00
|
|
|
def reset(self, required=False):
|
|
|
|
reset = _ow.reset(self.pin)
|
|
|
|
if required and not reset:
|
|
|
|
raise OneWireError
|
|
|
|
return reset
|
2015-12-29 00:22:51 +00:00
|
|
|
|
2016-04-28 13:33:55 +01:00
|
|
|
def readbit(self):
|
2015-12-29 00:22:51 +00:00
|
|
|
return _ow.readbit(self.pin)
|
|
|
|
|
2016-04-28 13:33:55 +01:00
|
|
|
def readbyte(self):
|
2015-12-29 00:22:51 +00:00
|
|
|
return _ow.readbyte(self.pin)
|
|
|
|
|
2016-08-29 03:27:21 +01:00
|
|
|
def readinto(self, buf):
|
|
|
|
for i in range(len(buf)):
|
2015-12-29 00:22:51 +00:00
|
|
|
buf[i] = _ow.readbyte(self.pin)
|
|
|
|
|
2016-04-28 13:33:55 +01:00
|
|
|
def writebit(self, value):
|
2015-12-29 00:22:51 +00:00
|
|
|
return _ow.writebit(self.pin, value)
|
|
|
|
|
2016-04-28 13:33:55 +01:00
|
|
|
def writebyte(self, value):
|
2015-12-29 00:22:51 +00:00
|
|
|
return _ow.writebyte(self.pin, value)
|
|
|
|
|
2016-04-28 13:33:55 +01:00
|
|
|
def write(self, buf):
|
2015-12-29 00:22:51 +00:00
|
|
|
for b in buf:
|
|
|
|
_ow.writebyte(self.pin, b)
|
|
|
|
|
|
|
|
def select_rom(self, rom):
|
|
|
|
self.reset()
|
2016-04-28 13:33:55 +01:00
|
|
|
self.writebyte(MATCH_ROM)
|
|
|
|
self.write(rom)
|
2015-12-29 00:22:51 +00:00
|
|
|
|
|
|
|
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
|
2016-04-28 13:33:55 +01:00
|
|
|
self.writebyte(SEARCH_ROM)
|
2015-12-29 00:22:51 +00:00
|
|
|
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):
|
2016-04-28 13:33:55 +01:00
|
|
|
b = self.readbit()
|
|
|
|
if self.readbit():
|
2015-12-29 00:22:51 +00:00
|
|
|
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
|
2016-04-28 13:33:55 +01:00
|
|
|
self.writebit(b)
|
2015-12-29 00:22:51 +00:00
|
|
|
if b:
|
|
|
|
r_b |= 1 << bit
|
|
|
|
i -= 1
|
|
|
|
rom[byte] = r_b
|
|
|
|
return rom, next_diff
|
|
|
|
|
|
|
|
def crc8(self, data):
|
|
|
|
return _ow.crc8(data)
|