Skip to content

Commit 00eda04

Browse files
authored
Merge pull request #3 from adafruit/uart
Uart
2 parents 0015261 + fbfff21 commit 00eda04

9 files changed

+413
-155
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ bundles
1616
dist
1717
**/*.egg-info
1818
.vscode
19-
*notes*
19+
*notes*

adafruit_bno080/__init__.py

Lines changed: 48 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,13 @@
3131
from collections import namedtuple
3232
import time
3333
from micropython import const
34-
import digitalio
3534

3635
# TODO: Remove on release
3736
from .debug import channels, reports
3837

3938
# TODO: shorten names
4039
# Channel 0: the SHTP command channel
41-
_BNO_CHANNEL_SHTP_COMMAND = const(0)
40+
BNO_CHANNEL_SHTP_COMMAND = const(0)
4241
BNO_CHANNEL_EXE = const(1)
4342
_BNO_CHANNEL_CONTROL = const(2)
4443
_BNO_CHANNEL_INPUT_SENSOR_REPORTS = const(3)
@@ -134,7 +133,8 @@
134133

135134
class PacketError(Exception):
136135
"""Raised when the packet couldnt be parsed"""
137-
pass
136+
137+
pass # pylint:disable=unnecessary-pass
138138

139139

140140
def _elapsed(start_time):
@@ -145,11 +145,11 @@ def elapsed_time(func):
145145
"""Print the runtime of the decorated function"""
146146

147147
def wrapper_timer(*args, **kwargs):
148-
start_time = time.monotonic_ns() # 1
148+
start_time = time.monotonic() # 1
149149
value = func(*args, **kwargs)
150-
end_time = time.monotonic_ns() # 2
150+
end_time = time.monotonic() # 2
151151
run_time = end_time - start_time # 3
152-
print("Finished", func.__name__, "in", (run_time / 1000000.0), "ms")
152+
print("Finished", func.__name__, "in", (run_time * 1000.0), "ms")
153153
return value
154154

155155
return wrapper_timer
@@ -388,7 +388,9 @@ def geomagnetic_quaternion(self):
388388
try:
389389
return self._readings[BNO_REPORT_GEOMAGNETIC_ROTATION_VECTOR]
390390
except KeyError:
391-
raise RuntimeError("No geomag quaternion report found, is it enabled?") from None
391+
raise RuntimeError(
392+
"No geomag quaternion report found, is it enabled?"
393+
) from None
392394

393395
@property
394396
def steps(self):
@@ -450,15 +452,15 @@ def shake(self):
450452
def _process_available_packets(self):
451453
processed_count = 0
452454
while self._data_ready:
453-
print("reading a packet")
455+
# print("reading a packet")
454456
try:
455457
new_packet = self._read_packet()
456458
except PacketError:
457459
continue
458460
self._handle_packet(new_packet)
459461
processed_count += 1
460462
self._dbg("")
461-
#print("Processed", processed_count, "packets")
463+
# print("Processed", processed_count, "packets")
462464
self._dbg("")
463465
# we'll probably need an exit here for fast sensor rates
464466
self._dbg("")
@@ -480,8 +482,12 @@ def _wait_for_packet_type(self, channel_number, report_id=None, timeout=5.0):
480482
return new_packet
481483
else:
482484
return new_packet
483-
self._dbg("passing packet to handler for de-slicing")
484-
self._handle_packet(new_packet)
485+
if new_packet.channel_number not in (
486+
BNO_CHANNEL_EXE,
487+
BNO_CHANNEL_SHTP_COMMAND,
488+
):
489+
self._dbg("passing packet to handler for de-slicing")
490+
self._handle_packet(new_packet)
485491

486492
raise RuntimeError("Timed out waiting for a packet on channel", channel_number)
487493

@@ -503,11 +509,14 @@ def _update_sequence_number(self, new_packet):
503509
self._sequence_number[channel] = seq
504510

505511
def _handle_packet(self, packet):
506-
507512
# split out reports first
508-
_separate_batch(packet, self._packet_slices)
509-
while len(self._packet_slices) > 0:
510-
self._process_report(*self._packet_slices.pop())
513+
try:
514+
_separate_batch(packet, self._packet_slices)
515+
while len(self._packet_slices) > 0:
516+
self._process_report(*self._packet_slices.pop())
517+
except Exception as error:
518+
print(packet)
519+
raise error
511520

512521
def _handle_control_report(self, report_id, report_bytes):
513522
if report_id == _SHTP_REPORT_PRODUCT_ID_RESPONSE:
@@ -543,8 +552,11 @@ def _process_report(self, report_id, report_bytes):
543552
if report_id == BNO_REPORT_SHAKE_DETECTOR:
544553
shake_detected = _parse_shake_report(report_bytes)
545554
# shake not previously detected - auto cleared by 'shake' property
546-
if not self._readings[BNO_REPORT_SHAKE_DETECTOR]:
547-
self._readings[BNO_REPORT_SHAKE_DETECTOR] = shake_detected
555+
try:
556+
if not self._readings[BNO_REPORT_SHAKE_DETECTOR]:
557+
self._readings[BNO_REPORT_SHAKE_DETECTOR] = shake_detected
558+
except KeyError:
559+
pass
548560
return
549561

550562
sensor_data = _parse_sensor_report_data(report_bytes)
@@ -567,11 +579,13 @@ def _get_feature_enable_report(
567579
pack_into("<I", set_feature_report, 5, report_interval)
568580
return set_feature_report
569581

582+
# TODO: add docs for available features
570583
def enable_feature(self, feature_id):
584+
"""Used to enable a given feature of the BNO080"""
571585
self._dbg("\n********** Enabling feature id:", feature_id, "**********")
572586

573587
set_feature_report = self._get_feature_enable_report(feature_id)
574-
print("Enabling", feature_id)
588+
# print("Enabling", feature_id)
575589
self._send_packet(_BNO_CHANNEL_CONTROL, set_feature_report)
576590
while True:
577591
packet = self._wait_for_packet_type(
@@ -585,11 +599,9 @@ def enable_feature(self, feature_id):
585599
self._readings[feature_id] = (0.0, 0.0, 0.0, 0.0)
586600
else:
587601
self._readings[feature_id] = (0.0, 0.0, 0.0)
588-
print("Enabled", feature_id)
602+
# print("Enabled", feature_id)
589603
break
590-
else:
591-
raise RuntimeError("Was not able to enable feature", feature_id)
592-
604+
raise RuntimeError("Was not able to enable feature", feature_id)
593605

594606
def _check_id(self):
595607
self._dbg("\n********** READ ID **********")
@@ -641,7 +653,6 @@ def _get_data(self, index, fmt_string):
641653
data_index = index + 4
642654
return unpack_from(fmt_string, self._data_buffer, offset=data_index)[0]
643655

644-
645656
# pylint:disable=no-self-use
646657
@property
647658
def _data_ready(self):
@@ -651,7 +662,9 @@ def hard_reset(self):
651662
"""Hardware reset the sensor to an initial unconfigured state"""
652663
if not self._reset:
653664
return
654-
#print("Hard resetting...")
665+
# print("Hard resetting...")
666+
import digitalio # pylint:disable=import-outside-toplevel
667+
655668
self._reset.direction = digitalio.Direction.OUTPUT
656669
self._reset.value = True
657670
time.sleep(0.01)
@@ -665,25 +678,18 @@ def soft_reset(self):
665678
print("Soft resetting...", end="")
666679
data = bytearray(1)
667680
data[0] = 1
668-
seq = self._send_packet(BNO_CHANNEL_EXE, data)
681+
_seq = self._send_packet(BNO_CHANNEL_EXE, data)
669682
time.sleep(0.5)
670-
671-
for i in range(3):
672-
while True: # retry reading packets until ready!
673-
try:
674-
packet = self._read_packet()
675-
break
676-
except PacketError:
677-
time.sleep(0.1)
678-
679-
#print(packet)
680-
if i == 0 and packet.channel_number != _BNO_CHANNEL_SHTP_COMMAND:
681-
raise RuntimeError("Expected an SHTP announcement")
682-
if i == 1 and packet.channel_number != BNO_CHANNEL_EXE:
683-
raise RuntimeError("Expected a reset reply")
684-
if i == 2 and packet.channel_number != _BNO_CHANNEL_CONTROL:
685-
raise RuntimeError("Expected a control announcement")
686-
print("OK!");
683+
_seq = self._send_packet(BNO_CHANNEL_EXE, data)
684+
time.sleep(0.5)
685+
686+
for _i in range(3):
687+
try:
688+
_packet = self._read_packet()
689+
except PacketError:
690+
time.sleep(0.5)
691+
692+
print("OK!")
687693
# all is good!
688694

689695
def _send_packet(self, channel, data):

adafruit_bno080/i2c.py

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,9 @@
66
Subclass of `adafruit_bno080.BNO080` to use I2C
77
88
"""
9-
import time
109
from struct import pack_into
1110
import adafruit_bus_device.i2c_device as i2c_device
12-
from . import BNO080, BNO_CHANNEL_EXE, DATA_BUFFER_SIZE, const, Packet, PacketError
13-
14-
# should be removeable; I _think_ something else should be able to prep the buffers?
11+
from . import BNO080, DATA_BUFFER_SIZE, const, Packet, PacketError
1512

1613
_BNO080_DEFAULT_ADDRESS = const(0x4A)
1714

@@ -23,7 +20,9 @@ class BNO080_I2C(BNO080):
2320
2421
"""
2522

26-
def __init__(self, i2c_bus, reset=None, address=_BNO080_DEFAULT_ADDRESS, debug=False):
23+
def __init__(
24+
self, i2c_bus, reset=None, address=_BNO080_DEFAULT_ADDRESS, debug=False
25+
):
2726
self.bus_device_obj = i2c_device.I2CDevice(i2c_bus, address)
2827
super().__init__(reset, debug)
2928

@@ -33,10 +32,7 @@ def _send_packet(self, channel, data):
3332

3433
pack_into("<H", self._data_buffer, 0, write_length)
3534
self._data_buffer[2] = channel
36-
3735
self._data_buffer[3] = self._sequence_number[channel]
38-
39-
# this is dumb but it's what we have for now
4036
for idx, send_byte in enumerate(data):
4137
self._data_buffer[4 + idx] = send_byte
4238

@@ -58,12 +54,10 @@ def _read_header(self):
5854
return packet_header
5955

6056
def _read_packet(self):
61-
# TODO: MAGIC NUMBER?
62-
# TODO: this can be `_read_header` or know it's done by `_data_ready`
6357
with self.bus_device_obj as i2c:
6458
i2c.readinto(self._data_buffer, end=4) # this is expecting a header?
6559
self._dbg("")
66-
#print("SHTP READ packet header: ", [hex(x) for x in self._data_buffer[0:4]])
60+
# print("SHTP READ packet header: ", [hex(x) for x in self._data_buffer[0:4]])
6761

6862
header = Packet.header_from_buffer(self._data_buffer)
6963
packet_byte_count = header.packet_byte_count
@@ -85,7 +79,6 @@ def _read_packet(self):
8579

8680
self._read(packet_byte_count)
8781

88-
# TODO: Allocation
8982
new_packet = Packet(self._data_buffer)
9083
if self._debug:
9184
print(new_packet)
@@ -114,7 +107,6 @@ def _data_ready(self):
114107

115108
if header.channel_number > 5:
116109
self._dbg("channel number out of range:", header.channel_number)
117-
# data_length, packet_byte_count)
118110
if header.packet_byte_count == 0x7FFF:
119111
print("Byte count is 0x7FFF/0xFFFF; Error?")
120112
if header.sequence_number == 0xFF:

0 commit comments

Comments
 (0)