I thought I would explain how the current step counter works, where it is weak and where it could be improved.
I refer to the diagram below to the various stages.
TH: - the raw signal is taken scaled and a gating signal derived from the input.
I will describe why the gating process is needed shortly.
This has a lot of weaknesses and assumptions but I was unable to come up with
some simple code to do what was needed. Others may be able to help in this area.
F : The raw signal is passed onto the LOW PASS FILTER with a cut off frequency of 3hz if I remember. This is to take out high frequencies that will not be walking. Steps take beween 300-1300ms. I did a spreadsheet of ranges that is published in this thread. However the sampling frequency is only 12.5Hz and this in itself results in a filter that could be improved and is unable to
detect a signal greater than 6.25hz (Nyquest Sampling rule). The current filter is a version of the Oxford step counter filter.
The filter has an amplification effect on any signal. A small amount of noise will come out of the filter amplified with peaks and troughs that could look like steps - this has been observed with 2 people who have watches that phantomly count steps.
P : Peak detection. The undulating signal its checked for a Peak. The primary reason for this is that the input to the filter can not be guaranteed to be a blanced zero average signal. In many cases it is offset in the positive direction. This means that some low points will be above the zero line and will not cross a negative threshold value. Using peak detection avoids this issue. The peak detection is crude BUT it works. It was well tested with recordings and I sometimes walked around with a debug version of the step counter connected to the IDE running on my phone. It maybe does not look elegant or good code but it works in practice. I would not say this is the weakest link.
The primary weakness is the implementation of the Threshold Gating signal - I will cover the reasons for saying after describing the G: and S: phases.
G: The gate. The gate_open boolen value set by the TH code is used to decide do we send the detected PEAK onto the statemachine or send throw the PEAK away. The idea is that we are not just sending amplified noise to the state machine. It is also necessary because I swapped to PEAK detection shortly after switching to the Oxford filter. The previous filter would result in a more balanced sinewave like signal that would cross the zero line. However the previous BAND-PASS filter also head a 'Ringing' issue that mean't when you stopped moving the signal would echo a further 5 or more cycles that would be counted as steps. Having swapped to PEAK detection it was important to ensure we were not just sending a peak in the noise signal onto the state machine.
So returning to the TH Threshold detection.
The idea was to say 'are we generating a strong enough signal to warrant checking if we are walking.
There are various problems.
There is not a lot of differentiation between gentle walking and noise.
The changes in acceleration are actually quite small unless you are a STOMPER of a walker like the incredible hulk.
The raw signal can be unbalanced. In that you would expect the sine wave to cross the zero line but it is often offset by a positive value.
The code assumes that the raw signal will not be offset and only checks that the raw signal is greater that +TH or less that -TH where TH is the threshold value.
What is really needed is a way to detect the average and to offset the raw signal so that its undulations rise and fall around a zero line. Then what is being fed into the LOW PASS filter will be balanced and just be amplified.
OR there needs to be two thresolds one for the position range and one for the negative range. EG 14-18 positive but -5 for negative.
The gate needs to open and close quickly, we allow 3 samples in a row that are above or below the threshold to set the gate and for this to be reset after 3 samples below the threshold. If we extend the time take to decide if the signal is some movement or noise is too long then we could start miss counting more steps during that period. 3 samples is less than 1 second at a 12.5hz sample frequency.
if (v > RAW_THRESHOLD || v < -1*RAW_THRESHOLD) {
if (active_sample_count < N_ACTIVE_SAMPLES)
active_sample_count++;
if (active_sample_count == N_ACTIVE_SAMPLES)
gate_open = true;
} else {
if (active_sample_count > 0)
active_sample_count--;
if (active_sample_count == 0)
gate_open = false;
}
One approach to improving this would be have a POS_THRESHOLD and NEG_THRESHOLD and to run tests against the test harness to establish the best pair of values for both.
But we also need a lot more controlled samples from different people and different watches. @johan_m_o - would be good if you could record some samples of different distinct activies against your fitbit. 1 mile walking. driving etc.
Espruino is a JavaScript interpreter for low-power Microcontrollers. This site is both a support community for Espruino and a place to share what you are working on.
I thought I would explain how the current step counter works, where it is weak and where it could be improved.
I refer to the diagram below to the various stages.
TH: - the raw signal is taken scaled and a gating signal derived from the input.
I will describe why the gating process is needed shortly.
This has a lot of weaknesses and assumptions but I was unable to come up with
some simple code to do what was needed. Others may be able to help in this area.
F : The raw signal is passed onto the LOW PASS FILTER with a cut off frequency of 3hz if I remember. This is to take out high frequencies that will not be walking. Steps take beween 300-1300ms. I did a spreadsheet of ranges that is published in this thread. However the sampling frequency is only 12.5Hz and this in itself results in a filter that could be improved and is unable to
detect a signal greater than 6.25hz (Nyquest Sampling rule). The current filter is a version of the Oxford step counter filter.
The filter has an amplification effect on any signal. A small amount of noise will come out of the filter amplified with peaks and troughs that could look like steps - this has been observed with 2 people who have watches that phantomly count steps.
P : Peak detection. The undulating signal its checked for a Peak. The primary reason for this is that the input to the filter can not be guaranteed to be a blanced zero average signal. In many cases it is offset in the positive direction. This means that some low points will be above the zero line and will not cross a negative threshold value. Using peak detection avoids this issue. The peak detection is crude BUT it works. It was well tested with recordings and I sometimes walked around with a debug version of the step counter connected to the IDE running on my phone. It maybe does not look elegant or good code but it works in practice. I would not say this is the weakest link.
The primary weakness is the implementation of the Threshold Gating signal - I will cover the reasons for saying after describing the G: and S: phases.
G: The gate. The gate_open boolen value set by the TH code is used to decide do we send the detected PEAK onto the statemachine or send throw the PEAK away. The idea is that we are not just sending amplified noise to the state machine. It is also necessary because I swapped to PEAK detection shortly after switching to the Oxford filter. The previous filter would result in a more balanced sinewave like signal that would cross the zero line. However the previous BAND-PASS filter also head a 'Ringing' issue that mean't when you stopped moving the signal would echo a further 5 or more cycles that would be counted as steps. Having swapped to PEAK detection it was important to ensure we were not just sending a peak in the noise signal onto the state machine.
So returning to the TH Threshold detection.
The idea was to say 'are we generating a strong enough signal to warrant checking if we are walking.
There are various problems.
There is not a lot of differentiation between gentle walking and noise.
The changes in acceleration are actually quite small unless you are a STOMPER of a walker like the incredible hulk.
The raw signal can be unbalanced. In that you would expect the sine wave to cross the zero line but it is often offset by a positive value.
The code assumes that the raw signal will not be offset and only checks that the raw signal is greater that +TH or less that -TH where TH is the threshold value.
What is really needed is a way to detect the average and to offset the raw signal so that its undulations rise and fall around a zero line. Then what is being fed into the LOW PASS filter will be balanced and just be amplified.
OR there needs to be two thresolds one for the position range and one for the negative range. EG 14-18 positive but -5 for negative.
The gate needs to open and close quickly, we allow 3 samples in a row that are above or below the threshold to set the gate and for this to be reset after 3 samples below the threshold. If we extend the time take to decide if the signal is some movement or noise is too long then we could start miss counting more steps during that period. 3 samples is less than 1 second at a 12.5hz sample frequency.
One approach to improving this would be have a POS_THRESHOLD and NEG_THRESHOLD and to run tests against the test harness to establish the best pair of values for both.
But we also need a lot more controlled samples from different people and different watches.
@johan_m_o - would be good if you could record some samples of different distinct activies against your fitbit. 1 mile walking. driving etc.
1 Attachment