onewire.py 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. # 1-Wire driver for MicroPython
  2. # MIT license; Copyright (c) 2016 Damien P. George
  3. from micropython import const
  4. import _onewire as _ow
  5. class OneWireError(Exception):
  6. pass
  7. class OneWire:
  8. SEARCH_ROM = const(0xf0)
  9. MATCH_ROM = const(0x55)
  10. SKIP_ROM = const(0xcc)
  11. def __init__(self, pin):
  12. self.pin = pin
  13. self.pin.init(pin.OPEN_DRAIN, pin.PULL_UP)
  14. def reset(self, required=False):
  15. reset = _ow.reset(self.pin)
  16. if required and not reset:
  17. raise OneWireError
  18. return reset
  19. def readbit(self):
  20. return _ow.readbit(self.pin)
  21. def readbyte(self):
  22. return _ow.readbyte(self.pin)
  23. def readinto(self, buf):
  24. for i in range(len(buf)):
  25. buf[i] = _ow.readbyte(self.pin)
  26. def writebit(self, value):
  27. return _ow.writebit(self.pin, value)
  28. def writebyte(self, value):
  29. return _ow.writebyte(self.pin, value)
  30. def write(self, buf):
  31. for b in buf:
  32. _ow.writebyte(self.pin, b)
  33. def select_rom(self, rom):
  34. self.reset()
  35. self.writebyte(MATCH_ROM)
  36. self.write(rom)
  37. def scan(self):
  38. devices = []
  39. diff = 65
  40. rom = False
  41. for i in range(0xff):
  42. rom, diff = self._search_rom(rom, diff)
  43. if rom:
  44. devices += [rom]
  45. if diff == 0:
  46. break
  47. return devices
  48. def _search_rom(self, l_rom, diff):
  49. if not self.reset():
  50. return None, 0
  51. self.writebyte(SEARCH_ROM)
  52. if not l_rom:
  53. l_rom = bytearray(8)
  54. rom = bytearray(8)
  55. next_diff = 0
  56. i = 64
  57. for byte in range(8):
  58. r_b = 0
  59. for bit in range(8):
  60. b = self.readbit()
  61. if self.readbit():
  62. if b: # there are no devices or there is an error on the bus
  63. return None, 0
  64. else:
  65. if not b: # collision, two devices with different bit meaning
  66. if diff > i or ((l_rom[byte] & (1 << bit)) and diff != i):
  67. b = 1
  68. next_diff = i
  69. self.writebit(b)
  70. if b:
  71. r_b |= 1 << bit
  72. i -= 1
  73. rom[byte] = r_b
  74. return rom, next_diff
  75. def crc8(self, data):
  76. return _ow.crc8(data)