Some Problems with MMS download and with 'packed mode'

edited January 26 in Python

I am using MMS with Python codes, but I have many problems:

  • the sensors have bluetooth connection problems. In fact, some sensors are able to stream data up to about 1 m from the dongle, while others lose the connection already if they are moved away a few cm. Can you tell me if it is a problem of the specific sensors or if I can do something to improve the connection ?

  • When I use the sensors in streaming mode I would like to send the data in packets and I saw that there is a function (packed) to send multiple samples in one bluetooth packet. However, if I use the code that is among the examples (the one of the gyroscopes) it gives me as error "segmentation fault". Can you tell me how I can solve ? also I would like to know if the packed mode is usable also in logging mode (I tried but I failed).

  • When I use the sensors in logging mode I usually do quite long tests (more than 1h). Downloading the data, the time is almost double the time of the test (I sample accelerometers and gyroscopes at 100 Hz). I would like to know if there is a way to download them faster.
    To do this I tried to connect the sensor via usb (I saw that there is the new function for MMS with python scripts). However every time I connect the sensor it takes more than a minute to connect and when disconnected it is no longer detected by bluetooth (I was able to connect only after doing 2 resets manually and this method does not always work). Also, even with USB the data download time is similar to bluetooth. can you tell me if I'm doing something wrong ?

Comments

  • Anyone who can help me?
    Do you need more information?

    1. You can use our tx power setting to improve the bluetooth. Also removing the pcb from the case helps as well.
    2. Can't comment without seeing the code and knowing if its used correctly.
    3. You are not doing anything wrong, unfortunately USB and Bluetooth just both take time since our sensor doesn't work like a flash drive.
  • edited April 6

    from mbientlab.metawear import MetaWear, libmetawear, parse_value, create_voidp, create_voidp_int
    from mbientlab.warble import *
    from mbientlab.metawear.cbindings import *
    from ctypes import c_void_p, cast, POINTER
    from time import sleep
    from threading import Event
    import six
    import platform
    import sys
    from sys import argv
    import csv
    import numpy as np
    import matplotlib.pyplot as plt
    from datetime import datetime;

    def retry_connection(d):
    print("----------------------------------Trying CONNECTION---------------------------------------------------")
    sleep(3.0)
    try:
    d.connect()
    except:
    return retry_connection(d)

    if sys.version_info[0] == 2:
    range = xrange

    class State:
    def init(self, device):
    self.device = device
    self.samples = 0
    self.analog_samples=0
    self.e=Event()
    self.timer=None
    self.callback = FnVoid_VoidP_DataP(self.data_handler)
    self.analog_callback = FnVoid_VoidP_DataP(self.analog_data_handler)
    self.an_signal = signal = libmetawear.mbl_mw_multi_chnl_temp_get_temperature_data_signal(self.device.board, MetaWearRProChannel.ON_BOARD_THERMISTOR)
    self.processor = None
    # Acc Gyr Callback
    def data_handler(self, ctx, data):
    values = parse_value(data, n_elem = 2)
    with open('./Data/dataacc_'+self.device.address+'.csv', 'a+', newline='') as file:
    writer = csv.writer(file, delimiter=';')
    writer.writerow([ datetime.timestamp(datetime.now()), values])
    # with open('./Data/datagyr_'+self.device.address+'.csv', 'a+', newline='') as file:
    # writer = csv.writer(file, delimiter=';')
    # writer.writerow([ datetime.timestamp(datetime.now()), values[1].x, values[1].y, values[1].z])
    libmetawear.mbl_mw_datasignal_read(self.an_signal)
    self.samples+= 1

    # Asnalog1 Callback
    def analog_data_handler(self, ctx, data):
    with open('./Data/analog_'+self.device.address+'.csv', 'a+', newline='') as file:
    writer = csv.writer(file, delimiter=';')
    writer.writerow([datetime.timestamp(datetime.now()), values])

    def setup(self):
        # ble settings
        libmetawear.mbl_mw_settings_set_connection_parameters(self.device.board, 7.5, 7.5, 0, 6000)
        sleep(0.5)
        # events
        e = Event()
        # processor callback fxn
        def processor_created(context, pointer):
            self.processor = pointer
            e.set()
        # processor fxn ptr
        fn_wrapper = FnVoid_VoidP_VoidP(processor_created)
        # setup acc
        libmetawear.mbl_mw_acc_bmi270_set_odr(self.device.board, AccBmi270Odr._100Hz)
        libmetawear.mbl_mw_acc_bosch_set_range(self.device.board, AccBoschRange._2G)
        libmetawear.mbl_mw_acc_write_acceleration_config(self.device.board)
        # get acc signal
        acc = libmetawear.mbl_mw_acc_get_packed_acceleration_data_signal(self.device.board)
        # setup gyr
        libmetawear.mbl_mw_gyro_bmi270_set_range(s.device.board, GyroBoschRange._125dps);
        libmetawear.mbl_mw_gyro_bmi270_set_odr(s.device.board, GyroBoschOdr._100Hz);
        libmetawear.mbl_mw_gyro_bmi270_write_config(s.device.board);
        # get gyro signal - MMRl, MMR, MMc ONLY
        gyro = libmetawear.mbl_mw_gyro_bmi270_get_packed_rotation_data_signal(self.device.board)
        # get gyro signal - MMRS ONLY
        #gyro = libmetawear.mbl_mw_gyro_bmi270_get_rotation_data_signal(self.device.board)
        # create signals variable
        signals = (c_void_p * 1)()
        signals[0] = gyro
        libmetawear.mbl_mw_dataprocessor_fuser_create(acc, signals, 1, None, fn_wrapper)
        # wait for fuser to be created
        e.wait()
        # subscribe to the fused signal
        libmetawear.mbl_mw_datasignal_subscribe(self.processor, None, self.callback)
        libmetawear.mbl_mw_datasignal_subscribe(self.an_signal, None, self.analog_callback)
        self.timer = create_voidp(lambda fn: libmetawear.mbl_mw_timer_create_indefinite(self.device.board, 50, 0, None, fn), resource = "timer", event = self.e)
        # create event based on timer - read temp when timer fires
        libmetawear.mbl_mw_event_record_commands(self.timer)
        libmetawear.mbl_mw_datasignal_read(self.an_signal)
        create_voidp_int(lambda fn: libmetawear.mbl_mw_event_end_record(self.timer, None, fn), event = self.e)
    
    
    def start(self):
        libmetawear.mbl_mw_timer_start(self.timer)
        # start gyro sampling - MMRL, MMC, MMR only
        #libmetawear.mbl_mw_gyro_bmi160_enable_rotation_sampling(self.device.board)
        # start gyro sampling - MMS ONLY
        libmetawear.mbl_mw_gyro_bmi270_enable_rotation_sampling(self.device.board)
        # start acc sampling
        libmetawear.mbl_mw_acc_enable_acceleration_sampling(self.device.board)
        # start gyro - MMRL, MMC, MMR only
        libmetawear.mbl_mw_gyro_bmi270_start(self.device.board)
        # start gyro sampling - MMS ONLY
        #libmetawear.mbl_mw_gyro_bmi270_start(self.device.board)
        # start acc
        libmetawear.mbl_mw_acc_start(self.device.board)
    
    
    
    def stop(self):
        libmetawear.mbl_mw_gyro_bmi270_stop(self.device.board)
        libmetawear.mbl_mw_acc_stop(self.device.board)
        libmetawear.mbl_mw_gyro_bmi270_disable_rotation_sampling(self.device.board)
        libmetawear.mbl_mw_acc_disable_acceleration_sampling(self.device.board)
        libmetawear.mbl_mw_timer_remove(self.timer)
        libmetawear.mbl_mw_event_remove_all(self.device.board)
        libmetawear.mbl_mw_datasignal_unsubscribe(self.an_signal)
    

    # ricerca dispositivi nelle vicinanze
    devices = None
    array = sys.argv
    del array[0]
    print(array)
    states = []
    # connect

    for a in array:
    device = MetaWear(a)
    device.connect()
    print("Connecting to " + device.address)
    print("CONNECTION STATE " + str(device.is_connected))
    states.append(State(device))

    # configure
    for s in states:
    # print("Configuring %s" % (s.device.address))
    s.setup()

    # start
    for s in states:
    s.start()

    print("Streaming data")
    stop = -1
    while stop == -1:
    msg = "Press s to stop data recording: "
    selection = raw_input(msg) if platform.python_version_tuple()[0] == '2' else input(msg)
    if selection == "s":
    stop = 0
    print("-----STOP STREAMING-----")

    for s in states:
    if s.device.is_connected:
    print("connected to " + device.address)
    s.stop()
    else:
    while(not s.device.is_connected):
    retry_connection(s.device)
    s.stop()

    # reset
    print("Resetting devices")
    events = []
    for s in states:
    e = Event()
    events.append(e)
    s.device.on_disconnect = lambda s: e.set()
    libmetawear.mbl_mw_debug_reset(s.device.board)

    for e in events:
    e.wait()

    # recap
    print("Total Samples Received")
    for s in states:
    print("%s -> %d" % (s.device.address, s.samples))

  • this is my code. Unfortunately i can't dowload and stream data in packed mode to have a faster download.

  • @giovanni_dq

    Make sure that you install the latest version of MetaWear Python on PyPi to be sure your devices are connecting over USB. The example scripts have also been updated to indicate what type of connection has been established and you may want to add something similar to your script. Here is an example: https://github.com/mbientlab/MetaWear-SDK-Python/blob/master/examples/log_acc.py#L13

    The packed mode is meant only for streaming, and will have a detrimental effect if logged. For an application that needs to switch between modes, you can log the unpacked version and stream the packed version. It is still advisable not to stream while downloading, as it may result in packet loss, but if this is a hard requirement you can try to test it in your setup. If the total throughput is not too high, it may work okay for you, especially if operating with USB downloads.

Sign In or Register to comment.