polarofficial / polar-ble-sdk

Repository includes SDK and code examples. More info https://polar.com/en/developers
Other
475 stars 153 forks source link

ECG streaming getting bigger and bigger delays #319

Closed Davidvster closed 1 year ago

Davidvster commented 1 year ago

Platform your question concerns:

Device:

Hi, I am using the polarApi.startEcgStreaming(.deviceId, settings) and I am logging the timestamp that I get in the PolarEcgData class and the current system timestamp. I am noticing that initially, the difference between the timestamp that I get from H10 and the Android system is minimal (between 500ms - 1s) and it stays consistent for about 10minutes, after that the difference starts exponentially increasing to seconds and then into minutes. Check the table below for examples.

Description: Hi, I am using the polarApi.startEcgStreaming(.deviceId, settings) and I am logging the timestamp that I get in the PolarEcgData class and the current system timestamp. I am noticing that initially, the difference between the timestamp that I get from H10 and the system is minimal (between 500ms - 1s) and it stays consistent for about 10minutes, after that the difference starts exponentially increasing to seconds and then into minutes. Check the table below for examples.

H10 ECG timestamp Android device timestamp of the event Diff
1 2022-11-27T22:12:29.691929527Z 2022-11-27T22:12:30.339316Z 647.386473ms
2 2022-11-27T22:15:40.496717200Z 2022-11-27T22:15:41.455464Z 958.746800ms
3 2022-11-27T22:18:29.085147998Z 2022-11-27T22:18:30.001913Z 916.765002ms
4 2022-11-27T22:20:14.940554192Z 2022-11-27T22:20:15.896959Z 956.404808ms
5 2022-11-27T22:22:09.759198714Z 2022-11-27T22:22:11.498240Z 1.739041286s
6 2022-11-27T22:22:46.165011025Z 2022-11-27T22:23:04.514644Z 18.349632975s
7 2022-11-27T22:23:47.215044216Z 2022-11-27T22:25:08.440471Z 1m 21.225426784s
8 2022-11-27T22:26:24.595825981Z 2022-11-27T22:28:43.014606Z 2m 18.418780019s
9 2022-11-27T22:28:30.052948660Z 2022-11-27T22:31:38.037593Z, 3m 7.984644340s

I tried setting the MTU to 70 and to 512 and no noticeable difference is found, the only difference is that with the 70 MTU there are more events with less samples meanwhile with 512 there are less events with more samples, but the difference between the H10 timestamp and the Android device is exponentially getting worse.

It looks like the H10 is throttling more and more how often it is sending the data for ECG. From my testing with the heart rate with polarApi.startListenForPolarHrBroadcasts(setOf(deviceId)) it is consistently being sent every second so I dont think there is a problem with the heart rate, just with the ECG.

The code I am using is in my git repo. I am doing the logging in the HeartRateRepository which is using the ObserveEcgDataInteractor and ObserveHrDataInteractor.

Tested using Samsung S21 with Android 13 but had the same issue with Android 12.

Thank you 😊

JOikarinen commented 1 year ago

Hi @Davidvster, thanks for the observation and detailed explanation.

I wanted to reproduce the issue so I did some modifications to example app to catch the issue you explained.

In startEcgStreaming() Observer I added the logging like this:

 { polarEcgData: PolarEcgData ->
          // Get Android system time since 1.1.1970 in nanoseconds
          val timeStampForDataArrival: Long = System.currentTimeMillis() * 1000L * 1000L

          // Pre condition, the H10 time is set to UTC time
          // time stamp of the latest sample recorded by H10 since 1.1.2000
          val timeStampH10 = polarEcgData.timeStamp
          // Offset 1.1.1970 to 1.1.2000
          val offset = 946684800000000000L
          val timeStampH10Since1970 = timeStampH10 + offset

          val timeDifference = timeStampForDataArrival - timeStampH10Since1970
          val oneSecondInNano = 1000000000L
          val fiveSecondsInNano = 5000000000L

          if (timeDifference < 0L ) {
              // Suspicious state if the H10 time stamp is bigger than Android system time stamp,
              // since there should always be some delay from the moment sample is taken in H10 until it arrives over the BLE
              Log.w("TIME_STAMP_TEST", "H10 time stamp is bigger. Android system timestamp $timeStampForDataArrival H10 time stamp: $timeStampH10Since1970")
          } else if (timeDifference  in 0L  until oneSecondInNano ) {
              // Expected. Let's accept the 1 second time difference
              Log.d("TIME_STAMP_TEST", "H10 time stamp and Android system timestamp within one second")
          } else if (timeDifference in oneSecondInNano  until fiveSecondsInNano) {
              // A bit of suspicious.
              Log.w("TIME_STAMP_TEST", "H10 time stamp and Android system timestamp difference more than one second. Android system timestamp $timeStampForDataArrival H10 time stamp: $timeStampH10Since1970")
          } else {
              // Very suspicious.
              Log.e("TIME_STAMP_TEST", "H10 time stamp and Android system timestamp difference more than five second. Android system timestamp $timeStampForDataArrival H10 time stamp: $timeStampH10Since1970")
          }
      },

See the branch with the test code: https://github.com/polarofficial/polar-ble-sdk/tree/issue-319.

After few rounds of testing I couldn't yet reproduce your observation: it stays consistent for about 10minutes, after that the difference starts exponentially increasing to seconds and then into minutes.

Davidvster commented 1 year ago

Hey @JOikarinen thank you very much for looking into this. I did test your code and it works as expected, even after 20minutes, the difference is 99% less than 1 second, only occasionally going over 1s, but never above 5s.

I assumed that the problem is with my app. I was displaying multiple graphs and a Google Map on the same screen, with all the data from sensors + H10 being displayed in the graphs. Once data got over cca 3k data entries each, the UI started to become laggy, but it still worked. Interestingly there was no delay with the phone sensors (gyro & accelerometer) and with the H10 heartrate broadcast. However the H10 ECG streaming is the one that became sluggish after cca 10min.

I now limited that I show at most 1k data entries in the graphs, the streaming of ECG works as expected averaging 200ms delay with the MTU set to 70.

Once again thank you.

Closing this issue as it was a problem with my implementation and not with the Polar SDK.