I am developing an application for Android that is supposed to check whether the device is lying still. This has to work when i lay the device on a flat surface. This also has to work when the device is lying still on either side of the device. While I am holding the device very still in my hand the check should fail. Because the small movement from your hand/arm should be enough to detect movement.
I've tried this over and over but i still seem to fail in doing so. What usually happens is that the data i receive from the SensorEventListener
is always fluctuating heavily. The data below represents the data i get back from the device while lying still on a flat surface.
0.07366191
0.056904275
0.034122672
0.047471035
0.080519415
0.07816742
1.2434766
0.34602648
0.25965866
0.52344894
0.14806636
I've tried the following:
- 10 second calibrate while lying flat on the table, storing that calibrated value and use it as threshold.
- Fixed thresholding based on
Math.sqrt(ax * ax + ay * ay + az * az)
results. - Using either the
TYPE_LINEAR_ACCELERATION
or normal type. - Using gravity (9.8) as threshold.
At this point I don't really know what to do anymore. I really hope someone can help me out. Thanks in advance.
I'm not sure what kind of values the Android accelerometer outputs, but if it's like the other accelerometers I've worked with, it will give you regular samples of the number of Gs or milliGs which the device is feeling in the x, y, and z directions (where the x-, y-, and z- axis are fixed with respect to the device- usually you can find a guide for the accelerometer which will tell you which way is which).
For example, an accelerometer lying flat is experiencing one G upwards. If the output is in milliGs, it will continuously output (0,0,1000). If you flip it over, it will output (0,0,-1000).
There will be a little noise, so you will see values like (-2,5,998), (1,0,1001), etc. instead of (0,0,1000). One way to filter that noise is the remember the last few samples and average them, then use the average instead of the raw data to do the decision making.
For the decision, you could try checking if the z-component of the G readings is within, say, 20 units away from 1000 or -1000.