Skip to content

Commit 558d835

Browse files
committed
working but unlinted
1 parent 7191d85 commit 558d835

File tree

1 file changed

+94
-1
lines changed

1 file changed

+94
-1
lines changed

adafruit_tfmini.py

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,100 @@
3939
4040
"""
4141

42-
# imports
42+
import time
43+
import struct
4344

4445
__version__ = "0.0.0-auto.0"
4546
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_TFmini.git"
47+
48+
_STARTCONFIG = b'\x42\x57\x02\x00\x00\x00\x01\x02'
49+
_STARTREPLY = b'\x57\x02\x01\x00\x00\x01\x02' # minus header 0x42
50+
_CONFIGPARAM = b'\x42\x57\x02\x00'
51+
_ENDCONFIG = b'\x42\x57\x02\x00\x00\x00\x00\x02'
52+
_ENDREPLY = b'\x42\x57\x02\x01\x00\x00\x00\x02'
53+
54+
MODE_SHORT = 2
55+
MODE_LONG = 7
56+
57+
class TFmini:
58+
"""TF mini communication module, use with just RX or TX+RX for advanced
59+
command & control.
60+
"""
61+
62+
def __init__(self, uart, *, timeout=3):
63+
self._uart = uart
64+
self._uart.baudrate = 115200
65+
self.timeout = timeout
66+
self._strength = None
67+
self._mode = None
68+
69+
@property
70+
def distance(self):
71+
"""The most recent distance measurement in centimeters"""
72+
# listen for new packet
73+
stamp = time.monotonic()
74+
while time.monotonic() - stamp < self.timeout:
75+
# look for the header start
76+
c = self._uart.read(1)
77+
if c[0] != 0x59:
78+
continue
79+
# get remaining packet
80+
data = self._uart.read(8)
81+
# check first byte is magicbyte
82+
framebyte, distance, self._strength, self._mode, _, checksum = struct.unpack("<BHHBBB",data)
83+
# look for second 0x59 frame indicator
84+
if framebyte != 0x59:
85+
continue
86+
# calculate and check sum
87+
mysum = (sum(data[0:7]) + 0x59) & 0xFF
88+
if mysum != checksum:
89+
continue
90+
return distance
91+
raise RuntimeError("Timed out looking for valid data")
92+
93+
@property
94+
def strength(self):
95+
self.distance
96+
return self._strength
97+
98+
@property
99+
def mode(self):
100+
self.distance
101+
return self._mode
102+
103+
@mode.setter
104+
def mode(self, newmode):
105+
if not newmode in (MODE_LONG, MODE_SHORT):
106+
raise ValueError("Invalid mode")
107+
self._set_config(_CONFIGPARAM + bytes([0, 0, newmode, 0x11]))
108+
109+
def _set_config(self, command):
110+
self._uart.write(_STARTCONFIG)
111+
stamp = time.monotonic()
112+
while (time.monotonic() - stamp) < self.timeout:
113+
# look for the header start
114+
c = self._uart.read(1)
115+
if c is None or c[0] != 0x42:
116+
continue
117+
echo = self._uart.read(len(_STARTREPLY))
118+
#print("start ", [hex(i) for i in echo])
119+
if echo != _STARTREPLY:
120+
raise RuntimeError("Did not receive config start echo")
121+
break
122+
123+
# Finally, send the command
124+
self._uart.write(command)
125+
#print([hex(i) for i in command])
126+
echo = self._uart.read(len(command))
127+
cmdreply = bytearray(len(command))
128+
cmdreply[:] = command
129+
cmdreply[3] = 0x1
130+
#print("cmd ", [hex(i) for i in echo])
131+
if echo != cmdreply:
132+
raise RuntimeError("Did not receive config command echo")
133+
134+
self._uart.write(_ENDCONFIG)
135+
echo = self._uart.read(len(_ENDREPLY))
136+
#print("end ", [hex(i) for i in echo])
137+
if echo != _ENDREPLY:
138+
raise RuntimeError("Did not receive config end echo")

0 commit comments

Comments
 (0)