Bangle.js 2 Cutting Edge - new heart rate algorithm

Posted on
Page
of 6
Prev
/ 6
Last Next
  • And let me remind you that even algorithms like WPFV [1] do produce values that differs significantly from the actual BPM, e.g. 15BPM for several seconds.

    [1] https://github.com/andtem2000/PPG

  • Thanks Gordon. With 2v17.55 the HR data looks at least plausible, although it seems a bit low. Before I was just ignoring HR data. I'm in the early stage of writing a sportwatch app specially for supporting running "reps" workouts and eventually workout programming. It would be relatively easy to guess if it's running strides, jogging recovery or still recovery from the app (and for sure with workout programming). A way of changing the mode from activity apps would be handy.

  • Just added Bangle.setOptions({hrmSportMode:1}) in the latest cutting edge builds - I'd love to see if it makes a noticeable difference!

  • ok similar to the last time I did the following small test with each part for approx one minute:

    1. sitting still
    2. walking slow
    3. walking fast
    4. running without moving
    5. sitting still

    Result is bt chest belt in blue, firmware 2v17.55 in green, firmware 2v17.56 in sports mode in red. X-Axis is hrm event count (~1 second), y-axis is BPM.


    1 Attachment

    • plot.png
  • Wow, I will settle for that!!!

  • Yes, that's very nice! And thanks again for these tests - nothing beats having real data to make decisions with.

    So what do we think about setting the sport mode up? We have a few options:

    • Default to just setting sport mode = 1 all the time (easy - maybe slightly longer time to get a heart rate?)
    • Use the accelerometer 'motion' value and if there was significant motion in the last ~30 seconds, switch to sport mode (this appears to be what the manufacturer-provided thing does)
    • Check for steps from the step counter in the last 30 seconds (although maybe this won't work for cycling/etc?)

  • Sounds like all 3 would work.

    Could you explain, option 2, motion value?

  • What would the battery usage be like comparing 1 and 2? Would polling the accelerometer increase power consumption vs keeping it always in sports mode?

    Is there any advantage to the regular mode vs sports mode besides possibly faster HR acquisition like you mentioned?

  • Don't think battery will be a problem, the accelerometer is always on anyway.

  • Yes, none of those would hurt power consumption any noticeable amount.

    Could you explain, option 2, motion value?

    We store a movement value for http://www.espruino.com/Reference#l_Bangle_getHealthStatus

    But what I'd do is basically just store a running average of acc.diff, and if that went above a certain level we assume there's enough movement that we could switch to running mode

  • I guess we can not do much wrong with #2 if the original firmware does something similar (or just make it configurable).

  • Is this in the latest firmware yet?

  • Not 2v17, but cutting edge. It'll be in 2v18 when released.

    Automatic sport mode switch isn't done yet

  • I tested cutting edge build and for me the HR is still about 10BPM off (lower) when sitting in steady state. I tried one Q3 with Bangle2 firmware, second Q3 with original firmware, GT101 fitness tracker and B5 fitness tracker both with original firmware. So on both hands I had one Q3 watch and one fitness tracker. When sitting still the three of them agreed my rate is about 70-75 while Bangle 2 showed 60-65 often with 100% confidence. Once I started moving and HR grew higher the difference went away and I had cases when all 4 agreed on my HR above 80 but when I went sitting still again and HR went lower then again there was about 10BPM difference. @Gordon is that binary from same source as used in original Q3 firmware? Because that one shows 'correct' value different from Bangle2. Maybe you can even try yourself with one still with Q3 firmware.

    I don't have anything else than all those watches and fitness trackers all using similar PPG sensors so not sure if my HR is actually 60 or 70 when sitting.

    And BTW the Q3 also shows blood pressure with VC31 sensor, do you have access to that binary too? The B5 fitness tracker (from SMA too but differenf HR sensor) shows blood pressure too and they show very similar values. And when I had blood pressure monitor from my doctor for a day I tried to use B5 at the same time and it showed very similar values for normal pressure I have so I was surprised it actually worked.

  • is that binary from same source as used in original Q3 firmware?

    Well, more or less - it was provided by SMA who make the watch so I assume they used the same firmware.

    Are you saying that the Bangle 2 reported 10bpm different with both old (open source) and new (proprietary) firmwares? Maybe it is more of a timing issue.

    And BTW the Q3 also shows blood pressure with VC31 sensor, do you have access to that binary too?

    I do have that code as well, yes. The only issue there is it puts the sensor into a different mode (making IR + visible readings at the same (higher) rate) and the code to set that mode is something I'd have to sort out and test. I also don't have a blood pressure tester here so it's not something I'd have any confidence in testing - I never had much confidence in using PPG for blood pressure, but if it worked for you maybe there's hope :)

    If someone wanted to have a go with it I'm happy to send over what I have though.

  • Are you saying that the Bangle 2 reported 10bpm different with both old (open source) and new (proprietary) firmwares? Maybe it is more of a timing issue.

    I tried only the new (binary) one now in cutting edge. And that one was 10BPM below what other 3 devices including Q3 showed. When sitting still. Maybe you can try with Q3 on the other hand too?

    Maybe it is more of a timing issue.

    You mean like feeding the algorithm with bad timing?

    I never had much confidence in using PPG for blood pressure

    Well, neither do I. As I understand it tries to match the shape to some pre-trained data set as explained e.g. in https://www.mdpi.com/1424-8220/23/8/4145 so could be pretty bad based on the dataset used. I only know the B5 showed quite similar values to the one doctor gave me but as I have pretty normal blood pressure I could not test with too low or high one. And yesterday when I tried B5 and Q3 at the same time it gave almost exactly the same values. Could still be some fake average :-)

  • You mean like feeding the algorithm with bad timing?

    Yes... One potential issue is I think the algorithm was designed to work at ~10Hz but we're giving it more like 25Hz at the moment - but as you can see from the graphs above it definitely looks like it's doing a reasonable job for @user140377 at least.

  • Right now, while I'm typing this, I'm using the Polar H10 chest sensor (one of the most accurate non-medical devices) and bangle.js2 in the left wrist (firmware 2v17.113).

    Polar Beat (using H10): 60bpm
    Bluetooth Heart Rate Monitor:
    Internal: 58bpm (confidence 96%)
    BT (H10): 60bpm (about one second lag updating to a new value compared with the Polar Beat app)

    Walking fast the internal sensor's reading is quite higher than the Polar H10, but running the internal is slower increasing the value and it tends to read lower). The values with H10 are always more stable, it doesn't fluctuate as much as bangle.js2. HR with H10 is consistent with the ECG data from the same H10 sensor, and my HR doesn't fluctuate as much as bangle.js2 shows. Bangle.js2 is more sensitive to movement (is BT Heart Rate Monitor using "running mode"?).

    All in all, to me the readings with the newer firmware versions seem good enough for an optical sensor.

  • How are you recording and plotting the graphs?

  • If you want to compare the Bangle.Js please only compare it to a chest belt like the "Polar H10" mentioned above. All wrist measurement devices do lie you can not decide for each indidivual which one does lie more without a reference measurement.

    @adjtm
    To be honest this is the dirty part which can be improved, it is the following code:

    const file = require("Storage").open("hrmlog.json","w");
    Bangle.setHRMPower(1);
    Bangle.setBTHRMPower(1);
    
    Bangle.on('HRM', (hrm) => {
        console.log(hrm);
        const json = JSON.stringify({now: new Date(), hrm: hrm});
        file.write(json + ",\n");
    });
    
    Bangle.on('BTHRM', (hrm) => {
    	if (hrm.bpm > 0) {
    		console.log(hrm);
    		const json = JSON.stringify({now: new Date(), bthrm: hrm});
    		file.write(json + ",\n");
    	}
    });
    

    The json is converted to csv and then given to PlotJuggler.
    Next time I will change this to record in csv so no conversion is required.
    bthrm must be configured not to overwrite the internal measurement.

  • is BT Heart Rate Monitor using "running mode"?

    Not by default, unless you set the value with setOptions as mentioned in some of the previous posts

  • If you want to compare the Bangle.Js please only compare it to a chest belt like the "Polar H10" mentioned above. All wrist measurement devices do lie you can not decide for each indidivual which one does lie more

    Well Bangle.js is also wrist measurement device :-)
    Yes they have their issues, major one is that any movement distorts the data a lot. However when sitting still I'd say in principle there is no reason for them to not work, the beats are there in the data to see, it is no magic (unlike blood pressure or other stuff). Also in my case all other devices basically agreed what my pulse is +-1 it was only Bangle2 that was off. Yesterday I retried again with other devices (ID130Plus HR, Kospet DK08, ID107HR Plus all with their original firmware) and it was quite the same, once I was not moving and gave it like 5-10 seconds they all stabilized on some number +-1 and slowly drifted as my pulse changed and bangle2 was mostly lower by ~10. I tried to arrange some photo/video but then gave up, it is hard to keep two hands still with all displays visible and make a photo :-)

    BTW it feels to me that initially the difference is not so high but once stuff settles after few seconds Bangle2 drifts down and stays there. It was also interesting that the confidence varies even if sitting still, I see nice regular bumps drawn and then it draws basically flat line and then it 'refocuses' and is OK again. Can't match it to my movements (tried to not move at all of course). And it is off by ~10 even when I see those nice regular bumps (and confidence 100%).

    I used the Heart Rate Monitor (v0.11) app
    https://github.com/espruino/BangleApps/tree/master/apps/hrm
    FW was 2v17.109 http://www.espruino.com/binaries/travis/d7e760bc7896eb15a875d5ea2c43dfa8900643e6/

    The most interesting to me is that one of the watches is Q3 = same hardware as Bangle2 with firmware that may even have same HR library linked inside. I also tried to switch hands of course.

  • Stupid question, but have you removed the protective film from the HRM? That could be messing readings up a bit

  • I don't know for sure but I think it is not there, here is photo of the back https://ibb.co/pjHdsYN This is the device I got initially from you and runs Espruino, I have another one bought directly from SMA (later in the same year) still running original firmware. Both are probably same old "pre-kickstarter" models without hole and older VC31.

    So you don't see it when trying two devices - one with Espruino with Heart Rate Monitor (v0.11) app and one with SMA firmware on each hand?

  • The picture is too blurry, but either you have the protective film or the window is very scratched. It happened to me that I used it without peeling it for my first run. About the revision of the device, mine is from January 2023, so maybe that's the cause of the discrepancy. Gordon, is it possible that the proprietary firmware for VC31 and VC31B should be different?

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Bangle.js 2 Cutting Edge - new heart rate algorithm

Posted by Avatar for Gordon @Gordon

Actions