Skip to content

Commit 787a2fd

Browse files
committed
added shake; needs tuning
1 parent 12b2293 commit 787a2fd

File tree

2 files changed

+62
-6
lines changed

2 files changed

+62
-6
lines changed

adafruit_bno080/__init__.py

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@
3232
from time import sleep, monotonic, monotonic_ns
3333
from micropython import const
3434

35+
# TODO: Remove on release
36+
from .debug import channels, reports
37+
3538
# TODO: shorten names
3639
# Channel 0: the SHTP command channel
3740
_BNO_CHANNEL_SHTP_COMMAND = const(0)
@@ -74,6 +77,8 @@
7477
_BNO_REPORT_ROTATION_VECTOR = const(0x05)
7578
_BNO_REPORT_GEOMAGNETIC_ROTATION_VECTOR = const(0x09)
7679
_BNO_REPORT_STEP_COUNTER = const(0x11)
80+
_BNO_REPORT_SHAKE_DETECTOR = const(0x19)
81+
7782

7883
_DEFAULT_REPORT_INTERVAL = const(50000) # in microseconds = 50ms
7984
_QUAT_READ_TIMEOUT = 0.500 # timeout in seconds
@@ -114,6 +119,7 @@
114119
_BNO_REPORT_ROTATION_VECTOR: (_Q_POINT_14_SCALAR, 4, 14,),
115120
_BNO_REPORT_GEOMAGNETIC_ROTATION_VECTOR: (_Q_POINT_12_SCALAR, 4, 14),
116121
_BNO_REPORT_STEP_COUNTER: (1, 1, 12),
122+
_BNO_REPORT_SHAKE_DETECTOR: (1, 1, 6),
117123
}
118124

119125
DATA_BUFFER_SIZE = const(512) # data buffer size. obviously eats ram
@@ -168,7 +174,12 @@ def _parse_sensor_report_data(report_bytes):
168174
# 10 Reserved
169175
# 11 Reserved
170176
def _parse_step_couter_report(report_bytes):
171-
return unpack_from("<h", report_bytes, offset=8)[0]
177+
return unpack_from("<H", report_bytes, offset=8)[0]
178+
179+
180+
def _parse_shake_report(report_bytes):
181+
shake_bitfield = unpack_from("<H", report_bytes, offset=4)[0]
182+
return (shake_bitfield & 0x111) > 0
172183

173184

174185
def parse_sensor_id(buffer):
@@ -222,7 +233,6 @@ def __init__(self, packet_bytes):
222233
self.data = packet_bytes[_BNO_HEADER_LEN:data_end_index]
223234

224235
def __str__(self):
225-
from .debug import channels, reports # pylint:disable=import-outside-toplevel
226236

227237
length = self.header.packet_byte_count
228238
outstr = "\n\t\t********** Packet *************\n"
@@ -252,11 +262,20 @@ def __str__(self):
252262
and len(self.data) >= 6
253263
and self.data[5] in reports
254264
):
255-
outstr += "DBG::\t\t \tSensor Report Type: %s(%d)\n" % (
265+
outstr += "DBG::\t\t \tSensor Report Type: %s(%s)\n" % (
256266
reports[self.data[5]],
257-
self.data[5],
267+
hex(self.data[5]),
258268
)
259269

270+
if (
271+
self.report_id == 0xFC
272+
and len(self.data) >= 6
273+
and self.data[1] in reports
274+
):
275+
outstr += "DBG::\t\t \tEnabled Feature: %s(%s)\n" % (
276+
reports[self.data[1]],
277+
hex(self.data[5]),
278+
)
260279
outstr += "DBG::\t\t Sequence number: %s\n" % self.header.sequence_number
261280
outstr += "\n"
262281
outstr += "DBG::\t\t Data:"
@@ -383,6 +402,20 @@ def gyro(self):
383402
self._process_available_packets()
384403
return self._readings[_BNO_REPORT_GYROSCOPE]
385404

405+
@property
406+
def shake(self):
407+
"""True if a shake was detected on any axis since the last time it was checked
408+
409+
This property has a "latching" behavior where once a shake is detected, it will stay in a
410+
"shaken" state until the value is read. This prevents missing shake events but means that
411+
this property is not guaranteed to reflect the shake state at the moment it is read
412+
"""
413+
self._process_available_packets()
414+
shake_detected = self._readings[_BNO_REPORT_SHAKE_DETECTOR]
415+
# clear on read
416+
if shake_detected:
417+
self._readings[_BNO_REPORT_SHAKE_DETECTOR] = False
418+
386419
# # decorator?
387420
def _process_available_packets(self):
388421
processed_count = 0
@@ -459,9 +492,27 @@ def _handle_control_report(self, report_id, report_bytes):
459492

460493
def _process_report(self, report_id, report_bytes):
461494
if report_id < 0xF0:
495+
self._dbg("\tProcessing report:", reports[report_id])
496+
if self._debug:
497+
outstr = ""
498+
for idx, packet_byte in enumerate(report_bytes):
499+
packet_index = idx
500+
if (packet_index % 4) == 0:
501+
outstr += "\nDBG::\t\t[0x{:02X}] ".format(packet_index)
502+
outstr += "0x{:02X} ".format(packet_byte)
503+
print(outstr)
504+
self._dbg("")
505+
462506
if report_id == _BNO_REPORT_STEP_COUNTER:
463507
self._readings[report_id] = _parse_step_couter_report(report_bytes)
464508
return
509+
if report_id == _BNO_REPORT_SHAKE_DETECTOR:
510+
shake_detected = _parse_shake_report(report_bytes)
511+
# shake not previously detected - auto cleared by 'shake' property
512+
if not self._readings[_BNO_REPORT_SHAKE_DETECTOR]:
513+
self._readings[_BNO_REPORT_SHAKE_DETECTOR] = shake_detected
514+
return
515+
465516
sensor_data = _parse_sensor_report_data(report_bytes)
466517
# TODO: FIXME; Sensor reports are batched in a LIFO which means that multiple reports
467518
# for the same type will end with the oldest/last being kept and the other
@@ -472,12 +523,14 @@ def _process_report(self, report_id, report_bytes):
472523

473524
# TODO: Make this a Packet creation
474525
@staticmethod
475-
def _get_feature_enable_report(feature_id):
526+
def _get_feature_enable_report(
527+
feature_id, report_interval=_DEFAULT_REPORT_INTERVAL
528+
):
476529
# TODO !!! ALLOCATION !!!
477530
set_feature_report = bytearray(17)
478531
set_feature_report[0] = _BNO_CMD_SET_FEATURE_COMMAND
479532
set_feature_report[1] = feature_id
480-
pack_into("<I", set_feature_report, 5, _DEFAULT_REPORT_INTERVAL)
533+
pack_into("<I", set_feature_report, 5, report_interval)
481534
return set_feature_report
482535

483536
def _enable_feature(self, feature_id):

examples/bno080_simpletest.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,8 @@
5959
print("")
6060
print("Steps detected:", bno.steps)
6161
print("")
62+
if bno.shake:
63+
print("SHAKE DETECTED!")
64+
print("")
6265

6366
sleep(0.5)

0 commit comments

Comments
 (0)