diff --git a/esp8266/tests/onewire.py b/esp8266/tests/onewire.py new file mode 100644 index 0000000000..15fec1e55c --- /dev/null +++ b/esp8266/tests/onewire.py @@ -0,0 +1,147 @@ +import time +import pyb +import _onewire as _ow + +class OneWire: + CMD_SEARCHROM = const(0xf0) + CMD_READROM = const(0x33) + CMD_MATCHROM = const(0x55) + CMD_SKIPROM = const(0xcc) + + def __init__(self, pin): + self.pin = pin + self.pin.init(pin.OPEN_DRAIN, pin.PULL_NONE) + + def reset(self): + return _ow.reset(self.pin) + + def read_bit(self): + return _ow.readbit(self.pin) + + def read_byte(self): + return _ow.readbyte(self.pin) + + def read_bytes(self, count): + buf = bytearray(count) + for i in range(count): + buf[i] = _ow.readbyte(self.pin) + return buf + + def write_bit(self, value): + return _ow.writebit(self.pin, value) + + def write_byte(self, value): + return _ow.writebyte(self.pin, value) + + def write_bytes(self, buf): + for b in buf: + _ow.writebyte(self.pin, b) + + def select_rom(self, rom): + self.reset() + self.write_byte(CMD_MATCHROM) + self.write_bytes(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.write_byte(CMD_SEARCHROM) + 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.read_bit() + if self.read_bit(): + 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.write_bit(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) + +class DS18B20: + THERM_CMD_CONVERTTEMP = const(0x44) + THERM_CMD_RSCRATCHPAD = const(0xbe) + + def __init__(self, onewire): + self.ow = onewire + self.roms = [] + + def scan(self): + self.roms = [] + for rom in self.ow.scan(): + if rom[0] == 0x28: + self.roms += [rom] + return self.roms + + def start_measure(self): + if not self.ow.reset(): + return False + self.ow.write_byte(CMD_SKIPROM) + self.ow.write_byte(THERM_CMD_CONVERTTEMP) + return True + + def get_temp(self, rom): + if not self.ow.reset(): + return None + + self.ow.select_rom(rom) + self.ow.write_byte(THERM_CMD_RSCRATCHPAD) + + buf = self.ow.read_bytes(9) + if self.ow.crc8(buf): + return None + + return self._convert_temp(buf) + + def _convert_temp(self, data): + temp_lsb = data[0] + temp_msb = data[1] + return (temp_msb << 8 | temp_lsb) / 16 + +# connect 1-wire temp sensors to GPIO12 for this test +def test(): + dat = pyb.Pin(12) + ow = OneWire(dat) + + ds = DS18B20(ow) + roms = ow.scan() + print('found devices:', roms) + + for i in range(4): + print('temperatures:', end=' ') + ds.start_measure() + time.sleep_ms(750) + for rom in roms: + print(ds.get_temp(rom), end=' ') + print() + +#pyb.freq(80000000) +#pyb.freq(160000000) +test()