From 6536793ad11c63b27a4798d963ab0ae3d10414f0 Mon Sep 17 00:00:00 2001 From: Matt Baker Date: Thu, 17 Mar 2022 12:45:25 -0700 Subject: [PATCH 1/4] usb: reduced read overhead for performance --- mbientlab/metawear/metawear.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/mbientlab/metawear/metawear.py b/mbientlab/metawear/metawear.py index e900582..c643aa5 100644 --- a/mbientlab/metawear/metawear.py +++ b/mbientlab/metawear/metawear.py @@ -58,6 +58,10 @@ class MetaWearUSB(object): GATT_MW_CHAR_COMMAND = '326a9001-85cb-9195-d9dd-464cfbbae75a' GATT_MW_CHAR_NOTIFICATION = '326a9006-85cb-9195-d9dd-464cfbbae75a' + SERIAL_XFER_SIZE = 1024 + SERIAL_BYTE_START = b'\x1f' + SERIAL_BYTE_STOP = b'\n' + @staticmethod def scan(): """List MetaWear devices attached to USB""" @@ -202,10 +206,10 @@ def _bin_cmd_decode(self, c): elif self._cmd_recv_len < self._cmd_len: self._cmd_recv_len += 1 self._cmd_buffer += c - elif c == b'\n': + elif c == MetaWearUSB.SERIAL_BYTE_STOP: self._cmd_started = False return self._cmd_buffer - elif c == b'\x1f': + elif c == MetaWearUSB.SERIAL_BYTE_START: self._cmd_started = True self._cmd_len = 0 self._cmd_recv_len = 0 @@ -217,18 +221,20 @@ def _read_poller(self): self._cmd_started = False while self._read_poll: try: - c = self.ser.read() + read_len = max(1, min(MetaWearUSB.SERIAL_XFER_SIZE, self.ser.in_waiting)) + line_bytes = self.ser.read(read_len) except serial.SerialException: self._read_poll = False self.disconnect() return - if len(c) < 1: + if len(line_bytes) < 1: continue - cmd = self._bin_cmd_decode(c) - if len(cmd) > 0: - if self._notify_handler is not None: - self._notify_handler(cmd) + for i in range(len(line_bytes)): + cmd = self._bin_cmd_decode(line_bytes[i:i+1]) + if len(cmd) > 0: + if self._notify_handler is not None: + self._notify_handler(cmd) def _write_poller(self): """Write poller enabling async writes and write response callbacks.""" From e76e8ce248f4829ad12071ba11fdff614899d434 Mon Sep 17 00:00:00 2001 From: Matt Baker Date: Wed, 23 Mar 2022 09:44:24 -0700 Subject: [PATCH 2/4] examples: add magnetometer streaming example. --- examples/stream_mag.py | 69 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 examples/stream_mag.py diff --git a/examples/stream_mag.py b/examples/stream_mag.py new file mode 100644 index 0000000..2b88129 --- /dev/null +++ b/examples/stream_mag.py @@ -0,0 +1,69 @@ +# usage: python3 stream_mag.py [mac1] [mac2] ... [mac(n)] +from __future__ import print_function +from mbientlab.metawear import MetaWear, libmetawear, parse_value +from mbientlab.metawear.cbindings import * +from time import sleep +from threading import Event + +import platform +import sys + +if sys.version_info[0] == 2: + range = xrange + +class State: + # init + def __init__(self, device): + self.device = device + self.samples = 0 + self.magCallback = FnVoid_VoidP_DataP(self.mag_data_handler) + + # mag callback + def mag_data_handler(self, ctx, data): + print("MAG: %s -> %s" % (self.device.address, parse_value(data))) + self.samples+= 1 + +states = [] + +# connect +for i in range(len(sys.argv) - 1): + d = MetaWear(sys.argv[i + 1]) + d.connect() + print("Connected to %s over %s" % (d.address, "USB" if d.usb.is_connected else "BLE")) + states.append(State(d)) + +# configure +for s in states: + print("Configuring device") + libmetawear.mbl_mw_settings_set_connection_parameters(s.device.board, 7.5, 7.5, 0, 6000) + sleep(1.5) + + # setup mag + libmetawear.mbl_mw_mag_bmm150_stop(s.device.board) + libmetawear.mbl_mw_mag_bmm150_set_preset(s.device.board, MagBmm150Preset.REGULAR) + + # get mag and subscribe + mag = libmetawear.mbl_mw_mag_bmm150_get_b_field_data_signal(s.device.board) + libmetawear.mbl_mw_datasignal_subscribe(mag, None, s.magCallback) + + # start mag + libmetawear.mbl_mw_mag_bmm150_enable_b_field_sampling(s.device.board) + libmetawear.mbl_mw_mag_bmm150_start(s.device.board) + +# sleep +sleep(10.0) + +# stop +for s in states: + libmetawear.mbl_mw_mag_bmm150_stop(s.device.board) + libmetawear.mbl_mw_mag_bmm150_disable_b_field_sampling(s.device.board) + + mag = libmetawear.mbl_mw_mag_bmm150_get_b_field_data_signal(s.device.board) + libmetawear.mbl_mw_datasignal_unsubscribe(mag) + + libmetawear.mbl_mw_debug_disconnect(s.device.board) + +# recap +print("Total Samples Received") +for s in states: + print("%s -> %d" % (s.device.address, s.samples)) From ffba7bc9fa58553db0946f2d5e9b94494e563460 Mon Sep 17 00:00:00 2001 From: Matt Baker Date: Mon, 4 Apr 2022 16:50:30 -0700 Subject: [PATCH 3/4] usb: add connection type debug message to examples. --- examples/acc_threshold_detector.py | 2 +- examples/anonymous_datasignals.py | 2 +- examples/calibrate.py | 2 +- examples/data_fuser.py | 2 +- examples/data_processor.py | 2 +- examples/firmware_build.py | 2 +- examples/full_reset.py | 2 +- examples/led.py | 2 +- examples/led_dongle.py | 2 +- examples/led_temp.py | 2 +- examples/log_acc.py | 2 +- examples/log_acc_perf.py | 2 +- examples/log_download.py | 2 +- examples/log_temp.py | 2 +- examples/macro_remove.py | 2 +- examples/macro_setup.py | 2 +- examples/motion_record_log.py | 2 +- examples/motion_record_log_no_reset.py | 2 +- examples/motion_record_stream.py | 2 +- examples/scan_connect.py | 2 +- examples/stream_acc.py | 2 +- examples/stream_acc_gyro_bmi160.py | 2 +- examples/stream_acc_gyro_bmi270.py | 2 +- examples/stream_acc_packed.py | 2 +- examples/stream_acc_x.py | 2 +- examples/stream_gyro_packed.py | 2 +- examples/stream_quat.py | 2 +- examples/stream_temp.py | 2 +- 28 files changed, 28 insertions(+), 28 deletions(-) diff --git a/examples/acc_threshold_detector.py b/examples/acc_threshold_detector.py index c3321c3..562b5e8 100644 --- a/examples/acc_threshold_detector.py +++ b/examples/acc_threshold_detector.py @@ -8,7 +8,7 @@ print("Searching for device...") d = MetaWear(sys.argv[1]) d.connect() -print("Connected to " + d.address) +print("Connected to " + d.address + " over " + ("USB" if d.usb.is_connected else "BLE")) print("Configuring device") libmetawear.mbl_mw_settings_set_connection_parameters(d.board, 7.5, 7.5, 0, 6000) sleep(1.0) diff --git a/examples/anonymous_datasignals.py b/examples/anonymous_datasignals.py index 1e861cc..6046faa 100644 --- a/examples/anonymous_datasignals.py +++ b/examples/anonymous_datasignals.py @@ -14,7 +14,7 @@ # connect metawear = MetaWear(sys.argv[1]) metawear.connect() -print("Connected") +print("Connected to " + metawear.address + " over " + ("USB" if metawear.usb.is_connected else "BLE")) # setup e = Event() diff --git a/examples/calibrate.py b/examples/calibrate.py index 721c97f..6584cd9 100644 --- a/examples/calibrate.py +++ b/examples/calibrate.py @@ -10,7 +10,7 @@ # connect device = MetaWear(sys.argv[1]) device.connect() -print("Connected") +print("Connected to " + device.address + " over " + ("USB" if device.usb.is_connected else "BLE")) # event e = Event() diff --git a/examples/data_fuser.py b/examples/data_fuser.py index e465d97..ad72723 100644 --- a/examples/data_fuser.py +++ b/examples/data_fuser.py @@ -65,7 +65,7 @@ def start(self): for i in range(len(argv) - 1): d = MetaWear(argv[i + 1]) d.connect() - print("Connected to " + d.address) + print("Connected to " + d.address + " over " + ("USB" if d.usb.is_connected else "BLE")) states.append(State(d)) # configure diff --git a/examples/data_processor.py b/examples/data_processor.py index 42f1253..45254a0 100644 --- a/examples/data_processor.py +++ b/examples/data_processor.py @@ -47,7 +47,7 @@ def start(self): for i in range(len(argv) - 1): d = MetaWear(argv[i + 1]) d.connect() - print("Connected to " + d.address) + print("Connected to " + d.address + " over " + ("USB" if d.usb.is_connected else "BLE")) states.append(State(d)) # configure diff --git a/examples/firmware_build.py b/examples/firmware_build.py index 7e71c1f..cd42638 100644 --- a/examples/firmware_build.py +++ b/examples/firmware_build.py @@ -10,7 +10,7 @@ # connect m = MetaWear(sys.argv[1]) m.connect() -print("Connected") +print("Connected to " + m.address + " over " + ("USB" if m.usb.is_connected else "BLE")) # get board info size = c_uint(0) diff --git a/examples/full_reset.py b/examples/full_reset.py index 6168e33..37e515d 100644 --- a/examples/full_reset.py +++ b/examples/full_reset.py @@ -9,7 +9,7 @@ # connect device = MetaWear(sys.argv[1]) device.connect() -print("Connected") +print("Connected to " + device.address + " over " + ("USB" if device.usb.is_connected else "BLE")) # stop logging libmetawear.mbl_mw_logging_stop(device.board) diff --git a/examples/led.py b/examples/led.py index 282952c..e167c18 100644 --- a/examples/led.py +++ b/examples/led.py @@ -10,7 +10,7 @@ # connect device = MetaWear(sys.argv[1]) device.connect() -print("Connected") +print("Connected to " + device.address + " over " + ("USB" if device.usb.is_connected else "BLE")) # create led pattern pattern= LedPattern(repeat_count= Const.LED_REPEAT_INDEFINITELY) diff --git a/examples/led_dongle.py b/examples/led_dongle.py index db0be18..8d14f9b 100644 --- a/examples/led_dongle.py +++ b/examples/led_dongle.py @@ -11,7 +11,7 @@ # Add hci_mac to the setup to specify which dongle to use device = MetaWear(sys.argv[1], hci_mac="B8:27:EB:F2:61:2E") device.connect() -print("Connected") +print("Connected to " + device.address + " over " + ("USB" if device.usb.is_connected else "BLE")) # create led pattern pattern= LedPattern(repeat_count= Const.LED_REPEAT_INDEFINITELY) diff --git a/examples/led_temp.py b/examples/led_temp.py index 282952c..e167c18 100644 --- a/examples/led_temp.py +++ b/examples/led_temp.py @@ -10,7 +10,7 @@ # connect device = MetaWear(sys.argv[1]) device.connect() -print("Connected") +print("Connected to " + device.address + " over " + ("USB" if device.usb.is_connected else "BLE")) # create led pattern pattern= LedPattern(repeat_count= Const.LED_REPEAT_INDEFINITELY) diff --git a/examples/log_acc.py b/examples/log_acc.py index d738717..a1d560c 100644 --- a/examples/log_acc.py +++ b/examples/log_acc.py @@ -10,7 +10,7 @@ print("Searching for device...") d = MetaWear(sys.argv[1]) d.connect() -print("Connected to " + d.address) +print("Connected to " + d.address + " over " + ("USB" if d.usb.is_connected else "BLE")) print("Configuring device") diff --git a/examples/log_acc_perf.py b/examples/log_acc_perf.py index 6323972..695fc1a 100644 --- a/examples/log_acc_perf.py +++ b/examples/log_acc_perf.py @@ -10,7 +10,7 @@ print("Searching for device...") d = MetaWear(sys.argv[1]) d.connect() -print("Connected to " + d.address) +print("Connected to " + d.address + " over " + ("USB" if d.usb.is_connected else "BLE")) print("Configuring device") diff --git a/examples/log_download.py b/examples/log_download.py index 3f2349c..14dca58 100644 --- a/examples/log_download.py +++ b/examples/log_download.py @@ -14,7 +14,7 @@ # connect metawear = MetaWear(sys.argv[1]) metawear.connect() -print("Connected") +print("Connected to " + metawear.address + " over " + ("USB" if metawear.usb.is_connected else "BLE")) # setup e = Event() diff --git a/examples/log_temp.py b/examples/log_temp.py index ceb0a8a..27aaedd 100644 --- a/examples/log_temp.py +++ b/examples/log_temp.py @@ -11,7 +11,7 @@ print("Searching for device...") d = MetaWear(sys.argv[1]) d.connect() -print("Connected to " + d.address) +print("Connected to " + d.address + " over " + ("USB" if d.usb.is_connected else "BLE")) try: # setup events diff --git a/examples/macro_remove.py b/examples/macro_remove.py index 909f73b..c681707 100644 --- a/examples/macro_remove.py +++ b/examples/macro_remove.py @@ -13,7 +13,7 @@ # connect device = MetaWear(sys.argv[1]) device.connect() -print("Connected to " + device.address) +print("Connected to " + device.address + " over " + ("USB" if device.usb.is_connected else "BLE")) sleep(1.0) # remove macros diff --git a/examples/macro_setup.py b/examples/macro_setup.py index f942cc8..8fe2fcd 100644 --- a/examples/macro_setup.py +++ b/examples/macro_setup.py @@ -13,7 +13,7 @@ # connect device.connect() -print("Connected to " + device.address) +print("Connected to " + device.address + " over " + ("USB" if device.usb.is_connected else "BLE")) # setup events e = Event() diff --git a/examples/motion_record_log.py b/examples/motion_record_log.py index 93d840a..840ee5a 100644 --- a/examples/motion_record_log.py +++ b/examples/motion_record_log.py @@ -40,7 +40,7 @@ def wont_be_used(): for i in range(len(sys.argv) - 1): d = MetaWear(sys.argv[i + 1]) d.connect() - print("Connected to " + d.address) + print("Connected to " + d.address + " over " + ("USB" if d.usb.is_connected else "BLE")) states.append(State(d)) # configure diff --git a/examples/motion_record_log_no_reset.py b/examples/motion_record_log_no_reset.py index d12f3bf..af3ddfe 100644 --- a/examples/motion_record_log_no_reset.py +++ b/examples/motion_record_log_no_reset.py @@ -41,7 +41,7 @@ def wont_be_used(): for i in range(len(sys.argv) - 1): d = MetaWear(sys.argv[i + 1]) d.connect() - print("Connected to " + d.address) + print("Connected to " + d.address + " over " + ("USB" if d.usb.is_connected else "BLE")) states.append(State(d)) for s in states: diff --git a/examples/motion_record_stream.py b/examples/motion_record_stream.py index cd293a7..18c4f72 100644 --- a/examples/motion_record_stream.py +++ b/examples/motion_record_stream.py @@ -42,7 +42,7 @@ def passthrough_created(self, context, signal): for i in range(len(sys.argv) - 1): d = MetaWear(sys.argv[i + 1]) d.connect() - print("Connected to " + d.address) + print("Connected to " + d.address + " over " + ("USB" if d.usb.is_connected else "BLE")) states.append(State(d)) # configure diff --git a/examples/scan_connect.py b/examples/scan_connect.py index 570330c..5cf1b1d 100644 --- a/examples/scan_connect.py +++ b/examples/scan_connect.py @@ -37,7 +37,7 @@ def handler(result): device = MetaWear(address) device.connect() -print("Connected") +print("Connected to " + device.address + " over " + ("USB" if device.usb.is_connected else "BLE")) print("Device information: " + str(device.info)) sleep(5.0) diff --git a/examples/stream_acc.py b/examples/stream_acc.py index 748a09c..862686b 100644 --- a/examples/stream_acc.py +++ b/examples/stream_acc.py @@ -27,7 +27,7 @@ def data_handler(self, ctx, data): for i in range(len(sys.argv) - 1): d = MetaWear(sys.argv[i + 1]) d.connect() - print("Connected to " + d.address) + print("Connected to " + d.address + " over " + ("USB" if d.usb.is_connected else "BLE")) states.append(State(d)) # configure diff --git a/examples/stream_acc_gyro_bmi160.py b/examples/stream_acc_gyro_bmi160.py index b7d0ac0..486f484 100644 --- a/examples/stream_acc_gyro_bmi160.py +++ b/examples/stream_acc_gyro_bmi160.py @@ -35,7 +35,7 @@ def gyro_data_handler(self, ctx, data): for i in range(len(sys.argv) - 1): d = MetaWear(sys.argv[i + 1]) d.connect() - print("Connected to " + d.address) + print("Connected to " + d.address + " over " + ("USB" if d.usb.is_connected else "BLE")) states.append(State(d)) # configure all metawears diff --git a/examples/stream_acc_gyro_bmi270.py b/examples/stream_acc_gyro_bmi270.py index c8723a1..fcfaaf1 100644 --- a/examples/stream_acc_gyro_bmi270.py +++ b/examples/stream_acc_gyro_bmi270.py @@ -35,7 +35,7 @@ def gyro_data_handler(self, ctx, data): for i in range(len(sys.argv) - 1): d = MetaWear(sys.argv[i + 1]) d.connect() - print("Connected to " + d.address) + print("Connected to " + d.address + " over " + ("USB" if d.usb.is_connected else "BLE")) states.append(State(d)) # configure diff --git a/examples/stream_acc_packed.py b/examples/stream_acc_packed.py index 706c3f2..05cebfc 100644 --- a/examples/stream_acc_packed.py +++ b/examples/stream_acc_packed.py @@ -30,7 +30,7 @@ def acc_data_handler(self, ctx, data): for i in range(len(sys.argv) - 1): d = MetaWear(sys.argv[i + 1]) d.connect() - print("Connected to " + d.address) + print("Connected to " + d.address + " over " + ("USB" if d.usb.is_connected else "BLE")) states.append(State(d)) # configure diff --git a/examples/stream_acc_x.py b/examples/stream_acc_x.py index be1ff08..2720161 100644 --- a/examples/stream_acc_x.py +++ b/examples/stream_acc_x.py @@ -28,7 +28,7 @@ def data_handler(self, ctx, data): for i in range(len(sys.argv) - 1): d = MetaWear(sys.argv[i + 1]) d.connect() - print("Connected to " + d.address) + print("Connected to " + d.address + " over " + ("USB" if d.usb.is_connected else "BLE")) states.append(State(d)) # configure diff --git a/examples/stream_gyro_packed.py b/examples/stream_gyro_packed.py index 3d0f2b8..ac52eb9 100644 --- a/examples/stream_gyro_packed.py +++ b/examples/stream_gyro_packed.py @@ -31,7 +31,7 @@ def gyro_data_handler(self, ctx, data): for i in range(len(sys.argv) - 1): d = MetaWear(sys.argv[i + 1]) d.connect() - print("Connected to " + d.address) + print("Connected to " + d.address + " over " + ("USB" if d.usb.is_connected else "BLE")) states.append(State(d)) # configure diff --git a/examples/stream_quat.py b/examples/stream_quat.py index 0887a41..09536dd 100644 --- a/examples/stream_quat.py +++ b/examples/stream_quat.py @@ -27,7 +27,7 @@ def data_handler(self, ctx, data): for i in range(len(sys.argv) - 1): d = MetaWear(sys.argv[i + 1]) d.connect() - print("Connected to " + d.address) + print("Connected to " + d.address + " over " + ("USB" if d.usb.is_connected else "BLE")) states.append(State(d)) # configure diff --git a/examples/stream_temp.py b/examples/stream_temp.py index 859c7a0..a92ddc5 100644 --- a/examples/stream_temp.py +++ b/examples/stream_temp.py @@ -13,7 +13,7 @@ # connect to macc d.connect() -print("Connected to " + d.address) +print("Connected to " + d.address + " over " + ("USB" if d.usb.is_connected else "BLE")) e = Event() # create callback From 1b685d3ed99c8cd035494d4b8763760ed3d6e8d9 Mon Sep 17 00:00:00 2001 From: Matt Baker Date: Mon, 4 Apr 2022 16:58:28 -0700 Subject: [PATCH 4/4] release: step version. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index b7e300c..c859a1a 100644 --- a/setup.py +++ b/setup.py @@ -67,7 +67,7 @@ def run(self): setup( name='metawear', packages=['mbientlab', 'mbientlab.metawear'], - version='1.0.6', + version='1.0.7', description='Python bindings for the MetaWear C++ SDK by MbientLab', long_description=open(os.path.join(os.path.dirname(__file__), "README.rst")).read(), package_data={'mbientlab.metawear': so_pkg_data},