# How to detect the Accelerometer is moving

I am using the MCU intergrade 3-axis accelerometer and set it on the bicycle. I want to detect the bicycle is moving or stop. But the vibration noise let my function failed.

Is anyone could share some information about accelerometer detect moving.

Thank you.

• Your filtering should already be handling vibrations. No filter? Add one. – Ignacio Vazquez-Abrams Feb 26 '18 at 2:36
• Perhaps the presence of vibrations will tell you that it's moving, and the absence that it's stopped? – tomnexus Feb 26 '18 at 3:33

## 3 Answers

Calculate the distance of the accelerometer vectors.

$L = \sqrt{x^2+y^2+z^2}$

You will have roughly one g active at all times due to gravity. So L should be about 1 when the bike is not moving, and something oscillating near 1 when you're moving.

So what you are really interested in is the vibrations caused by the moving bike, you are not interested in the long frequency gravity noise. This means that a high pass filter will give a small value, near 0.

The simplest high pass filter would be something like this:

L_HP = L-L_t1;
L = L_t1;

• L will be according to the equation above
• L_t1 will be the previous value of L
• L_HP will contain information about the vibrations without any offset

And then all you need is an if statement to decide what noise that stems from riding a bike or from all other unwanted noise.

if(L_HP>0.1){
//We've detected that the bike is moving
}


But as the vibrations go back and forth, the if statement will go true and false for small moments when we actually drive it, so you will need some timer that gets activated every time we detect that the bike is moving. So a timer for like 1 second should be enough. If you can, use actual timers that comes with the microcontrollers, I will write pseudo code so you get the gist of it.

So all in all, this is the idea of how it can be done.

/*initiation*/{
float x = 0;
float y = 0;
float z = 0;
float L_HP = 0;
float L = 0;
float L_t1 = 0;
int timer=0;
}

/*major loop of the microcontroller*/{

L = sqrt(x*x+y*y+z*z);
L_HP = L-L_t1;
L = L_t1;

if(L_HP>0.1){//0.1 means g force of 0.1, you will have to
//change this threshold to something that you prefer.
timer = 10000;//Or some value that equals to 1 second
}

if(timer==0){
//We're not moving any more
}else{
//We're moving
timer -= 1;
}
}


If calculating the L variable takes too much time, then just use L = abs(x) + abs(y) + abs(z), it won't be as accurate, but it will make the code run much faster.

It's hard to give specific help when you haven't shared the code, the microcontroller, the programming language, the problems you've actually encountered. But this general information should suffice, if it doesn't, then udpate your question and hope that someone else will come along.

Good luck.

• Hi Harry, I am sorry about provide not enough information for this question. I use BMA250E accelerometer and MCU is cortex-m0. I read the BMA250E via SPI and I get the xyz raw datas. the BMA250E initial is +/-16G so I calculate each axis raw datas like is: unsigned int x_axis;//the axis data is 10bit float xg; x_axis &= 0x3FF; if( x_axis > 511 ){ x_axis -= 1023;//data will between +32~-32 } xg = (float)x_axis/32;//x-axis energy and other axis also. When I got the 3 axis g data then follow your formula. – vk8051 Feb 27 '18 at 3:56
• L = sqrt(xgxg+ygyg+zg*zg); ...... The result is much hard to reach. I need moving very fast the L_HP will > 0.1 If I reduce the L_HP vaule the vibrate will trigger it. Thanks you – vk8051 Feb 27 '18 at 4:05

It's simple - you probably can't.

Accelerometers cannot distinguish between any uniform velocity, including zero. By definition, uniform velocity of any magnitude has zero acceleration.

IF you can determine when the accelerometer is at rest (for instance, as tomnexus commented, by looking for the absence of noise), then you can, in principle, integrate acceleration to get velocity.

On the other hand, if the noise you are referring to is accelerometer noise which is produced when the accelerometer is stationary, you are probably out of luck. You can integrate the signal and let the noise (more or less) average out, but that will only work is the average signal is significantly higher than the drift spec of the accelerometer. Without knowing more, there is no way of telling if you have a chance.

• Absolutely correct. That said, if the accelerometer were on the pedal... Of course, this tells you when the bike is being pedaled, which is a bit different from telling one when the bike is stationary or moving. – Scott Seidman Feb 26 '18 at 18:45
• If it were on the wheel, off-axis, now there's a promising solution (one that requires slip rings, some clever mount, or wireless comms) – Scott Seidman Feb 26 '18 at 18:47

The most reliable way would be to put the accelerometer in a fixed position on the inside of the wheel rim. At least one axis would vary sinusoidally around $\pm 1g$, as it goes from right side up to up side down because of wheel rotation. You'd need a slip ring to keep your wires from twisting, unless it was in a stand-alone module. Wireless communication would also be a viable option.

In fact, your velocity would be a linear function with the frequency of the sine wave.

• If you go this way, though, you may as well just use a reflective photointerrupter on the frame near the wheel, and a few mirrors on the spokes. Much simpler. You'd still get velocity info, and wouldn't need slip rings. – Scott Seidman Feb 26 '18 at 20:20
• Thanks you. I will keep try and find the answer for this application. – vk8051 Feb 27 '18 at 4:10
• and the accelerometer position is under cushion and detect bicycle form moving to stop then light on the LED. that's all. I know if I set the wheel hub it can detect much easy. any way thanks again. – vk8051 Feb 27 '18 at 4:22