How to measure the tilt of the phone in XY plane using accelerometer in Android
Essentially, there is 2 cases here: the device is laying flat and not flat. Flat here means the angle between the surface of the device screen and the world xy plane (I call it the inclination) is less than 25 degree or larger than 155 degree. Think of the phone lying flat or tilt up just a little bit from a table.
First you need to normalize the accelerometer vector.
That is if g is the vector returns by the accelerometer sensor event values. In code
float[] g = new float[3];
g = event.values.clone();
double norm_Of_g = Math.sqrt(g[0] * g[0] + g[1] * g[1] + g[2] * g[2]);
// Normalize the accelerometer vector
g[0] = g[0] / norm_Of_g
g[1] = g[1] / norm_Of_g
g[2] = g[2] / norm_Of_g
Then the inclination can be calculated as
int inclination = (int) Math.round(Math.toDegrees(Math.acos(g[2])));
Thus
if (inclination < 25 || inclination > 155)
{
// device is flat
}
else
{
// device is not flat
}
For the case of laying flat, you have to use a compass to see how much the device is rotating from the starting position.
For the case of not flat, the rotation (tilt) is calculated as follow
int rotation = (int) Math.round(Math.toDegrees(Math.atan2(g[0], g[1])));
Now rotation = 0 means the device is in normal position. That is portrait without any tilt for most phone and probably landscape for tablet. So if you hold a phone as in your picture above and start rotating, the rotation will change and when the phone is in landscape the rotation will be 90 or -90 depends on the direction of rotation.
How to accurately detect when phone has been tilted back and forth in Android
You cannot use the z-value to detect the titling since the accelerometer value is given in term of device coordinate. You should use the change of inclinations instead (see How to measure the tilt of the phone in XY plane using accelerometer in Android)
How do I get the angle/degree of the phone with sensor/s?
I don't know if i understand your question ,but i think you want your app to calculate the angel of tilt only if the phone is in portrait ,first you need to take the value of mSensorEvent.values[0]
and in this case if the phone in stand state in will return 0
, tilt to right will be negative values from 1 to 9 ,and the left positive .
then you have to do all this just in case of mSensorEvent.values[1]
values between 9 and 7 for example (9 is perfect stand) . to ensure the the device in portrait position .
and if you need the degree angle values you can multiply the float value of mSensorEvent.values
by 10.
i hope this help you
UPDATE***
you can try this :
private boolean isLandscape;
@Override
public void onSensorChanged(SensorEvent mSensorEvent) {
float X_Axis = mSensorEvent.values[0];
float Y_Axis = mSensorEvent.values[1];
if((X_Axis <= 6 && X_Axis >= -6) && Y_Axis > 5){
isLandscape = false;
}
else if(X_Axis >= 6 || X_Axis <= -6){
isLandscape = true;
}
}
Head tracking angle using accelerometer
Measure just gravity orientation. there are two approaches I know of
1.use smooth (FIR) filter to filter out quick changes
- for example remember last N measurements
- and output their average
- this is easy and continuous but not precise
2.check for acceleration vector size
and ignore all measurements where it does not match the gravity
a=sqrt( ax^2 + ay^2 + az^2 )
if (fabs(a*scale-9.81)>0.1) ignore...where a is size of acceleration vector
- (ax,ay,az) is measured acceleration vector (local to your device)
- scale is scale of your accelerometer to convert a value to actual units like [m/s^2] or [N/kg]
- device accelerometers are usualy already in [g] so the scale is 9.81
- 9.81 is the gravity in the area of measurement
- 0.1 is accuracy of acceleration size check (change it to your needs)
- this approach is a bit slower
- and not continuous because during acceleration will not measure the output (can use last valid output)
- but it is much more precise
Now the formulas should work, from what I read your axises are
- x - up,down
- y - left,right
- z - forward,backward
- do not know the orientation so just negate output angle if i hit it the wrong way
- green is the gravity
- blue is measured values
red is your pitch angle (ang)
ang=asin(az*scale/9.81)
do not forget to avoid using asin with parameter out of range < -1.0 , +1.0 > !!!
Related Topics
Eclipse Error "Adb Server Didn't Ack, Failed to Start Daemon"
How to Programmatically Turn Off Wifi on Android Device
Calling Startactivity() from Outside of an Activity
Locationsettingsrequest Dialog to Enable Gps - Onactivityresult() Skipped
How to Avoid Soft Keyboard Pushing Up My Layout
Example Communicating with Handlerthread
Why Does the Google Play Store Say My Android App Is Incompatible with My Own Device
About "_Id" Field in Android SQLite
How to Measure the Tilt of the Phone in Xy Plane Using Accelerometer in Android
How to Check If an Activity Is the Last One in the Activity Stack for an Application
Android Support Repo 46.0.0 with Android Studio 2.3
How to Capture an Image and Store It with the Native Android Camera
Android Studio Says "Cannot Resolve Symbol" But Project Compiles
Difference Between Oncreateview and Onviewcreated in Fragment
Android: How to Make a Clickable Map Image with Each Country Producing a Different Action
How to Send an Email with a File Attachment in Android
Android Webview, How to Handle Redirects in App Instead of Opening a Browser