Better Pedometer - HELP NEEDED!

Posted on
Page
of 3
Prev
/ 3
Next
  • Here you go. This log is wrist twisting through 90 degrees and back, on my right hand. Maybe 30 wrist twists at the rate of 1 per second in this sample.


    1 Attachment

  • Is it actually better than the old step counter? If not, I might as well revert it.

    Thanks for the log - However...

    Maybe 30 wrist twists at the rate of 1 per second in this sample.

    Is that something you normally do? I don't really see how I'm supposed to filter this out if it's at a rate that's the same as walking?

    I could be wrong but I think if you did this to most step counters, they would count steps as well.

    I can't really afford to spend too long on this, so I've put my current code with test harness up at https://github.com/gfwilliams/step-count­

    Maybe someone will have a bit more success than me

  • Is it actually better than the old step counter? If not, I might as well revert it.

    Gut feel, I think it is improved, but still quite a way off being able to say we have reliable step counter. I was going to give a good test on a known 1.03mile route I have previously used many times to test step counters - but when I saw I was logging 1000s of steps sat at a desk I thought it would be better to see if that got sorted first. I may try it with the activepedom as well, assuming it is still compatible with that widget. ActivePedom has the X steps in X seconds feature which effectively takes out any counting when sat still.

    Is that something you normally do? I don't really see how I'm supposed to filter this
    out if it's at a rate that's the same as walking?

    No. Apologies - maybe that sample was not that great an idea. Maybe I should have done it just 3 times in 30 seconds.

    I could be wrong but I think if you did this to most step counters, they would count steps as well.

    I have an AmizFit Bip and an old FitBit and neither count steps on reaching across a desk or rotating a wrist, maybe the odd time but not consistantly to the point that by the end of the day when my AmizFit would say 1200 steps and the bangle says 8000+ today.

    I can't really afford to spend too long on this

    Yeah - I understand, this will be one of many things wanting attention.

    Maybe its time to have a competition to see if anyone can get a better version. I might have a go myself if its not to hard a jump to get into. I had a quick look at the link. What is the lifcycle of trying to improve this ? EG - do you just add samples until you get better figures at the end or would the C need to be adjusted etc ? How would one actually test this for real on a Bangle ? Is there a way to patch the firmware or would you have to build your own firmware from the source etc and then use the DFU loader etc. I think real world testing is needed here - I know all too well how time consuming that is from walking outside waiting for a GPS fix etc.

    Having a good enough step counter is an essential base level feature of any smartwatch though. I would rather Bangle became my default smartwatch than have to wear a second one to get an accurate step count etc.

    Maybe float the idea of a competion and see if there is much enthiusiasm for it ?

  • neither count steps on reaching across a desk or rotating a wrist

    My point was just that if you repeatedly rotate your wrist once every second, they may well start to count steps. But yes, normal reaching/rotating is something that obviously needs filtering out :)

    Maybe its time to have a competition

    Yes, totally! Is anyone interested in this? I had been considering it... I guess the thing to do would be for us to ensure we have a really good representative set of data in https://github.com/gfwilliams/step-count­ and then see who can get lowest.

    I now have a bunch of what will probably be the 'new' Bangle.js (the SMA Q3) and I could send one of those out to the winner... Or maybe something else?

    What is the lifcycle of trying to improve this ?

    Realistically it's a matter of changing the C code. It's really pretty basic at the moment.

    How would one actually test this for real on a Bangle ?

    Right now on the Bangle there's a specific step counter file:

    https://github.com/espruino/Espruino/blo­b/master/libs/misc/stepcount.c

    So you'd just have to copy/paste into there, recompile, and DFU. Realistically the step-count repo above should just use that file directly though, then you could just move the file across when you were happy with it.

    You actually could just include it with Inline C though, so you could tweak it quickly on real hardware without recompiling. If there's interest I could paste up an example of how to do that?

    While obviously it helps to do it on real hardware, there's a lot to be said for doing it 'offline' just because you can run over the same data over and over, look at a graph, see exactly what's going on and why it is/isn't working.

  • the 'new' Bangle.js (the SMA Q3)

    This sounds interesting, tell me more. I was wondering if there would be a another smartwatch hardware that would run Espurino. I will google it. I would love something like the form factor of the AmizFit Bip if that were possible. It has some advantages. The charging connector is not magnetic and interferes less with compass calibration. Its smaller. Battery life is very good. Having said that I curently have that test Bangle you sent me not needing a recharge after 300+ hours.

    Found this.

    https://hackaday.io/project/175577-hacka­ble-nrf52840-smart-watch

    Looks really cool. When are these going on sale in the Bangle Shop, can you place advance orders. Only snag for me is that is another GPS data sheet to grapple with. Nice looking watch though.

  • you actually could just include it with Inline C though, so you could tweak it quickly on real >hardware without recompiling. If there's interest I could paste up an example of how to do that?

    Sounds like a great option. I think having to recompile the firmware might put a few off.

    If you can write up the basic process loop of what you do to iterate round the process. I could have a go. I've done a lot of C in the past but nothing todo with filters or machine learning etc. I still have a few more enhancements and bug fixes to do to 'kitchen combo' though.

    Is there a way to simulate this in javascript first, run on the bangle and then translate it to C ?

  • Yes, that Hackaday link is basically all the info I have on the Q3 at the moment, and you can build Espruino (although I'm not doing automatic builds at the moment). Basically what we're missing is the heart rate sensor right now (since I have to reverse engineer it all). I'm hoping to get them in the shop 'soon' - hopefully within the next month - but they're still very much beta as I have to decide exactly what to do about making existing apps compatible (the screen/buttons are different).

    GPS is a pain though - it doesn't seem to be quite as good as the Bangle's, and as you say it's a completely different command set too.

    Is there a way to simulate this in javascript first,

    Yes - it's not a very difficult algorithm (there is no machine learning), so this is probably what I should have actually done at the start. Try:

    // values for debug plotting
    var lastAccel = 120;      // BLUE
    var lastAccelFilt = 120;  // YELLOW
    var lastThresh = 120;     // RED
    
    var filter_taps = new Int8Array([ -2, 4, 4, 1, -1, 0, 2, -3, -12, -13, 2, 24, 29, 6, -25, -33, -13, 10, 11, -1, 3, 29, 41, 4, -62, -89, -34, 62, 110, 62, -34, -89, -62, 4, 41, 29, 3, -1, 11, 10, -13, -33, -25, 6, 29, 24, 2, -13, -12, -3, 2, 0, -1, 1, 4, 4, -2 ]);
    var history = new Int8Array(filter_taps.length);
    const stepCounterThresholdMin = 1500;
    const stepCounterAvr = 1;
    
    /// Theshold in filtered acceleration for detecting a step
    var stepCounterThreshold = stepCounterThresholdMin;
    /// has filtered acceleration passed stepCounterThresholdLow?
    var stepWasLow = false;
    
    function onAccel(a) {
      // scale to fit and clip
      var v = ((a.mag-1)*8192)>>5;
      // save
      history.set(new Int8Array(history.buffer,1));
      history[history.length-1] = E.clip(v, -128, 127);
      // do filtering
      var accFiltered = E.convolve(filter_taps, history, 0) >> 2;
    
      /*
      // Simple average-based threshold
      if (stepCounterAvr) {
        var a = accFiltered;
        if (a<0) a=-a;
        stepCounterThreshold = (stepCounterThreshold*(32-stepCounterAvr­) + a*stepCounterAvr) >> 5;
        if (stepCounterThreshold < stepCounterThresholdMin)
          stepCounterThreshold = stepCounterThresholdMin;
      }*/
      
      // Set threshold based on the 'middle' history item - the one making the big spikes.
      // Try and scale it appropriately
      var a = history[32] * 55; 
      if (a<0) a=-a;
      if (a > stepCounterThreshold) 
        stepCounterThreshold = a;//(stepCounterThreshold+a) >> 1;
      stepCounterThreshold -= 48;
      if (stepCounterThreshold < stepCounterThresholdMin)
        stepCounterThreshold = stepCounterThresholdMin;  
      
      // check for steps
      var hadStep = false;
      if (accFiltered < -stepCounterThreshold) 
        stepWasLow = true;
      else if ((accFiltered > stepCounterThreshold) && stepWasLow) {
        stepWasLow = false;
        hadStep = true;
      }
    
      // output data
      g.scroll(0,1);
      var n;
      
      if (accFiltered < -stepCounterThreshold)
        g.setColor("#0ff").fillRect(0,0,8,0);
      if (accFiltered > stepCounterThreshold)
        g.setColor("#0ff").fillRect(232,0,240,0)­;
      
      n = 120+v;
      g.setColor("#00f").fillRect(lastAccel,0,­n,0);
      lastAccel = n;
      n = 120+(accFiltered>>6);
      g.setColor("#ff0").fillRect(lastAccelFil­t,0,n,0);
      lastAccelFilt = n;
      n = 120+(stepCounterThreshold>>6);
      g.setColor("#f00").fillRect(lastThresh,0­,n,0);
      lastThresh = n;
    
      if (hadStep) {
        g.setColor(-1).drawString("STEP",60,0);
      }
    }
    Bangle.on('accel',onAccel);
    Bangle.setLCDTimeout(0);
    
    

    On the graph that's displayed, blue is the actual accelerometer data, yellow is the filtered data, and red is the threshold.

    The issue is really the filter...

    • It's good in that repeated inputs within the frequency range get amplified, so are easy to detect
    • However a single big acceleration input will 'ring' - it generates oscillations in the desired frequency.

    So if using the filter actually turns out to be a good idea, we basically need a way of only passing through steps when the filter is producing values that are all the same (ish) amplitude, and not passing through the outliers.

  • I was wondering if there would be a another smartwatch hardware that would run Espurino. I will google it.

    Yes definitely try googling if you wonder about such things :-) Or even look around this forum. There are plenty of watches running Espruino. Some even run some Bangle apps.

  • I'm hoping to get them in the shop 'soon' - hopefully within the next month - but they're still very much beta

    Even the HW was beta, looks like newer ones that some guys received later have small hole and pressure sensor works much better with that. Without hole the pressure inside just goes up with the temperature and does not reflect air pressure very much.

  • looks like newer ones that some guys received later have small hole

    The new ones I have have the hole too. I hope they've done something about waterproofing!

    The software they ship with definitely needs some work. Even when 'off' they are advertising with Bluetooth, so as a result it's a bit tricky trying to use Bluetooth right now (with 100 SMA Q3 entries every time I try to connect with the Web IDE!).

  • There is that offline/silent/powersaving mode? you swipe down and one of the icons turns off bluetooth and everything and puts on some simple clock. Also there is power off in the hidden menu. When in settings menu hold button until 4 digit code entry pops up and then 2020 is power off and 2019 is test menu which also has power off menu. Hopefully it is not advertising in that off mode.

    But anyway doing this with 100 watches must be a pain if they come like this from the factory.

  • @Gordon - Good news with firmware 2v09.9, and step counting.

    I did a test walk this morning 1.53 miles
    AmizFit Bip: 3057 steps
    Bangle: 3068 steps

    I did a similar walk yesterday and got very close results but did not write them down before midnight. I appreciate that 1 test result does not make strong evidence - on the other hand I have been routinely testing the step counter widgets (with different settings) across multiple walks since I purchased my Bangle in December 2020. I have never managed to get within 400 steps of the AmizFit bip - so to be within 11 steps is a brilliant result.

    I have been using the ActivePedom Widget with the following settings:

    Step Threshold 5: Active Res (ms) 5000. In other words only register steps after 5 steps in 5 seconds. All other settings in ActivePedom left as default.

    I think if you produced a firmware with this additional threshold built in you would have a pretty accurate step counter. I'd be happy to do some real world testing.

  • I installed your code to try and undertand how this works. I can see the ringing effect that you point out. As per my post above I think all that is a needed is a two filter approach. This existing filter in your code that detects potential steps. The 2nd filtering stage ensures that 5 steps in 5 seconds are detected before counting them as step events. The step count will always be 5 seconds behind but I think that is ok. I have noticed (external observations as a user only) that FitBits and AmizFit Bips both appear to have a threshold before they will start registering steps. From a pure technical perspective that might not be the best theoretical approach but it appears to be working from a pragmatic point of view. Worth a try and get some feedback from others maybe ?

  • some fitness trackers I tested ignore few steps if the activity does not continue but I think there was no time limit like the 5 seconds you mentioned. So first few steps are delayed until that threshold (e.g. 10 continuous steps) is reached, but then it adds it all and it continues with real number, not delayed

  • Just to be clear - you're using a new firmware (with the new step counter code), but then just having that filter for the amount of steps in a set time?

    Interestingly I had looked at that before, but the lack of filtering meant you could get a bunch of steps very close together. The addition of the filter probably makes doing something simple like that quite a good approach.

    I guess there is also the option of just adding 5 steps to the step count once we've had 5 steps in a row as well?

  • Hi @Gordon - apologies been out of contact for a few days. Yes - using v209.9 step code and the activepedom widget with the thresholds set to 5 steps in 5 seconds. This seems the most accurate I have seen so far. Just want to check that doing this was / is a valid test case - what do you think ? To be clear I have not written any code. I am assuming that what comes out of the v2.09.9 firmware is the step count code and the ActivePedom is effectively acting as a second filter, this may not be the case though. Thats the tests that I have done. I think it might be enough to go down to 3 steps in 3 seconds and still be enough to get rid of miscounting of slight movement when moving arms, wrist twisting when sat still etc.

  • Thanks - this sounds really promising. As far as I can tell, activepedometer really does just work off the 'step' event so acts as a second filter. The other filtering it does shouldn't have much effect, so just the 3 steps in 3 seconds thing sounds very easy to implement.

  • I can do another 1.5 mile test with those settings later in the week. Will report back.

  • but they're still very much beta as I have to decide exactly what to do about making existing apps compatible (the screen/buttons are different).

    I've been thinking about this. I think the best way would be to say, the screen is different size, its got one button, its a different watch but same API, you will have to port your App. Hopefully the original authors of the Apps would do the porting. The thing with a one button watch is that the whole way of interacting with an App will be totally changed. With it being a full touch screen I would expect use of Up, Down, Left, Right swipe would provide a lot more options for navigating round things.

    I'm definitely up for having a go at the low power GPS again. It was a lot of work but worth it. There were a few comments made about me stepping outside the house a lot to get a signal :)

  • Yes, that's definitely the direction I'm headed in!

    I'm planning on adding a simple UI/layout library that'll handle a lot of the common layouts I'm seeing in apps, and then I'll change a bunch of the most common/useful apps over to use that so that they can work on both Bangles (and maybe even Pixl.js too).

  • Quick update here - step counting on 'cutting edge' should be significantly improved now. I added the 'X steps in Y seconds' algorithm then trained it based on the recorded step count data I have, and we're getting far better accuracy than before now.

  • I'll download and flash the latest firmware.

  • Hi @Gordon - I have flashed 2.09.90. And have done some tests. I just want to check a couple of things. 1) All that is necessary is to uplift to the cutting edge firmware. 2) there is no need to configure anything. Not sure what X steps in Y seconds is though. Is it 5 steps in 5 seconds or 3 steps in 3 seconds. To test it I am just using the widpedom widget and using the getSteps() call.

  • 1) All that is necessary is to uplift to the cutting edge firmware.

    Correct, yes

    2) there is no need to configure anything. Not sure what X steps in Y seconds is though. Is it 5 steps in 5 seconds or 3 steps in 3 seconds.

    It's actually 6 steps in 6 seconds now. I updated https://github.com/gfwilliams/step-count­ so now it uses the exact Espruino step count algorithm, then brute-forced it on all the recorded data we had and that provided the best results. On average over all the 18 data files we have recorded, it's only 1.5 steps out per file - around 1%.

    To test it I am just using the widpedom widget and using the getSteps() call.

    That should be fine. Just don't use Active Pedometer as that applies extra filtering on top of the already filtered data

  • OK - its not good news I'm afraid. My test strategoy was to wear the Bangle and an Amafit bip from midnight onwards. Sleep with the watches on, go about my normal work day, mostly sat down, a couple of short walks of the dog etc. At 6pm I took both watches off and recorded the step count.

    Bangle: 9902 and Amazfit Bip: 4479.

    When I woke up in the morning the Bangle was on about 1200 steps to the Amizfit Bip 200 or so.

    The idea of testing recorded accelerometer samples against the C code is good, but something is making it not work out in practice. At the end of the day its only the field test result that counts.

    I like the javascript idea and might try and produce a widget out of the code you did.
    I looked at the javascript code and made a few comments and have some questions that I will post. Apologies in advance I have never done anything with digital filters before and there will be a bit of learning curve on some of the javascript.

    I have had a look at a couple of papers on step counting out of curiosity so might try out a few things. I'm away for a few weeks in July so progress might be slow.

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

Better Pedometer - HELP NEEDED!

Posted by Avatar for Gordon @Gordon

Actions