Issue reconnecting to data stream on device...

edited July 2019 in C#

Okay, we've hammered past most issues.

We've built a network server to server data to the Unity app. Works great, but we have an issues with the stream not working a second time.

    async public void StartRotationalAccelerometer(Action<string, EulerAngles> _return)
    {
        Console.WriteLine("StartRotationalAccelerometer");
        if (device == null)
            return;

        Console.WriteLine("Set StartRotationalAccelerometer");
        if (rotationalAccelerometer == null)
            rotationalAccelerometer = device.GetModule<ISensorFusionBosch>();

        _EulerAnglesReturn = _return;

        Console.WriteLine("Start StartRotationalAccelerometer");
        rotationalAccelerometer.Configure();
        rotationalAccelerometer.EulerAngles.Start();
        rotationalAccelerometer.Start();

        Console.WriteLine("Stream StartRotationalAccelerometer");

        //await rotationalAccelerometer.EulerAngles.AddRouteAsync(null);

        await rotationalAccelerometer.EulerAngles.AddRouteAsync(ReturnStream2);
    }

Then it goes to:

                    public void ReturnStream2(MbientLab.MetaWear.Builder.IRouteComponent _data)
                    {
                        Console.WriteLine("Stream2 StartRotationalAccelerometer");
                        _data.Stream(ReturnStream3);
                    }

                    public void ReturnStream3(IData _data)
                    {
                        Console.WriteLine("Stream3 StartRotationalAccelerometer");
                        EulerAngles sample = _data.Value<EulerAngles>();
                        if (_EulerAnglesReturn != null)
                            _EulerAnglesReturn.Invoke(deviceMac, sample);
                    }

When I close the device:

    async public void StopRotationalAccelerometer()
    {
        if (device == null)
            return;

        if (rotationalAccelerometer == null)
            rotationalAccelerometer = device.GetModule<ISensorFusionBosch>();

        _EulerAnglesReturn = null;

        // break linkup...
        await rotationalAccelerometer.EulerAngles.AddRouteAsync(source => source.Stream(null));

        // Put accelerometer back into standby mode
        rotationalAccelerometer.Stop();

        // Stop accelerationi data
        rotationalAccelerometer.EulerAngles.Stop();

        // break linkup...
        await rotationalAccelerometer.EulerAngles.AddRouteAsync(source => source.Stream(null));
    }

Sadly, the code works fine the first time, but after that, it never gets a stream again.

Anything I'm missing?

Comments

    • Why are you continually adding routes instead of removing them?

    • What behaves differently in your code between the first run and subsequent runs?

    • Same as in the other thread, isolate your code into a self contained static function that reproduces the behavior.

  • Simple. I never found a way to remove routes. Even the samples I found have addition of null routes. I can't even find a usable method for route removal.

    Can I ask why you want it static, as opposed as in a storage class? Generally, I have the whole kit as follows:

    namespace mbientlab_BridgeServer
    {
    public class MbientLabDevice
    {
    public IMetaWearBoard device;
    public ILed led;
    public ISensorFusionBosch rotationalAccelerometer;

        public string userName;
        public string deviceName;
        public string deviceMac;
    
        public bool connecting = false;
    
        public List<Acceleration> lateral_samples = new List<Acceleration>();
        public List<EulerAngles> rotational_samples = new List<EulerAngles>();
    
        public void Setup(string _name, string _mac)
        {
            userName = _name;
            deviceName = _name;
            deviceMac = _mac;
    
        }
    
        async public Task<bool> Connect()
        {
            if (string.IsNullOrEmpty(deviceMac))
            {
                return false;
            }
    
            try
            {
                connecting = true;
                if (device == null)
                {
                    device = MbientLab.MetaWear.NetStandard.Application.GetMetaWearBoard(deviceMac);
                    device.TimeForResponse = 10000;
                }
    
                if (device.IsConnected)
                {
                    led = device.GetModule<ILed>();
    
                    if (rotationalAccelerometer == null)
                        rotationalAccelerometer = device.GetModule<ISensorFusionBosch>();
    
                    connecting = false;
                    return true;
                }
    
                await device.InitializeAsync();
    
                led = device.GetModule<ILed>();
                if (rotationalAccelerometer == null)
                    rotationalAccelerometer = device.GetModule<ISensorFusionBosch>();
    
                connecting = false;
                return true;
            }
            catch (Exception e)
            {
                connecting = false;
                return false;
            }
        }
    
        async public Task<bool> Disconnect()
        {
            if (device == null)
            {
                return true;
            }
    
    
            try
            {
                if (led != null)
                {
                    led.Stop(true);
                    led = null;
                }
    
    
                if (rotationalAccelerometer != null)
                {
                    StopRotationalAccelerometer();
                }
    
                if (device != null && !device.InMetaBootMode)
                {
                    device.TearDown();
    
                    int timeout = 5000;
                    var task = device.GetModule<IDebug>().DisconnectAsync();
                    if (await Task.WhenAny(task, Task.Delay(timeout)) == task)
                    {
                        connecting = false;
                        return true;
                    }
                    else
                    {
                        connecting = false;
                        return false;
                    }
                }
            }
            catch (Exception e)
            {
                connecting = false;
                return false;
            }
    
            return false;
        }
    
        public void BlinkLed(MbientLab.MetaWear.Peripheral.Led.Color _color = MbientLab.MetaWear.Peripheral.Led.Color.Red)
        {
            if (device == null)
                return;
    
            if (led == null)
                led = device.GetModule<ILed>();
    
            led.Stop(true);
            led.EditPattern(_color, Pattern.Pulse, 0);
            led.Play();
        }
    
        public void ClearLed()
        {
            if (device == null)
                return;
    
            if (led == null)
                led = device.GetModule<ILed>();
    
            led.Stop(true);
        }
    
        Action<string, EulerAngles> _EulerAnglesReturn;
        Action<string, Acceleration> _LinearAccelerationReturn;
    
        async public void StartSensors(Action<string, EulerAngles> _eReturn, Action<string, Acceleration> _aReturn)
        {
            if (device == null)
                return;
    
            if (rotationalAccelerometer == null)
                rotationalAccelerometer = device.GetModule<ISensorFusionBosch>();
    
            _EulerAnglesReturn = _eReturn;
            _LinearAccelerationReturn = _aReturn;
    
            rotationalAccelerometer.Configure();
            rotationalAccelerometer.EulerAngles.Start();
            rotationalAccelerometer.LinearAcceleration.Start();
            rotationalAccelerometer.Start();
    
            await rotationalAccelerometer.EulerAngles.AddRouteAsync(ReturnStreamEulerAngles);
            await rotationalAccelerometer.LinearAcceleration.AddRouteAsync(ReturnStreamLinearAcceleration);
    
        }
    
        public void ReturnStreamEulerAngles(MbientLab.MetaWear.Builder.IRouteComponent _data)
        {
            _data.Stream(ReturnStreamEulerAnglesFinal);
        }
    
        public void ReturnStreamEulerAnglesFinal(IData _data)
        {
            EulerAngles eSample = _data.Value<EulerAngles>();
            if (_EulerAnglesReturn != null)
                _EulerAnglesReturn.Invoke(deviceMac, eSample);
        }
    
        public void ReturnStreamLinearAcceleration(MbientLab.MetaWear.Builder.IRouteComponent _data)
        {
            _data.Stream(ReturnStreamLinearAccelerationFinal);
        }
    
        public void ReturnStreamLinearAccelerationFinal(IData _data)
        {
            Acceleration aSample = _data.Value<Acceleration>();
            if (_LinearAccelerationReturn != null)
                _LinearAccelerationReturn.Invoke(deviceMac, aSample);
        }
    
        async public void StopRotationalAccelerometer()
        {
            if (device == null)
                return;
    
            if (rotationalAccelerometer == null)
                rotationalAccelerometer = device.GetModule<ISensorFusionBosch>();
    
            _EulerAnglesReturn = null;
    
            // break linkup...
            await rotationalAccelerometer.EulerAngles.AddRouteAsync(source => source.Stream(null));
            await rotationalAccelerometer.LinearAcceleration.AddRouteAsync(source => source.Stream(null));
    
            // Put accelerometer back into standby mode
            rotationalAccelerometer.Stop();
    
            // Stop accelerationi data
            rotationalAccelerometer.EulerAngles.Stop();
            rotationalAccelerometer.LinearAcceleration.Stop();
    
            // break linkup...
            await rotationalAccelerometer.EulerAngles.AddRouteAsync(source => source.Stream(null));
            await rotationalAccelerometer.LinearAcceleration.AddRouteAsync(source => source.Stream(null));
        }
    }
    

    }

    Generally, the whole kit is stored in a variable for each device, so they can work independently.

    I will see if I can narrow the effect, as well.

  • @FoolishFrost said:
    Simple. I never found a way to remove routes. Even the samples I found have addition of null routes.

    addRoute does not remove routes, the documentation clearly states what it does.
    https://github.com/mbientlab/MetaWear-SDK-CSharp/blob/1.2.0/MetaWear/IDataProducer.cs#L12

    I can't even find a usable method for route removal.

    https://mbientlab.com/csdocs/1/metawearboard.html#tear-down
    https://github.com/mbientlab/MetaWear-SDK-CSharp/blob/1.2.0/MetaWear/IRoute.cs

    Can I ask why you want it static, as opposed as in a storage class? Generally, I have the whole kit as follows:

    For now, I don't care about your non-MetaWear code. I just want a simple, self contained function that only uses MetaWear code to reproduce this issue.

    Also, please answer my 2nd question from my previous post

    What behaves differently in your code between the first run and subsequent runs?

Sign In or Register to comment.