Cheap Android Tablets & Multiple BLE connections performance
Hello there,
some days ago I've recieved an bug ticket from a user with an Tablet: Lenovo Tab M8 (3rd Gen) 8"
He told me that when he connects a bluetooth-scale, the receiving data are working flawless.
When he connects a bluetooth-pressure, the receiving data are working flawless.
But when he connects the bluetooth scale, aswell as the bluetooth pressure device, the receiving data has a high latency lag. The data from the pressure sensor aswell as from the scale are reported within 100ms each. When both are connected, the data transmittings take like 1.5s to 2s for each value in worst case.
Another tablet e.g: Samsung Tab A 10.1 (2016) does not have any issues anymore.
Therefore for me its looking like somehow a bluetooth chip usage issues even when BT 5.0 is stated.
Do you know this issue, do you have ideas how to handle it maybe?
Thanks so far for your time! Have a great cup of coffee :) Lars
Hi @graphefruit
As a step one, I'd suggest try calling https://github.com/don/cordova-plugin-ble-central?tab=readme-ov-file#requestconnectionpriority with "high", and see if this makes a difference.
E.g.,
await ble.withPromises.requestConnectionPriority(device_id, "high");
Hey @peitschie, thanks for the fast replay (as always <3) I've made the change and sent to the user:
ble.connect(
deviceId,
(data: PeripheralData) => {
try {
setTimeout(() => {
ble.requestConnectionPriority(deviceId, 'high', ()=> {
this.uiToast.showInfoToast('We requested high priority sucessfully for scale');
},
()=> {
this.uiToast.showInfoToast('We could not request high priority for scale');
});
},500);
}catch(ex) {
}
I couldn't do the requestConnectionPriority before connecting, it just worked when connected. The user (and myself) got toast popup that the priority was successfully done for scale.
The feedback of the user was that it doesn't helped sadly.
Adding to this, this are the reported timestamps of the values of the scale.
15:42:25.929
15:42:26.780
15:42:28.239
15:42:28.527
15:42:29.231
15:42:30.171
15:42:30.906
15:42:31.579
15:42:32.580
15:42:33.766
15:42:34.322
15:42:34.883
15:42:36.158
15:42:36.716
15:42:37.140
15:42:38.122
15:42:38.763
15:42:39.221
15:42:39.762
15:42:40.727
15:42:41.006
15:42:41.713
15:42:42.501
There are realy huge jumps.
Hrm!
Are you able to get any information from the Bluetooth device about it's connection parameters (connection intervals, slave latency, etc)?
The other thing I'd suggest is use nrf Connect to try connecting, and look at the debug logs from there to see if there's any connection interval info we can see.
There's very little that plugin does here that might contribute to latency, which makes me wonder if what you are seeing is a performance problem with the tablet manufacturer's Bluetooth stack, or potentially even a limitation of the BLE radio the tablet uses (perhaps it's not able to handle the concurrent packets efficiently).
Thanks @peitschie, great idea! I've forwarded this idea to the user and waiting for response right now :)
But I also think its a total limitation of the BLE radio/stack.
The issue rather on my end is: People are having a tablet, using the Beanconqueror App and getting back to me because they have BLE-issues, and I actually can't give a good feedback like: you need a minimum requirement of X tablet
Hey @peitschie long time ago to come back here - sorry it took a while to get the feedback. Somehow the user did some more tests, this time just with one connected bluetooth scale.
Test device: Lenovo M8 tablet
He did two tests scenarios:
- Using the bluetooth scale with an app written in Flutter - No lag
- Using the bluetooth scale with the Beanconqueror App (now Capacitor, but this plugin in Cordova) - Lag
Second test: Test Device: Samsung S22
- Using the bluetooth scale with an app written in Flutter - No lag
- Using the bluetooth scale with the Beanconqueror App (now Capacitor, but this plugin in Cordova) - No lag
So somehow things behave different on the Lenovo. I thought maybe you have also (a bit) knowledge how things work in Flutter and could make some conclusions?
Thanks so far for your help!
@graphefruit thanks for continuing to report back your findings.
The strange part here is that theoretically the flutter/cordova/capacitor differences should happen after the notification is grabbed and queued up for sending to the UI. I.e., all these frameworks tend to use an identical plugin-based method to access the same underlying Bluetooth calls in the operating system.
How "simple" is the capacitor app you're using here? Is this a barebones app that does nothing other than report the scale weights... or is there a bunch of other processing/animations/etc. that happen in the javascript engine?
I have seen a problem reported every now and then where a lower power tablet seems to have issues keeping up with Bluetooth notifications... but the fact that flutter works fine here but capacitor does not makes me wonder if the application's own performance is a factor here (previously I had mostly assumed the app couldn't impact the rate at which data can be received by Android).
Hello @peitschie ! And a happy new year belated! ;) Thank you for the detailed feedback.
Easy spoken: my capacitor app is more or less an track-book for coffee brews. The logic is like: You startup, press "add" and then you're on a dedicated page where you can track your coffee brew with all parameters.
There is indeed some background things and the app is "bloated" with services, helper functions etc, but none of them are called while runtime streaming the data. In behind I'm using the IndexedDB to save the data.
But to be honest: There are no css-animations (just plotly), very powerfull consumption calculation or even background-tasks running.
For the chart rendering I'm using plotly.js.
My capacitor app is done with Ionic based on Angular.
With my latest 8.0 release, I've checked also the change-detections from Angular and there where huge checks (more then a hundred checks within 1 second), which I've taken down to like 1 or 2 checks within one second. (That said, the app run fluently before aswell)
The only thing how data are send when received via bluetooth is with an observable
I've made a short gif demonstrating what is happening:
The updating for the tiles you see (pressure, weight, flow) is also done native, without angular, and out of the ngZone.
Actually I don't have the time to totally make a new draft app to just stream the weight and plot it, but maybe this helps aswell.
The most curious for me: Why its working on several devices without issues, and on others there is the issue. Adding to this: I've had the situation on an iPad Mini 3, that when using http-calls and bluetooth, I had lags, but using just http or bluetooth I don't had lags, just combined. Not 100% located to this case, but maybe also a helpful insights.
What comes to my mind: Is it actually possible that the plugin logs the real timestamp when it receives a package? So I may could log this one, and log when Beanconqueror receives this in the application to get more insights?
Thank you so far for taking the time to help here! Have a great cup of coffee Lars
Good Evening @peitschie, I've some new insights to this topic.
Some days ago I've got a Samsung Galaxy A7 Lite. And I've got the issue when connecting one bluetooth scale.
I've somehow stumbled across my code and removed things and voila i've found one crucial situation:
Plotly.extendTraces(
this.profileDiv.nativeElement,
{
x: xData,
y: yData,
},
tracesData,
);
I'm plotting the data via Plotly. And somehow when the data came in to fast, the drawing blocked everything.
The solution was:
if (this.graph_threshold_frequency_update_active === true) {
if (
Date.now() - this.graphUpdateChartTimestamp <
this.graph_frequency_update_interval
) {
return;
}
this.graphUpdateChartTimestamp = Date.now();
}
I just update the graph every X milliseconds which can be set from a user.
Changing to like 150ms or 200ms refresh time, made it working as good as flawless.
I've now sent some test versions out to users with poor performing tablets, also an iPad Mini 3, and I can give feedback again.
@graphefruit oh! I've had exactly this challenge before on other graphing applications 😅. It didn't occur to me that the graph in your picture above was so real-time.
Thanks for sharing your investigation results back. Once you're happy this has fixed your problem, feel free to close out this issue 🙂
Good Evening,
We've now did some more tests (Galaxy Tab A7 Lite, aswell as on a iPad Mini 3). It turns out that changing the refresh-interval for the graph going up from 100 ms to like 150 or 200ms does fix the mentioned situation.
Anyhow some more words:
What we did was taking an Galaxy Tab A7 Lite and a Samsung Galaxy S22 (which didn't had this issue) and we set the refresh interval for the Galaxy Tab A7 Lite to 200ms, and for the Samsung Galaxy S22 we deactivated it (so it refreshed directly when a new data package was received).
Beanconqueror allows to download then all reported data-packages, and we compared those too several times (and also switched the scales for the phones) Resolution: The reported weights where the "Same" (some scales are faster, some are a bit slower), but the end weight was always the same.
So ticket can be closed.
Thank you for the support, and your time invest @peitschie ! And sorry for the false promise situation here. Lars