Forum Cross Platform with Xamarin

Question Regarding Plugin.BLE Characteristic.WriteAsync

Hello,
I have a Xamarin Forms App that connects to a custom made Bluetooth LE device. I have configured my Xamarin forms App to WriteAsync to a characteristic. It works swimmingly in Android. I have a button event handler that calls a task and the Write occurs in Milliseconds. However, in iOS it does not work the same. I have debug statements that show it is called and returns true but the firmware in the BLE device never sees the call.

One thing I do notice is that if I call the function when I very first start the App it works. After the first call the state of the app changes and I wonder if it has something to do with not being called from the main thread. I did try to get it to call from the main thread but that didn't work either.

I have several Characteristics that I can ReadAsync with no problems, this is the first time I have tried to write one. Here is the code for the write.
WriteOk always returns true regardless what the BLE device hears.
public async Task ResetInhaleTimer()
{

            if (digitalData.CanWrite)
           {
        var WriteOk = await digitalData.WriteAsync(mybyte, new CancellationToken(true)).ConfigureAwait(false);
            if(!WriteOk)
            {
                Debug.WriteLine(" Writing to the Digital Char and AhHa C# Thinks it did NOT write");
           }
           else
            {
                Debug.WriteLine("Writing to the digital char and AhHa C# Thinks it did write");
            }
            }return false;


    }
Tagged:

Answers

  • judsonabrahamjudsonabraham USMember ✭✭✭
    edited November 2020

    Did you solve it? Even I'm stuck with this. Please help.

  • dlchambersdlchambers Member ✭✭

    Here's what worked for me on Android. Haven't tried it on iOS yet.

    First, create an async method (must be async to satisfy WriteAsync() )

        private async Task<bool> _write(Plugin.BLE.Android.Characteristic aChx, byte[] data)
        {
            bool success = false; // Default to fail unless explicit success
            int timeout = 2000; // Very generous! Should complete in milliseconds
            var writetask = aChx.WriteAsync(data);
            if (await Task.WhenAny(writetask, Task.Delay(timeout)) == writetask)
            {
                // task completed within timeout... how'd we do?
                if (TaskStatus.RanToCompletion == writetask.Status)
                {
                    success = writetask.Result; // This is the result you're after!
                }
                else
                {
                    // This is a failure not associated with the timeout
                    // Basically, anything other than RanToCompletion is a failure.
                    // E.g. TaskStatus.Faulted means that WriteAsync overtly failed
                }
            }
            else
            {
                // WriteAsync() took too long
            }
            return success;
        }
    

    Then call it from your non-async code:

    Plugin.BLE.Android.Characteristic chx = (previously retrieved Characteristic)
    byte[] data = new byte[] {0x01, 0x02}; // whatever your data is
    bool rslt = _write(chx, data).Result;
    
Sign In or Register to comment.