laberning / openrowingmonitor

A free and open source performance monitor for rowing machines
https://laberning.github.io/openrowingmonitor
GNU General Public License v3.0
98 stars 19 forks source link

BLE Heart Rate recording issue? #132

Closed sean808080 closed 1 year ago

sean808080 commented 1 year ago

I am wondering if there is any issue with the BLE heart rate data being captured in my installation? I did a workout yesterday and watched as the screen showed my heart rate dropping when I was sweating and working hard. My Apple Watch recorded the data as expected (no dips, gradual increase) but the data captured by ORM and uploaded to Strava shows a few erroneous dips in the middle of the workout. I'm fairly confident that my strap is working as expected as I've used it many times and never seen an issue like this before.

Screen capture of the workout captured by my Apple Watch:

goodImage

Screen capture of the workout captured by ORM: flaky2

Abasz commented 1 year ago

When I was doing the ANT+ part I noticed this issue with my ant+ strap, and it turned out the ant stick's and the straps (garmin HRM TRI) range was very limited and when I moved the Rpi closer to me the issue got resolved. How far are you from the Rpi when rowing? The distance these straps can handle is really limited in my experience, though I have never used BLE ones.

sean808080 commented 1 year ago

Iโ€™m only about 3 feet away from the Rpi3. What I also notice is that the rate recovers when I stop paddling so I wonder if itโ€™s a setting?

webUpdateInterval: 200, peripheralUpdateInterval: 400,

beavis69 commented 1 year ago

I have polar H10 strap and it can be connected via ANT+ or BLE, i've tried both.

When using ANT+, if it's disconnected i have to force the reconnection by restarting the workout on web interface or restarting the service via ssh. Connection distance must be very small like 2 meter max.

When using BLE it seems to reconnect without doing anything, and connection distance seems to be more like 5 or 10 meters. The issue, i have with BLE is that H10 can be connected to 2 devices (you can see 2 mac address), but i cannot force the bluetooth mac address used by openrowingmonitor. Sometimes my phone and openrowingmonitor are fighting to connect to the same mac address .

sean808080 commented 1 year ago

I have polar H10 strap and it can be connected via ANT+ or BLE, i've tried both.

When using ANT+, if it's disconnected i have to force the reconnection by restarting the workout on web interface or restarting the service via ssh. Connection distance must be very small like 2 meter max.

When using BLE it seems to reconnect without doing anything, and connection distance seems to be more like 5 or 10 meters. The issue, i have with BLE is that H10 can be connected to 2 devices (you can see 2 mac address), but i cannot force the bluetooth mac address used by openrowingmonitor. Sometimes my phone and openrowingmonitor are fighting to connect to the same mac address .

@beavis69 Can't you disable the Ant+ support so it always connects to the BLE channel?

I see this in the default.config.js: heartrateMonitorANT: false,

To stop fighting the phone connection, can't you forget the bluetooth profile?

beavis69 commented 1 year ago

I've disabled ant+ both in H10 strap and in my config.js with heartrateMonitorANT: false

Actually i want both BLE connections : polar flow on my phone and openrowingmonitor on my rpi. The phone use the main mac address (used to configure the H10 to enable or disable ANT+ and duplicate BLE mode). I don't how to check the bluetooth mac address openrowingmonitor is using and how to force it to the second address.

Abasz commented 1 year ago

When using ANT+, if it's disconnected i have to force the reconnection by restarting the workout on web interface or restarting the service via ssh. Connection distance must be very small like 2 meter max.

What ANT stick are you using? Actually for me once its connected and reconnects automatically. There are sometimes issues with the initial connection but after that it works (unless not close enough). My stick is chineese and actually 2meters are too far :) I have to ahve the rpi next to the flywheel and also the less blockage the better connection.

Now on the connection restart issue: the communication with the ANT+ stick is done via a usb nodejs library that is not that stable for me. For instance sometimes the stick is not closed properly by the usb library and reconnection is no longer possible (but this relates to restarting ORM).

I have tried to actually restart the stick once connection to a peripheral is lost but in case of frequent dropouts it could cause crash.

@sean808080 On the bluetooth side. Can you disable BLE data broadcast (i.e. FTMS or CPS or which ever) if you have not done so? The BLE implementation is quite tricky as we are using two ble libraries as one library can only handle one connection. This far from ideal as we need to spawn a separate BLE process for the HRM using a different library.

Abasz commented 1 year ago

When using BLE it seems to reconnect without doing anything, and connection distance seems to be more like 5 or 10 meters. The issue, i have with BLE is that H10 can be connected to 2 devices (you can see 2 mac address), but i cannot force the bluetooth mac address used by openrowingmonitor. Sometimes my phone and openrowingmonitor are fighting to connect to the same mac address .

This would be a very complicated matter to sort out efficiently as the mac address filter would need to be implemented (that is not that complicated) and the straps mac would need to be saved. This requires revamp on at least 2, but preferably 3 areas (settings persistence, settings management from gui, and peripheral connection management).

beavis69 commented 1 year ago

It's a genuine garmin stick that was sold with an old garmin swim watch, detected as "mini ANT+ stick" in openrowing monitor logs.

For the double BLE connection, i've tried bluetoothctl block xx:xx:xx:xx:xx but it seems that openrowingmonitor overides that.

beavis69 commented 1 year ago

Can you disable BLE data broadcast

I dont see any settings for that. How to disable it ? I've read app/ble/PeripheralManager.js (v1beta) and it seems it's always active.

sean808080 commented 1 year ago

@Abasz what a good suggestion as I don't need the BLE data options at this time but as @beavis69 said, there is no obvious way to disable it. In the UI, clicking the bluetooth icon just iterates through the profiles and one is always active.

Perhaps a NONE option should be added so we can disable it from the UI?

@sean808080 On the bluetooth side. Can you disable BLE data broadcast (i.e. FTMS or CPS or which ever) if you have not done so? The BLE implementation is quite tricky as we are using two ble libraries as one library can only handle one connection. This far from ideal as we need to spawn a separate BLE process for the HRM using a different library.

sean808080 commented 1 year ago

Checking the logs for anything that might be useful. I see something like this in most of the logs. Which is what i expect. Screenshot 2023-03-03 at 11 39 15 AM

Just a bit further down it shows this which I don't expect. It is showing a number of HRR devices sometimes in the logs when there should always be just one. Am I understanding it correctly? Screenshot 2023-03-03 at 11 39 19 AM

beavis69 commented 1 year ago

@sean808080 i think your are still on master branch, this is what i see with v1beta on connection/disconnection :

mars 03 13:39:17 rowingmonitor npm[942]: heart rate peripheral connected, name: 'Polar H10 7xxxxxxxx', id: xxxxxxxxxxx
mars 03 13:39:23 rowingmonitor npm[942]: heart rate peripheral disconnected, searching new one
mars 03 13:39:34 rowingmonitor npm[942]: heart rate peripheral connected, name: 'Polar H10 7xxxxxxxx', id: xxxxxxxxxxxx
mars 03 13:39:34 rowingmonitor npm[942]: heart rate peripheral disconnected, searching new one
mars 03 13:39:36 rowingmonitor npm[942]: heart rate peripheral connected, name: 'Polar H10 7xxxxxxxx', id: xxxxxxxxxxxx
mars 03 13:39:44 rowingmonitor npm[942]: heart rate peripheral disconnected, searching new one

I see no message with HRR

sean808080 commented 1 year ago

I should be on v1beta. I see this elsewhere in the logs from yesterday when I was trying to use my applewatch with the ORM.

Mar 02 09:30:19 rowingmonitor npm[2441]: heart rate peripheral disconnected, searching new one Mar 02 09:30:19 rowingmonitor npm[2441]: heart rate peripheral connected, name: 'ECHO HR', id: 5d47dd72f5f5 Mar 02 09:30:19 rowingmonitor npm[2441]: heart rate peripheral disconnected, searching new one Mar 02 09:30:19 rowingmonitor npm[2441]: heart rate peripheral connected, name: 'ECHO HR', id: 5d47dd72f5f5 Mar 02 09:30:50 rowingmonitor npm[2441]: heart rate peripheral disconnected, searching new one Mar 02 09:33:42 rowingmonitor npm[2441]: heart rate peripheral connected, name: 'RHYTHM+870395', id: c926f0ed47fb Mar 02 09:33:55 rowingmonitor npm[2441]: heart rate peripheral disconnected, searching new one Mar 02 09:33:55 rowingmonitor npm[2441]: heart rate peripheral connected, name: 'ECHO HR', id: 5d47dd72f5f5 Mar 02 09:34:25 rowingmonitor npm[2441]: heart rate peripheral disconnected, searching new one

beavis69 commented 1 year ago

@sean808080 do you have multiple BLE heart rate monitors, or are you near other people with such devices ? Your log shows there are 2 : ECHO HR and RHYTHM+870395

I think, we need be able to lock the connection on a mac address, if not, how is openrowingmonitor supposed to pick the right one when there is multiple ? A list of whitelisted mac address would be ideal.

sean808080 commented 1 year ago

@sean808080 do you have multiple BLE heart rate monitors, or are you near other people with such devices ?

Your log shows there are 2 : ECHO HR and RHYTHM+870395

@beavis69 That was just a one time test of using my Apple Watch as a heart rate sensor (using the ECHO HR app). The logs I shared earlier with the dips in the recorded heart rate were using only the regular heart rate strap. No other Bluetooth peripherals nearby.

Abasz commented 1 year ago

I just realized you are not using the updated peripheral code as it is in the hanging PR: https://github.com/laberning/openrowingmonitor/pull/114

Sorry about that. In that PR there is a majour overhaul of the BLE and ANT management. It is possible to switch everything independently on and off etc. We switched the ANT library to one that is being maintained. Also provide ANT FE-C rowing profile for smart watch integration.

How much do you know about git commands? :)

You need to switch to Jaap's v1beta_update branch under his repo (https://github.com/JaapvanEkris/openrowingmonitor)

What needs to be done is that you need to add a new git remote in the current ORM folder and checkout the v1beta_update branch.

sean808080 commented 1 year ago

@Abasz very interesting...I'm game to try it but my CLI skills are rusty. I'm glad I'm able to get this far. ๐Ÿ‘๐Ÿพ

Does this look like what I need to do from the command line on the rpi?

cd /opt/openrowingmonitor git remote add origin https://github.com/JaapvanEkris/openrowingmonitor.git git checkout v1beta_updates

Abasz commented 1 year ago

@Abasz very interesting...I'm game to try it but my CLI skills are rusty. I'm glad I'm able to get this far. ๐Ÿ‘๐Ÿพ

Does this look like what I need to do from the command line on the rpi?

cd /opt/openrowingmonitor git remote add origin https://github.com/JaapvanEkris/openrowingmonitor.git git checkout v1beta_updates

You are on the right track, thanks for committing more effort to this project. I Would use something different than origin as name, like devel or whatever. Origin is likely to exist already for the main repo.

Also you might need to do a git fetch devel/v1beta_updates befor checkout. Also you might need to use git checkout devel/v1beta_updates

Actually I use VSCode that has an integrated git manager and these simple tasks are done via the gui so I dont use these cli commands that often, only the more complicated ones that are not in the GUI.

sean808080 commented 1 year ago

I took your lead @Abasz and installed VS and the github and SSH extensions

I was able to add the remote and checkout the v1beta_updates but now I'm getting an error related to dependencies I guess:

Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'incyclist-ant-plus' imported from /opt/openrowingmonitor/app/peripherals/ant/AntManager.js

sean808080 commented 1 year ago

@Abasz I figured it out I think....

npm install

now ORM is starting up without errors but it's time to take the kid to basketball practice so this will have to end here for today. Thanks for the tip!

Abasz commented 1 year ago

@Abasz I figured it out I think....

npm install

now ORM is starting up without errors but it's time to take the kid to basketball practice so this will have to end here for today. Thanks for the tip!

Yes the install I have not mentioned sorry:)

beavis69 commented 1 year ago

Hi, I switched to v1beta_updates and now ble is working great with my polar H10 with double ble activated. Thank you.

JaapvanEkris commented 1 year ago

Checking the logs for anything that might be useful. I see something like this in most of the logs. Which is what i expect. Screenshot 2023-03-03 at 11 39 15 AM

Just a bit further down it shows this which I don't expect. It is showing a number of HRR devices sometimes in the logs when there should always be just one. Am I understanding it correctly? Screenshot 2023-03-03 at 11 39 19 AM

HRRx stands for Recovery Heart Rate after x minutes. So HRR1 is the heartrate after 1 minute, etc..

Recovery Heart Rate is an important indicator for heart health.

sean808080 commented 1 year ago

Thanks for clarifying @JaapvanEkris

The v1beta_updates update did the same thing yesterday during a workout. I'm going to troubleshoot a bit more to see if I can isolate why the heart rate is erratic for me.

Abasz commented 1 year ago

Thanks for clarifying @JaapvanEkris The v1beta_updates update did the same thing yesterday during a workout. I'm going to troubleshoot a bit more to see if I can isolate why the heart rate is erratic for me.

Can please post the logs once you have it please? I don't use ble for heart rate as my strap is ant+ and only my watch can broafcast it via ble but measuring HR on wrist with optical while rowing is not working that well, so ble HR did not get that much of a testing in real scenarios.

Disconnects are logged if debug is enabled. It would make sense to see if there are any disconnects.

sean808080 commented 1 year ago

@Abasz Here are the logs from the last 2 days. My workout yesterday had the same observation where HR went down unexpectedly.

logs.txt

Abasz commented 1 year ago

The UI needs recompiling, though this is nothing to do with the HR. Can you please issue in the ORM dir:

npm build

and then restart ORM

I suppose this goes for you too @beavis69

I will have a look a the the logs and revert back

Abasz commented 1 year ago

@Abasz Here are the logs from the last 2 days. My workout yesterday had the same observation where HR went down unexpectedly.

logs.txt

The logs show that the strap connects correctly at the start and disconnects at the end. There is no dropout of connection, so it is more likely that the data that comes from the strap. So I think this is not ORM it self.

Its possible that the strap goes out of range for a short amount of time (like when you start recovery) also it is possible that the chest strap is not tight enough and looses contact with the skin and gets confused, but can be 100 other thing.

I would try to move the pi closer, also connect the strap to a compatible phone app for a session and see what that records.

sean808080 commented 1 year ago

The UI needs recompiling, though this is nothing to do with the HR. Can you please issue in the ORM dir:

npm build

and then restart ORM

I suppose this goes for you too @beavis69

I will have a look a the the logs and revert back

fyi I got this when trying to issue 'npm build'

npm WARN build npm build called with no arguments. Did you mean to npm run-script build?

Running npm run-script build gave an Error: EACCES: permission denied,

Running sudo npm run-script build worked.

beavis69 commented 1 year ago

Actually i did (as root user) :

/opt/openrowingmonitor
npm config set user 0
npm ci
npm run build

like it's done in install.sh

Abasz commented 1 year ago

Actually i did (as root user) :

/opt/openrowingmonitor
npm config set user 0
npm ci
npm run build

like it's done in install.sh

Yes, indeed. Sorry in my workflow I have this aliased so I dont have to type out the whole thing.

sean808080 commented 1 year ago

Unfortunately I'm still seeing issues with the heart rate as recorded by ORM.

  1. I first confirmed my Scosche Rhythm + by doing a workout watching the Scosche app on my phone and it worked as expected. No drop offs were observed nor were there any in the past with this strap.
  2. Today I licked the back of the strap just to ensure conductivity. Didn't need it before but it didn't hurt. :-)
  3. Mid workout I even paused to power cycle the heart rate strap to see if ORM would then work correctly. That didn't work.

So, during today's workout, the recorded heart rate barely went above 100! It just moved around close to that low rate despite my efforts. Here's a chart of what ORM captured:

Screenshot 2023-03-09 at 9 22 48 AM

Here's the same workout with the heart rate as captured by my Apple Watch (working as expected):

Screenshot 2023-03-09 at 9 27 33 AM

So overall, today's workout was the worst one yet heart rate wise. Maybe it's user error but I'm not sure how.

Interestingly, only after I hit the reset button on the screen post workout did it magically show the current heart rate.

IMG_5081

Attaching the logs... logs_03092023.txt

Abasz commented 1 year ago

I fully understand your issue and frustration. The problem is that there is no obvious way to debug this. I did not experience this problem when I tested this feature. @JaapvanEkris I think has been using BLE strap as well and I believe (but he will correct me if I am wrong) he did not experience such behavior either.

I know that sometimes ORM drops the connection and then reconnects and than there is a dropout, but that should be visible in the logs. In your logs the strap connects and remains connected throughout the workout and disconnects only at the end.

Due to the above was I saying that it is probably no the code in ORM. Actually the BLE HR related code in ORM is extremely simple: once there is new raw data, it is translated as per the official specs by interpreting the flag bits and converting bits to integers:

              const buffer = Buffer.from(data)
              const flags = buffer.readUInt8(0)
              // bits of the feature flag:
              // 0: Heart Rate Value Format
              // 1 + 2: Sensor Contact Status
              // 3: Energy Expended Status
              // 4: RR-Interval
              const heartRateUint16LE = flags & 0b1

              // from the specs:
              // While most human applications require support for only 255 bpm or less, special
              // applications (e.g. animals) may require support for higher bpm values.
              // If the Heart Rate Measurement Value is less than or equal to 255 bpm a UINT8 format
              // should be used for power savings.
              // If the Heart Rate Measurement Value exceeds 255 bpm a UINT16 format shall be used.
              const heartrate = heartRateUint16LE ? buffer.readUInt16LE(1) : buffer.readUInt8(1)
              emitter.emit('heartRateMeasurement', { heartrate, batteryLevel })

What you could try is to include a log statement to log the raw arrayBuffer to the console and inspect manually. But IMHO if something was wrong with the code one would not get data at all. That is why I still suggest that it is the strap that has trouble measuring while this specific movement.

Second option is to try to set your apple watch to HR broadcast mode (if apple watch supports this at all, I never had an apple watch) and use that for testing out. This is what I did with my garmin while testing, I was watching the watch and the monitor whether they show the same value and while testing it did.

JaapvanEkris commented 1 year ago

I fully understand your issue and frustration. The problem is that there is no obvious way to debug this. I did not experience this problem when I tested this feature. @JaapvanEkris I think has been using BLE strap as well and I believe (but he will correct me if I am wrong) he did not experience such behavior either.

I use it almost daily with a Garmin Dual Pro, and ORM never drops out on BLE. Sometimes I use ANT+, also reliable as a rock. In fact, the PM5 lost connection two weeks ago, where ORM just went ahead and stayed connected. In my experience, the new implementation of @Abasz (included V1Beta_Updates) is even a bit better than the 0.8.4 and V1Beta implementation. It is much more responsive, so finding the HR monitor is much quicker.

I know that sometimes ORM drops the connection and then reconnects and than there is a dropout, but that should be visible in the logs. In your logs the strap connects and remains connected throughout the workout and disconnects only at the end.

Agree. An issue I do observe with Garmin that when it loses connection with my body (strap too loose or sensors not wet enough), it will default to 72 BPM. ORM can perfectly see it and it won't tell it has a problem (so no errors in the ORM logs), but it won't measure anything sensible. I can inmagine another manufacturer will do the same.

What you could try is to include a log statement to log the raw arrayBuffer to the console and inspect manually. But IMHO if something was wrong with the code one would not get data at all. That is why I still suggest that it is the strap that has trouble measuring while this specific movement.

Rowing can be quite a wild experience for watches and chest straps. Watches usually struggle a lot (my Garmin Venu missed quite some measurements during a row, which is why I started using a chest strap like most rowers).

Second option is to try to set your apple watch to HR broadcast mode (if apple watch supports this at all, I never had an apple watch) and use that for testing out. This is what I did with my garmin while testing, I was watching the watch and the monitor whether they show the same value and while testing it did.

AFAIK, it requires an additional app to do that. I'm quite sceptical for watches being able to keep measuring during a rowing sprint. When there are quite hefty movements, the movement will block HR reading.

sean808080 commented 1 year ago

Thanks for the input sir. I am going to continue testing a couple of different ways and will circle back with my findings.

sean808080 commented 1 year ago

I switched to a Garmin HRM duo and have had multiple sessions without issue so the likely culprit may be the older heart rate monitor. Thanks all for the input.

Abasz commented 1 year ago

Does it show the battery state on the GUI? I think I might have found a bug there but I dont have the equipment to confirm...

sean808080 commented 1 year ago

Does it show the battery state on the GUI? I think I might have found a bug there but I dont have the equipment to confirm...

Battery state isn't shown any more..when an HRM is connected which worked before.

Another issue is the ability to toggle the heart rate monitor itself doesn't work like it did before. Prior, you could turn BLE on and off by clicking on the heart icon here:

image

alternate link to image

Abasz commented 1 year ago

Another issue is the ability to toggle the heart rate monitor itself doesn't work like it did before. Prior, you could turn BLE on and off by clicking on the heart icon here:

Yes I broke that :), but will be working shorty, I already know what I messed up and fixed on my local version (sorry about that). The battery not being shown is a completely different issue I think and might be on the server side. The GUI works if it receives the battery data, but I suspect that the BLE specs changed and there is a separate "battery service" with a different UUID and the server does not subscribe for that. I will try to code up a device to mock a BLE battery service to test.