Saving Calibration data in NVM using Macros

Hi,
I have problems successfully storing calibration data into the NVM. To make it as easy as possible I added this this function to the calibration.py example as follows:

# usage: python calibrate.py [mac]
from mbientlab.metawear import MetaWear, libmetawear, parse_value, create_voidp_int
from mbientlab.metawear.cbindings import *
from time import sleep
from threading import Event
import sys

device = MetaWear(sys.argv[1])
device.connect()
print("Connected")

e = Event()


def calibration_data_handler(ctx, board, pointer):
    print("calibration data: %s" % (pointer.contents))
    # libmetawear.mbl_mw_sensor_fusion_write_calibration_data(board, pointer)
    # libmetawear.mbl_mw_memory_free(pointer)

    print("Write to NVM")
    libmetawear.mbl_mw_macro_record(board, 1)
    print("macro record")
    libmetawear.mbl_mw_sensor_fusion_write_calibration_data(board, pointer)
    print("calibr data")
    create_voidp_int(lambda fn: libmetawear.mbl_mw_macro_end_record(board, None, fn))
    print("done recording macro")
    e.set()


fn_wrapper_01 = FnVoid_VoidP_VoidP_CalibrationDataP(calibration_data_handler)

signal = libmetawear.mbl_mw_sensor_fusion_calibration_state_data_signal(device.board)


def calibration_handler(ctx, pointer):
    value = parse_value(pointer)
    print("state: %s" % (value))

    if (value.accelrometer == Const.SENSOR_FUSION_CALIBRATION_ACCURACY_HIGH and
            value.gyroscope == Const.SENSOR_FUSION_CALIBRATION_ACCURACY_HIGH and
            value.magnetometer == Const.SENSOR_FUSION_CALIBRATION_ACCURACY_HIGH):

        libmetawear.mbl_mw_sensor_fusion_read_calibration_data(device.board, None, fn_wrapper_01)
    else:
        sleep(1.0)
        libmetawear.mbl_mw_datasignal_read(signal)


fn_wrapper_02 = FnVoid_VoidP_DataP(calibration_handler)

libmetawear.mbl_mw_sensor_fusion_set_mode(device.board, SensorFusionMode.NDOF)
libmetawear.mbl_mw_sensor_fusion_write_config(device.board)

libmetawear.mbl_mw_datasignal_subscribe(signal, None, fn_wrapper_02)
libmetawear.mbl_mw_sensor_fusion_start(device.board)
libmetawear.mbl_mw_datasignal_read(signal)
e.wait()

print("Disconnecting")
e.clear()
device.on_disconnect = lambda s: e.set()
libmetawear.mbl_mw_sensor_fusion_stop(device.board)
libmetawear.mbl_mw_debug_disconnect(device.board)

e.wait()

however it always gets stuck at the command:
create_voidp_int(lambda fn: libmetawear.mbl_mw_macro_end_record(board, None, fn))

Is there anything I miss?

Thanks,
alex

Comments

  • Doesn't look like you started the macro to begin with.

  • Isn't that done in this line?

    libmetawear.mbl_mw_macro_record(board, 1)

  • My bad, the issue is that you don't properly handle the macro_end callback.

  • Thank you. It works now.

  • Hey @atonino, can you confirm your fix?

  • Dear Laura,

    I am trying to use coinespy to calibrate the BMI160 raw data (not in any fusion model). But it seems sensors can't be connected using this lib.

    The example code provided by BOSCH is like this. My MMR is connected to PC using USB. It should work properly. However the output is "Could not connect to board: -1". Do I wrongly use this lib or actually I can't use this lib to calibrate the sensor?

    `
    import coinespy as BST

    if name == "main":

    board = BST.UserApplicationBoard()
    # If you get an error message on startup, that coineslib could not be loaded, then
    # intialize the UserApplicationBoard object with the path to the library, e.g.
    #(WIN)board = BST.UserApplicationBoard(r'libcoines.dll')
    #(LINUX)board = BST.UserApplicationBoard(r'libcoines.so')
    
    print('COINES library - %s' %(board.coines_lib_version))
    print('coinespy version - %s' %(BST.__version__))
    
    board.PCInterfaceConfig(BST.PCINTERFACE.USB)
    if board.ERRORCODE != 0:
        print('Could not connect to board: %d' % (board.ERRORCODE))
    else:
        b_info = board.GetBoardInfo()
        print('BoardInfo: HW/SW ID: ' + hex(b_info.HardwareId) + '/' + hex(b_info.SoftwareId))
        board.ClosePCInterface()
    

    `

    Thanks in advance,
    Xiaorui

  • HI @Xiaorui,
    Unfortunately we don't support USB connections for the MMR.

  • @Laura said:
    HI @Xiaorui,
    Unfortunately we don't support USB connections for the MMR.

    hello Laura,

    Thanks for your fast reply.

    Since we need to receive data at 50hz the fusing model (fixed 100hz) is not suitable for us.

    So is there a way to calibrate raw data (without using the fusing model)?

    All the best,
    Xiaorui

  • Unfortunately we don't allow that currently. We may enable this feature in the MMS in the future.
    Can you use our data processor to lower the sensor fusion data rate?

  • Hello Laura,

    I am using your calibrate.py to calibrate sensors then using stream_quat.py to get calibrated data. However, I always get this problem Failed to write value to characteristic(Error trying to issue command mid state)

    The strange thing is when I reset sensors and run stream_quat.py directly (without calibration first) I can get the quarantine properly.

    Is there something wrong with calibrate.py ?

    All the best,

  • I don't think the calibrate.py example works for the MMRL or MMS. It was made for the MMR so I might need to check if it needs updates for our new sensors.

  • @Laura said:
    I don't think the calibrate.py example works for the MMRL or MMS. It was made for the MMR so I might need to check if it needs updates for our new sensors.

    Hey Laura,

    we are using MMR to do the calibration. our goal is to synchronize multiple sensors.

    We have a question about calibration performance. you can see the pictures below (two sensors), it seems that calibrate.py doesn't work well. the offset is still there. Is this offset normal after calibration or we can make the curve overlap better?

    All the best,
    Xiaorui

  • @Laura said:
    Hey @atonino, can you confirm your fix?

    yeah sure. sorry:

    create_voidp_int(lambda fn: libmetawear.mbl_mw_macro_end_record(board, None, fn))
    needs to be changed to
    macro_end_callback = FnVoid_VoidP_VoidP_Int(lambda ctx, board, status: macro_end_event.set()) libmetawear.mbl_mw_macro_end_record(board, None, macro_end_callback)

  • I'm confused on calibration with MMRL. I have tried the calibration.py from examples, and also the modified code per atonino in this thread. They both run without errors, but what is the difference between the two methods (mbl_mw_sensor_fusion_write_calibration_data and the mbl_mw_macro_end_record methods)? Do they both persist after disconnect or restart?

  • @bobaloo

    mbl_mw_sensor_fusion_write_calibration_data will write the calibration data into volatile memory, which will work until the device is reset or loses power. So it will persist a disconnect, but not a reset (restart) of the device.

    The mbl_mw_macro_end_record method will build a macro in non volatile that reloads the calibration data on reset/reboot/powerloss.

  • Thanks Matt, that makes perfect sense.

Sign In or Register to comment.