1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
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()
|