views:

2722

answers:

2

I'm wanting to detect the orientation of the iPhone at 45 degree increments. Ideally I'd like to be able to get the angle of orientation along any axis.

The detection I need to do is similar to how Trism for the iPhone flashes an arrow towards the current bottom position of the screen when orientation changes.

I have something coded up but really don't understand how the accelerometer readings work and could use a nudge in the right direction. My current code logs the current angle but even when the phone is flat I get readings varying wildly a few times a second.

- (void) checkOrientation:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration
{
    int accelerationX = acceleration.x * kfilteringFactor + accelerationX * (1.0 - kfilteringFactor);
    int accelerationY = acceleration.y * kfilteringFactor + accelerationY * (1.0 - kfilteringFactor);

    float currentRawReading = (atan2(accelerationY, accelerationX)) * 180/M_PI;
    NSLog(@"Angle: %f",currentRawReading);
}

Sample from log while phone is flat:

2009-06-16 17:29:07.987 [373:207] Angle: 0.162292
2009-06-16 17:29:07.994 [373:207] Angle: 179.838547
2009-06-16 17:29:08.014 [373:207] Angle: 179.836182
2009-06-16 17:29:08.032 [373:207] Angle: -90.000000
2009-06-16 17:29:08.046 [373:207] Angle: 179.890900
2009-06-16 17:29:08.059 [373:207] Angle: -90.000000
2009-06-16 17:29:08.074 [373:207] Angle: 179.917908
2009-06-16 17:29:08.088 [373:207] Angle: -179.950424
2009-06-16 17:29:08.106 [373:207] Angle: 90.000000
2009-06-16 17:29:08.119 [373:207] Angle: 90.000000
2009-06-16 17:29:08.134 [373:207] Angle: -179.720245
+4  A: 

I think your problem is that you're using int variables when you want float.

I think the accelerationX and –Y should be instance variables and thus:

accelerationX = acceleration.x * kfilteringFactor + accelerationX * (1.0 - kfilteringFactor);
accelerationY = acceleration.y * kfilteringFactor + accelerationY * (1.0 - kfilteringFactor);

Should give you more what you were looking for.

Andrew Pouliot
Thanks for your reply, I changed the code to use floats intead of ints, but I'm still getting the result of wildly fluctuating values being calculated when the device is lying flat.
Farid
Added some lines from log to the question.
Farid
Ah, missed your comment the first time regarding the instance variables, looks like it might be the solution, will get back to you.
Farid
That did it, thanks!
Farid
+3  A: 

The reason is that you're using local variables, while they shouldn't be local.

Try to do the following:

Declare instance variables:

@interface YourViewControllerClass: UIViewController {
    float accelerationX, accelerationY;
}

...

other declarations

Update variables in accelerometer delegate:

 accelerationX = acceleration.x * kfilteringFactor + accelerationX * (1.0 - kfilteringFactor);
 accelerationY = acceleration.y * kfilteringFactor + accelerationY * (1.0 - kfilteringFactor);

It should give more precise results without sudden jumps.

Valerii Hiora