I'm communicating with a custom external device, and this device requires when I send data, I must send the same data once again, between 10 and 100 milliseconds (send the data twice 10-100 ms interval).
Basically it's working very well to send the data, but the second sending is between 500 - 800 milliseconds, so I must decrease it.
I using Plugin.BLE
...
public async Task WriteCharacteristics(byte value)
{
try
{
byte[] data = {value};
await Service.GetCharacteristicsAsync().ContinueWith(async task =>
{
Characteristics = task.Result;
await Characteristics.First().WriteAsync(data).ContinueWith(async t1 =>
{
await Characteristics.First().StartUpdatesAsync();
});
});
}
catch (Exception e)
{
Debug.WriteLine("********* Failed to get ReadCharacteristics: " e.Message);
}
}
...
and when I call:
...
_ = ble.WriteCharacteristics((byte)value).ContinueWith(_ =>
{
Thread.Sleep(10);
ble.WriteCharacteristics((byte)value).Wait();
});
...
I tried to call the function twice, as parallel, but that solution not good.
As you see when I call, it waits 10 milliseconds, and want to send the data again. Is there any workaround to solve this problem?
CodePudding user response:
One reason for the long delay between write operations could be the writeType. There are two types, writeWithResponse
and writeWithoutResponse
. The first is the safer method because you will receive a confirmation if your message was sent correctly. This obviously restricts data throughput.
Setting the writeType to writeWithoutResponse could work in your case. This issue on github shows the correct way:
Characteristics.WriteType = Plugin.BLE.Abstractions.CharacteristicWriteType.WithoutResponse;
CodePudding user response:
I see two issues that can be improved:
- As mentioned by JonasH in a comment, don't use
async/await
andContinueWith
together.await
is sufficient to suspend your code until an async Task completes. - Re-use the "setup" of the communications, so that only the final call needs to be done twice.
I'm not familiar with that plugin (looked at its docs just now, to confirm the basic approach), so this code may need some adjustment, but hopefully this will be a starting point:
public async Task WriteByteTwice(byte value)
{
try
{
// Plug-in docs say WriteAsync call should be on MAIN THREAD.
if (!Xamarin.Essentials.MainThread.IsMainThread)
throw new InvalidProgramException("WriteByteTwice must be called from MainThread");
byte[] data = {value};
Characteristics = await Service.GetCharacteristicsAsync();
// Send data first time.
await Characteristics.First().WriteAsync(data);
await Characteristics.First().StartUpdatesAsync();
await Task.Delay(10);
// Send data again.
await Characteristics.First().WriteAsync(data);
await Characteristics.First().StartUpdatesAsync();
}
catch (Exception e)
{
Debug.WriteLine("********* Failed to get ReadCharacteristics: " e.Message);
}
}