Heart Rate Variability with the Bangle.js/Espruino

Posted on
  • Couldn't see this implemented anywhere so I've put together an app that can collect hrm data over ~20 seconds and attempts to report HRV on the Bangle.JS. More details in the GitHub repo. There's 1 issue where it seems to try processing the data twice but it doesn't break anything - I think I'm just not handling the hrm event quite correctly atm.

    https://github.com/jabituyaben/Espruino-­HRV

  • This is great! Which function seems to be getting called twice? I could take a look...

    Would you be ok with adding this as an app in the Bangle.js apps repo?

    Do you think the upscaling is really required? I guess I wonder whether it's actually giving you real accuracy or just the illusion of it.

    If you're just trying to find when the peaks are I bet there's a way to estimate the time of a peak with subsample accuracy, for instance:

    // looks pretty much middle of sample
    *****
    **********************************
    *****
    
    // you could be pretty sure this one was halfway
    *****
    **********************************
    **********************************
    *****
    

    Also, if you really needed it I could add an option to raise the HRM poll rate.

  • The function seems to be behaving normally now, I changed a couple of things so it might have been something simple. Basically if you look at how I'm handling the HRM event I'm not sure if the way I'm calling the turn_off function is ideal and if there should be any process to wait for the hrm.raw data to be read in.

    Polling the data more often might be overkill but if you're able to create a different Event seperate from the HRM one or add that option I'd be interested to test it out at double the sample rate at 100Hz maybe and see if there's much of a difference - not done anything around HRV before so worth trying different approaches.

    Regardless the sample rate you'd always need to do some level of processing, and I don't think just a rolling average to smooth it out is enough because if you do too much of that you end up blurring the signal. So it's finding a compromise between doing a little bit of basic noise cancellation and then also a more intelligent interpolation between each point to define the peaks. The margins of error on HRV are quite narrow also, it's a very sensitive metric so slight errors in calculating peak gaps at 50Hz makes quite a significant difference to the reading you get.

    I've submitted a pull request to the app loader. Next update will be to add a simple log function so you can record and maybe plot relative changes over time.

  • Thanks! I've now merged it and it's live: https://banglejs.com/apps/#hrv

    Also filed an issue for the HRM poll interval at https://github.com/espruino/Espruino/iss­ues/1968

    I believe there should be a way to apply a filter on a rolling set of maybe 20 samples - so you could filter out any high or low frequency elements without actually doing any smoothing like you'd get from an average. I'd have to read up on it though as my signal processing knowledge is a bit lacking!

  • Awesome, Cheers. Basically I do the rolling average at the start which is just on the 50hz samples and then I used Bézier curves as I expand it-I tried other cubic spline interpolation with libraries in python on a sample dataset but i get the same kinda results. I actually do another slight rolling average after the interpolation but I’m not sure it’s needed yet so will play around and see what can be cut out. You can see line graphs and data in my GitHub repo to see what each stage does.

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

Heart Rate Variability with the Bangle.js/Espruino

Posted by Avatar for BenJabituya @BenJabituya

Actions