Xamarin Forms - DiscoverModules timeout issue

edited January 2018 in General
Hello

I'm implementing an application with Xamarin.Forms using the MetaWear C# SDK.

After connecting to the MetaWear device through a bluetooth adapter and creating the MetaWearBoard object, I  tried to Initialize the board using  - IMetaWearBoard.InitializeAsync method, at some point this calls the DiscoverModulesAsync which throws a timeout exception when it tries to write into a characteristic.

I tried to increase the time but the same issue happened. Also the module that gives me the exception is different every time.

Here is the code from the MetaWear C# SDK

DiscoverModules:
image

Execute:
image

sendCommand:

image

Did you have any issues like this, or a working solution for Xamarin.Forms?

Thanks

Comments

  • Your images are not visible.  Please post the actual text/code, not a screen shot.

    The C# SDK has not be tested by MbientLab with Xamarin Forms though another community member has worked on plugging in the necessary files.  The issue you are having might be related to one discussed in this thread:

  • Sorry, here is the missing code

    DiscoverModules:

    private async Task<OrderedDictionary> DiscoverModulesAsync(ICollection<Module> ignore) {
                var output = new OrderedDictionary();
                readInfoRegisterTask = new TimedTask<ModuleInfo>();

                try {                
                    foreach (Module module in Enum.GetValues(typeof(Module))) {
                        if (!ignore.Contains(module)) {
                            var info = await readInfoRegisterTask.Execute("Did not receive module info (" + module.ToString() + ") within {0}ms", bridge.TimeForResponse,
                                () => bridge.sendCommand(new byte[] { (byte)module, READ_INFO_REGISTER }));
                            output.Add(module, info);
                        }
                    }
                } 
        catch (TimeoutException e) {
                    throw new TaskTimeoutException(e, output);
                }

                return output;
            }


  • Execute:

    internal async Task<T> Execute(string format, int timeout, Action action) {
                taskSource = new TaskCompletionSource<T>();
                cts = new CancellationTokenSource();

                action();
                if (timeout != 0) {
                    var delay = Task.Delay(timeout, cts.Token);
                    if (await Task.WhenAny(taskSource.Task, delay) != taskSource.Task) {
                        if (!delay.IsCanceled) {
                            taskSource.SetException(new TimeoutException(string.Format(format, timeout)));
                        }
                    } else {
                        cts.Cancel();
                    }
                }
                return await taskSource.Task;
            }

  • edited January 2018
    sendCommand:

    public async Task sendCommand(byte[] command) {
                    if (GetModule<Event>() is Event eventModule && eventModule.ActiveDataType != null) {
                        eventModule.convertToEventCommand(command);
                    } else {
                        try {
                            if (GetModule<IMacro>() is Macro macro && macro.isRecording) {
                                macro.commands.Enqueue(command);
                            }
                            await metawear.gatt.WriteCharacteristicAsync(
                                COMMAND_GATT_CHAR,
                                command[0] == (byte)MACRO ? GattCharWriteType.WRITE_WITH_RESPONSE : GattCharWriteType.WRITE_WITHOUT_RESPONSE,
                                command
                            );
                            
                        } catch (Exception e) {
                            metawear.io.LogWarn("metawear", "Failed to send command: " + Util.arrayToHexString(command), e);
                        }
                    }
                }

    Also here is the code that writes into the characteristic:

    public async Task WriteCharacteristicAsync(Tuple<Guid, Guid> gattChar, GattCharWriteType writeType, byte[] value)
            {
                await Task.Factory.StartNew(() =>
                {
                    ICharacteristic characteristic = characteristics.FirstOrDefault(x => x.Id == gattChar.Item2);
                    if (characteristic != null)
                    {
                        try
                        {
                            characteristic.Write(value);
                        }
                        catch(Exception ex)
                        {
                            Debug.WriteLine(ex.Message);
                        }
                    }
                    else
                    {
                        throw new InvalidOperationException(string.Format("GATT characteristic '{0}' does not exist", gattChar.Item2));
                    }
                });
            }
  • edited January 2018
    Log which values are successfully written and what notifications are received from the board before the timeout exception is thrown.  Please capture several attempts as well.

    Again, your issue may be the same as the one discussed in this thread:


This discussion has been closed.