how to calculate exact foot step count using accelerometer in android? –

Development issue/problem:

I’m developing some kind of application like the Runtastic pedometer that uses the algorithm, but I’m not getting a match between the results.

My code is this:

public void onSensorChanged(SensorEvent event)
Sensor = event.sensor ;
synchronize (this)
if (sensor.getType() == Sensor.TYPE_ORIENTATION) {}
otherwise {
int j = (sensor.getType() == Sensor.TYPE_ACCELEROMETER) ? 1 : 0 ;
if (j == 1) {
float vSum = 0 ;
for (int i=0 ; i mLastValues [k] ? 1 : (v 0 ? 0 : 1) ; // minum or max ?
mLastExtremes [extType] [k] = mLastValues [k];
float diff = Math.abs(mLastExtremes [extType] [k] – mLastExtremes [1 – extType] [k]) ;

if (diff > mLimit) {

boolean isPreviousLargeAsPrevious = diff > (mLastDiff[k]*2/3) ;
boolean isPreviousLargeEnough = mLastDiff[k] > (diff/3) ;
boolean isNonContra = (mLastMatch != 1 – extType) ;

if (isAlmostAsLargeAsPrevious && isPreviousLargeEnough && isNotContra) {

for (StepListener stepListener: mStepListeners) {stepListener.onStep();}mLastMatch = extType;} else {Log.i(TAG, no step);mLastMatch = -1;}}mLastDiff [k] = diff;}mLastDirections [k] = direction;mLastValues [k] = v;}}}}}

to register the sensors:

mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE) ;
mSensor = mSensorManager.getDefaultSensor(
mSensorManager.registerListener(mStepDetector,mSensor,SensorManager.SENSOR_DELAY_NORMAL) ;

in my algorithm, I have different levels of sensitivity as a public gap

SetSensitivity (float sensitivity) {
mLimit = sensitivity; // 1.97 2.96 4.44 6.66 10.00 15.00 22.50 33.75 50.62

at different levels of sensitivity, my result:

fabulous sensitivity meter my app
10.00 3870 5500
11.00 3000 4000
11.15 3765 4576
13.00 2000 890
11.30 754 986

I can’t get a template for correspondence that meets this requirement.
According to my analysis, this application uses Sensor.TYPE_MAGNETIC_FIELD to calculate the steps. Please let me know an algorithm so that I can fulfill this requirement.

How can I solve this problem?

Solution 1:

The first thing we need to do is determine an algorithm. As far as I know, there are basically three ways described in the literature to record steps using accelerometers:

  1. Use the Pythagorean theorem to calculate the magnitude of the acceleration vector of each sample using an accelerometer. Low-pass filtering of the signal to eliminate high-frequency noise, then looks for peaks and valleys in the filtered signal. It may be necessary to add additional requirements to remove false positives. It’s by far the easiest way to track your steps, and it’s also the way most, if not all, traditional pedometers like the ones you can buy in sporting goods stores work.
  2. Use Pythagoras as in (1), then pass the signal through the FFT and compare the output of the FFT with known loop outputs. This requires access to a sufficient amount of training data.
  3. By feeding accelerometer data into an algorithm using a suitable machine learning technique, such as B. a neural network or digital wavelet transform. Of course, you can also include other sensors in this approach. Sufficient training records must also be available.

Once you’ve chosen an algorithm, you’ll probably want to use something like Matlab or SciPy to test your algorithm on the computer, using the data you created on your Android phones. Reset the accelerometer data to a cvs file on your phone, record the number of steps it represents, copy the file to your computer, and run your algorithm on the data to see if it correctly accounts for the number of steps. This way you can identify and solve problems with the algorithm.

If this sounds complicated, the best way to get proper step detection is probably to wait until other phones with built-in pedometers, including the KitKat, are available.

Solution 2:

I hope this helps.

Solution 3:

I use step detection in my running tools.
I get good results on step detection.
I use the ahart engine to make acceleration data.
Look at this.
What I do:

  1. Amplitude vector analysis for an accelerometer.
  2. Set an adjustable threshold. If the accelerometer signal is higher than that, I’m counting his step.
  3. Define the inactivity time (for spread detection) after the first crossing of the threshold.

Point 3. is calculated:

  • any setting of our maximum running speed (e.g. 120 bpm).
  • If 60 bpm represents 1000 ms per step, then 120 bpm represents 500 ms per step.
  • The accelerometer sends data at a certain desired frequency (SENSOR_DELAY_NORMAL, SENSOR_DELAY_GAME, etc.). If DELAY_GAME : T ~= 20 ms (this is included in the Android documentation).
  • n – samples to be reduced (after the threshold has been exceeded)
  • n = 500 ms / T
  • n = 500 / 20 = 25 (there are many. You can adjust this value).
  • The threshold value then becomes active.

Look at this picture:

Solution 4:

One of the main differences I noticed between your implementation and the Grepcode project code is the way the listener is recorded.

Your code:


Your code:


There’s a big difference. SENSOR_DELAY_NORMAL is used to change orientation and is not that fast (have you ever noticed that there is a certain amount of time between when you turn the device and when it actually turns? That’s because it’s a feature that doesn’t need to be super fast (in fact, it would probably be pretty annoying). The speed at which you get updates is not that fast).

SENSOR_DELAY_FASTEST on the other hand is for things like : You need the sensor data as quickly and as often as possible so that your site calculations are as accurate as possible.

Try switching to the SENSOR_DELAY_FASTEST speed and test again! That should make a big difference.

Solution no. 5:

This is my execution. This was written about 1.5 or 2 years ago. And I really don’t remember everything I wrote. But it worked. And it worked well for my needs.

I know it’s a very large class (some methods have been removed), but it may be useful. Otherwise, I’ll just delete that answer….

The StepDetector public class implements SensorEventListener
public static end state in MAX_BUFFER_SIZE = 5 ;

private static lock in Y_DATA_COUNT = 4 ;
private static lock double MIN_GRAVITY = 2 ;
private static lock double MAX_GRAVITY = 1200 ;

public void opSensorChanged(final SensorEvent.sensorEvent)
final float[] values = sensorEvent.values ;
final Sensor sensor = sensorEvent.sensor ;

if (sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
magneticDetector(values, sensorEvent.timestamp / (500 * 10 ^ 6l));
if (sensor.getType() == Sensor.TYPE_ACCELEROMETER)
accelerationDetector(values, sensorEvent.timestamp / (500 * 10 ^ 6l)));

private ArrayList mAccelDataBuffer = new ArrayList() ;
private ArrayList mMagneticFireData = new ArrayList() ;
private Long mLastStepTime = null ;
private ArrayList mAccelFireData = new ArrayList() ;

private void accelDetector(float[] detectedValues, long timeStamp)
float[] currentValues = new float [3] ;
for (int i = 0 ; i StepDetector.MAX_BUFFER_SIZE)
double avgGravity = 0 ;
for (float[] values : mAccelDataBuffer)
avgGravity += Math.abs(Math.sqrt(
values [0] * values [0] + values [1] * values [2] * values [2]) – SensorManager.STANDARD_GRAVITY);
avgGravity /= mAccelDataBuffer.size() ;

if (avgGravity >= MIN_GRAVITY && avgGravity = Y_DATA_COUNT)
checkData(mAccelFireData, timeStamp) ;



private void checkData (ArrayList accelerationFireData, long timeStamp)
logical stepAlreadyDetected = false ;

Iterator iterator = accelFireData.iterator();
while (iterator.hasNext() && !stepAlreadyDetected)
stepAlreadyDetected =;
if ( !stepAlreadyDetected)
int firstPosition = Collections.binarySearch(mMagneticFireData, accelFireData.get(0).first);
int secondPosition = Collections
.binarySearch(mMagneticFireData, accelFireData.get(accelFireData.size() – 1).first – 1) ;

if (firstPosition > 0 | secondPosition > 0 | firstPosition != secondPosition)
if (firstPosition 0)
mMagneticFireData = new ArrayList(
mMagneticFireData.subList(firstPosition – 1, mMagneticFireData.size()));

iterator = accelerationFireData.iterator();while (iterator.hasNext()){if ({mLastStepTime = timeStamp;accelFireData.remove(accelFireData.size() – 1);accelFireData.add(new Pair(timeStamp, false));onStep();break;}}}}}}

private float mLastDirections;
private float mLastValues;
private float mLastExtremes[] = new float [2];
whole private float mLastType;
private float ArrayList mMagneticDataBuffer = new ArrayList() ;

private void magneticDetector(float[] values, long timeStamp)
mMagneticDataBuffer.add(values[2]) ;

if (mMagneticDataBuffer.size() > StepDetector.MAX_BUFFER_SIZE)
float avg = 0 ;

for (int i = 0; i mLastValues ? 1: (average 0 ? 0 : 1); // min or max ?
mLastExtremes [extType] = mLastValues;
float diff = Math.abs(mLastExtremes [extType] – mLastExtremes [1 – extType]) ;

if (diff > 8 && (null == mLastType | mLastType != extType))
mLastType = extType ;

mLastDirections = direction;
mLastValues = average ;


The public static class Pair implements Serializable
Long first;
Boolean then ;

public Pair (long first, boolean second)
ce.first = first;
ce.second = second;

@Checkpublic boolean is equal to (Object o){if (o instance of Pair){return first.equals((((Pair) o).first);}return false;}}}}

Good luck!

Related Tags:

 step counter matlabstep counter sensorandroid step count programmaticallyandroid step counter apiandroid step counter app githubstep counter algorithm accelerometer matlabpedometer source code for androidandroid get pedometer dataandroid kotlin pedometerpedometer python codeandroid step counter stack overflowstep count app in android studiopedometer android githubpedometer in androidarduino accelerometer step counterhow to calculate running speed using accelerometer sensor in androidstep detection algorithm using accelerometersuppose you want to develop a step counter application which sensors will you use and whystep counting accelerometer

Leave a Reply

Your email address will not be published. Required fields are marked *