I testing the accelerometer output on 2 different devices(Elocity A7 and Archos 7 Home tablet) but the sensor seems to be giving different results. I have it programmed to set to landscape mode but the x and y axis seem to be the oppisite between the 2 devices. The x axis returns 10 when held perpendicular to the ground and the Archos X axis returns 0. The Elocity tablet is android 2.2 and the Archos is 2.1. Can someone point me in the right direction as how to get orientation from the accelerometer in sync between these 2 devices?
The accelerometer sensor is used to add intelligence into hand-held devices. The accelerometer can detect the orientation of the device which can be used to alert the hand-held device to update the image based on the sensor orientation data.
For determining a device's orientation, you can use the readings from the device's accelerometer and the geomagnetic field sensor.
Accelerometer detects acceleration in space. The reason why it will always detect an acceleration of 9.8m/s^2 downwards is because gravity is equivalent to acceleration in space. Orientation detects if your device's axis are rotated from the real-world; it detects tilts and and degrees from the magnetic North.
Smartphones and other mobile technology identify their orientation through the use of an accelerator, a small device made up of axis-based motion sensing. The motion sensors in accelerometers can even be used to detect earthquakes, and may by used in medical devices such as bionic limbs and other artificial body parts.
In fact, the accelerometer axises are relative to the default orientation of the device.
Here how to deal with it:
static void canonicalOrientationToScreenOrientation(
int displayRotation, float[] canVec, float[] screenVec)
{
final int axisSwap[][] = {
{ 1, -1, 0, 1 }, // ROTATION_0
{-1, -1, 1, 0 }, // ROTATION_90
{-1, 1, 0, 1 }, // ROTATION_180
{ 1, 1, 1, 0 } }; // ROTATION_270
final int[] as = axisSwap[displayRotation];
screenVec[0] = (float)as[0] * canVec[ as[2] ];
screenVec[1] = (float)as[1] * canVec[ as[3] ];
screenVec[2] = canVec[2];
}
This solution was provided by NVidia. Check their white paper about Android Accelerometer for more details.
just wanted to add something to Hartok's answer as I couldn't understand it at first...
I've rewritten the method to be:
public static float[] adjustAccelOrientation(int displayRotation, float[] eventValues)
{
float[] adjustedValues = new float[3];
final int axisSwap[][] = {
{ 1, -1, 0, 1 }, // ROTATION_0
{-1, -1, 1, 0 }, // ROTATION_90
{-1, 1, 0, 1 }, // ROTATION_180
{ 1, 1, 1, 0 } }; // ROTATION_270
final int[] as = axisSwap[displayRotation];
adjustedValues[0] = (float)as[0] * eventValues[ as[2] ];
adjustedValues[1] = (float)as[1] * eventValues[ as[3] ];
adjustedValues[2] = eventValues[2];
return adjustedValues;
}
Exactly the same thing, just with more user friendly variable names and I recreate the float internally because I needed it like that... Simply call this function, put in the getRotation and the event.values float array, check the values of its return float array and pick whatever number you prefer...
Hope this helps someone!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With