Timing Exception

I have a Droid app written in C#, Xamarin. Works well to connect to the MetaMotion device to gather readings including a custom sensor. I'm trying to track down an exception that is thrown. It takes a long time (8+ hours) for this exception to finally get triggered, so debugging is a bit tough.

Any thoughts on where this is coming from and what I should look at:

"Unhandled Exception:

System.TimeoutException: Did not receive a response for command [0x11, 0x92] within 250ms"

Thanks
Carlton

Comments

  • Also, after this exception is thrown, I have to restart my application to get the device to talk again.

  • edited May 2019

    How are you configuring your metamotion device?

    What are the steps to reproduce this issue?

  • Best I just share the function. This function runs every 10 minutes and works for a long time. I've set some additional debug message to help track down where the problem might be but wanted to ask in case this was something that is known.

    Thanks

    public async Task QueryBiometricBraceletV2()
    {
    // QUERY MetaWear Bracelet
    // 1) Connect to bracelet
    try
    {
    await BluetoothLeGatt2.DiscoverMetaWearAsync(scanTimeout: 20000, macAddress: MainActivity.Settings.BraceletID);
    }
    catch (Exception ex)
    {
    SettingsLog.WriteLog("EXC", string.Format(ex.Message));
    }

            SettingsLog.WriteLog("INF", "Found " + BluetoothLeGatt2.Devices.Count);
    
            if (BluetoothLeGatt2.Devices.Count > 0)
            {
                try
                {
                    metawear = new MetaWearBoard(new BluetoothLeGatt2(BluetoothLeGatt2.Device), new IO(MainActivity.Settings.BraceletID));
                    await metawear.InitializeAsync();
    
                    SettingsLog.WriteLog("INF", string.Format("Connect: {0} Name {1} Status {2} {3}\r\n", BluetoothLeGatt2.Device.Id, BluetoothLeGatt2.Device.Name, BluetoothLeGatt2.Device.State, metawear.IsConnected));
                }
                catch (Exception ex)
                {
                    SettingsLog.WriteLog("EXC", string.Format(ex.Message));
                    metawear = null;
                }
            }
    
            byte isCharging = 0;
            byte powerLevel = 0;
            float alcoholVoltage = 0.0F;
            float temperature = 0.0F;
            float frequencyMeasurement = 0.0F;
            float photoVoltage = 0.0F;
    
            // 2) Read settings from bracelet
            if (metawear != null && metawear.IsConnected)
            {
                // Get current power level
                powerLevel = await metawear.ReadBatteryLevelAsync();
    
                // Turn on LED to indicate that we are taking a reading
                var led = metawear.GetModule<ILed>();
                if (led != null)
                {
                    led.EditPattern(MbientLab.MetaWear.Peripheral.Led.Color.Green, duration: 1000, highTime: 500, high: 16, low: 16, count: 5);
                    led.Play();
                }
    
                // Turn on HDC (Haptic) to start heater, run for X seconds
                var haptic = metawear.GetModule<IHaptic>();
                haptic.StartBuzzer(10000);
    
                // Get charging status
                var settings = metawear.GetModule<ISettings>();
                isCharging = await settings.ChargeStatus.ReadAsync();
    
                // Get current temperature in celcius
                var temperatureModule = metawear.GetModule<ITemperature>();
                if (temperatureModule != null)
                {
                    var thermistor = temperatureModule.FindSensors(SensorType.NrfSoc)[0];
                    await temperatureModule.Sensors[0].AddRouteAsync(source => source.Stream(data =>
                        {
                            temperature = data.Value<float>() * 9/5 + 32;
                            SettingsLog.WriteLog("INF", "Temperature (F) = " + temperature);
                        })
                    );
                    thermistor.Read();
                }
    
                // Movement
                var accelerometerModule = metawear.GetModule<IAccelerometer>();
                if (accelerometerModule != null)
                {
                    accelerometerModule.Configure(odr: 100f, range: 16f);
                    await accelerometerModule.Acceleration.AddRouteAsync(source => source.Stream(data => 
                    {
                        SettingsLog.WriteLog("INF", "Acceleration = " + data.Value<Acceleration>());
    
                        // FOR TESTING store value in Bodymass and IR Sensor
                        // Frequency Measurement
                        // PhotoVoltage (Light Sensor)
                        frequencyMeasurement = Math.Abs(data.Value<Acceleration>().X * 1000);
                        photoVoltage = Math.Abs(data.Value<Acceleration>().Y *1000);
                    }));
    
                    accelerometerModule.Acceleration.Start();
                    accelerometerModule.Start();
                }
    
                // Wait for heater
                await Task.Delay(3000);
    
                // Turn on ADC1 to start voltage flow to read sensor
                var gpio = metawear.GetModule<IGpio>();
                if (gpio != null)
                {
                    gpio.Pins[1].ClearOutput();
                }
    
                // Get ADC (Voltage reading from sensor)
                if (gpio != null)
                {
                    var adc = gpio.Pins[0].Adc;
                    await adc.AddRouteAsync(source => source.Stream(data =>
                    {
                        alcoholVoltage = data.Value<ushort>();
                        SettingsLog.WriteLog("INF", "adc = " + data.Value<ushort>());
                    })
                    );
                    adc.Read();
                }
    
                await Task.Delay(2000);
    
                // Stop getting readings
                if (accelerometerModule != null)
                {
                    accelerometerModule.Stop();
                    accelerometerModule.Acceleration.Stop();
                }
    
                // Turn off power to heater, but wait time before so a good reading comes in.
                if (gpio != null)
                {
                    gpio.Pins[1].SetOutput();
                }
    
                var strMessage = "Create message to send to server";
                MainActivity.Settings.BiometricPowerPercent = powerLevel;
                MainActivity.Settings.BiometricRead = true;
                biometricMessage = strMessage;
            }
    
            // 3) Disconnect from Metawear Board
            if (metawear != null && metawear.IsConnected)
            {
                await metawear.DisconnectAsync();
    
                //https://mbientlab.com/community/discussion/comment/7752#Comment_7752
                metawear.TearDown();
                metawear = null;
            }
        }
    
  • Which line exactly fails? And why are you not retrying the command?

  • I've isolated it to this:

                // Get charging status
                var settings = metawear.GetModule<ISettings>();
                isCharging = await settings.ChargeStatus.ReadAsync();
    

    After a long period of time, the above function no longer works. Actually, I'm not sure it works at all. It always returns false even when I have a battery connected and it should be charging.

    Thoughts?

  • edited May 2019
    • Does it work eventually if you retry the function call?
    • Does the command even get sent while in this state? Maybe there is a bug with your ble library
    • Attaching a battery doesn't mean it is charging. Double check with a script that just checks charging status
  • My function is now:

                try
                {
                    // Get charging status
                    var settings = metawear.GetModule<ISettings>();
                    isCharging = await settings.ChargeStatus.ReadAsync();
                }
                catch
                {
                    isCharging = 0;
                }
    

    Because I wasn't catching the exception, any code after the above didn't execute. Now that I am capturing the exception, function seems to be working ok.

    After period of time, the ChargeStatus.ReadAsync() begins to work again. What's odd is that the functions after this function do work, so I'm not loosing a connection w/ the metawear board.

    I'll keep this in our development log and if something else pops up, will re-open this discussion.

Sign In or Register to comment.