I can't seem to find any documentation online about this, and what I am googling is giving me a lot of conflicting information...
From iphonedevsdk.com:
The accelerometers used in the first and second generation iPhones (and I assume also the iPod touches) operate in two modes: +/- 2 g, and +/- 8 g. (Actually, as you observed, they report accelerations somewhat outside the nominal range. Accuracy is not spec'ed outside that range, though.)
Apple operates them in the +/- 2 g mode. There is a tradeoff: The current resolution is nominally 0.018 g, according to the datasheet (though my first generation iPhone uses 0.018168604, according to a modified version of AccelerometerGraph). In the +/- 8 g mode, the resolution would be four times cruder.
I assume Apple decided that the finer resolution would be more useful than the wider range. (I'd rather see finer resolution than 0.018 g. So neither of us is fully satisfied.)
You cannot change the mode with any published feature of the APIs. Since they are passing acceleration as a double, they could theoretically allow a change in mode, and simply look at the mode when rescaling the A/D value, before reporting acceleration. (The obvious place to set the mode would be in the call which sets up the application to receive accelerometer information.) However, for backward compatibility, the OS would have to set the accelerometer mode to +/- 2 g at the beginning of the application. And none of the background processes could be allowed to set the accelerometer mode.
I created the following application to try to test out the ranges...
UIAccelerometer *objAccelerometer;
UILabel *lblxmin, *lblxmax, *lblymin, *lblymax, *lblzmin, *lblzmax;
UILabel *lblxnow, *lblynow, *lblznow;
float xmin = 0.0, xmax = 0.0, ymin = 0.0, ymax = 0.0, zmin = 0.0, zmax = 0.0, xnow = 0.0, ynow = 0.0, znow = 0.0;
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
//NSLog (@"%f, %f, %f", acceleration.x, acceleration.y, acceleration.z);
xnow = acceleration.x;
ynow = acceleration.y;
znow = acceleration.z;
if (xnow < xmin) { xmin = xnow; }
if (ynow < ymin) { ymin = ynow; }
if (znow < zmin) { zmin = znow; }
if (xnow > xmax) { xmax = xnow; }
if (ynow > ymax) { ymax = ynow; }
if (znow > zmax) { zmax = znow; }
lblxmin.text = [NSString stringWithFormat:@"%f", xmin];
lblymin.text = [NSString stringWithFormat:@"%f", ymin];
lblzmin.text = [NSString stringWithFormat:@"%f", zmin];
lblxmax.text = [NSString stringWithFormat:@"%f", xmax];
lblymax.text = [NSString stringWithFormat:@"%f", ymax];
lblzmax.text = [NSString stringWithFormat:@"%f", zmax];
lblxnow.text = [NSString stringWithFormat:@"%f", xnow];
lblynow.text = [NSString stringWithFormat:@"%f", ynow];
lblznow.text = [NSString stringWithFormat:@"%f", znow];
}
-(void) invokeAccelerometer {
objAccelerometer = [UIAccelerometer sharedAccelerometer];
objAccelerometer.delegate = self;
objAccelerometer.updateInterval = (1.0 / 10.0);
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
lblxmin = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 100, 40)];
lblxnow = [[UILabel alloc] initWithFrame:CGRectMake(100, 10, 100, 40)];
lblxmax = [[UILabel alloc] initWithFrame:CGRectMake(200, 10, 100, 40)];
lblymin = [[UILabel alloc] initWithFrame:CGRectMake(10, 60, 100, 40)];
lblynow = [[UILabel alloc] initWithFrame:CGRectMake(100, 60, 100, 40)];
lblymax = [[UILabel alloc] initWithFrame:CGRectMake(200, 60, 100, 40)];
lblzmin = [[UILabel alloc] initWithFrame:CGRectMake(10, 110, 100, 40)];
lblznow = [[UILabel alloc] initWithFrame:CGRectMake(100, 110, 100, 40)];
lblzmax = [[UILabel alloc] initWithFrame:CGRectMake(200, 110, 100, 40)];
[self.view addSubview:lblxmin];
[self.view addSubview:lblxnow];
[self.view addSubview:lblxmax];
[self.view addSubview:lblymin];
[self.view addSubview:lblynow];
[self.view addSubview:lblymax];
[self.view addSubview:lblzmin];
[self.view addSubview:lblznow];
[self.view addSubview:lblzmax];
[self invokeAccelerometer];
[super viewDidLoad];
}
The problem is, when I rotate my iPod along the horizontal/vertical axes and then flip it over, I get values like:
xmin -1.271802
xmax 1.180959
ymin -1.344477
ymax 1.108285
zmin -2.30713
zmax 2.325581
If I take the iPod and shake the heck out of it, I get...
x -2.325581 to 2.307413
y -2.325581 to 2.307413
z -2.307413 to 2.325581
Any ideas what it's measuring?
The best I've come up with is:
vertical axis
x = -1 if tilted to the left ( <| )
x = +1 if tilted all the way to the right ( |> )
- where < is the way the screen faces, and | is the bottom of the iPod
y ~ -1 if screen is facing you, perpendicular to floor ("standing up")
y ~ 1 if facing away from you (and upside down)