iPhone Tutorial - Reading the Accelerometer

Skill

iPhone Tutorial - Reading the Accelerometer

Posted in:

The iPhone's accelerometer has opened up a whole new world for mobile games and applications. Fortunately, Apple has made reading the accelerometer's values an almost trivial task. The hard part is just up to you - how to actually use it. This tutorial will introduce you to the accelerometer, how to read it, and how to create a simple user interface to display its X, Y, and Z values.

For the purposes of this tutorial, I'm going to assume you know how to create a basic user interface. If you don't, I would recommend checking out our previous getting started tutorial. Below you can see an image and a quick video of the application we'll be building today.

Get Adobe Flash player

The first thing you should notice is that we've got some UILabels and some UIProgressView objects that are used to display the accelerometer's values. I created a new UIViewController subclass called MainViewController and added these objects as properties. Here's my new header file:

//
//  MainViewController.h
//  AccelerometerTutorial
//
//  Created by Brandon Cannaday on 8/5/09.
//  Copyright 2009 Paranoid Ferret Productions. All rights reserved.
//

#import <UIKit/UIKit.h>


@interface MainViewController : UIViewController <UIAccelerometerDelegate> {
  IBOutlet UILabel *labelX;
  IBOutlet UILabel *labelY;
  IBOutlet UILabel *labelZ;
 
  IBOutlet UIProgressView *progressX;
  IBOutlet UIProgressView *progressY;
  IBOutlet UIProgressView *progressZ;
 
  UIAccelerometer *accelerometer;
}

@property (nonatomic, retain) IBOutlet UILabel *labelX;
@property (nonatomic, retain) IBOutlet UILabel *labelY;
@property (nonatomic, retain) IBOutlet UILabel *labelZ;

@property (nonatomic, retain) IBOutlet UIProgressView *progressX;
@property (nonatomic, retain) IBOutlet UIProgressView *progressY;
@property (nonatomic, retain) IBOutlet UIProgressView *progressZ;

@property (nonatomic, retain) UIAccelerometer *accelerometer;

@end

A couple of things might jump out at you - first, I have another property for a UIAccelerometer object. This object is actually what's used to receive values from the accelerometer hardware. The UIAccelerometer sends updates through the use of the UIAccelerometerDelegate protocol, which is why I've marked my class as implementing this protocol.

All right, we've got the declarations out of the way. Let's now set up the UIAccelerometer object. I added code to my UIViewController's viewDidLoad method for this.

- (void)viewDidLoad {
  [super viewDidLoad];
 
  self.accelerometer = [UIAccelerometer sharedAccelerometer];
  self.accelerometer.updateInterval = .1;
  self.accelerometer.delegate = self;
}

Instances of UIAccelerometer should never be created, they should only be acquired by getting the system's shared accelerometer object. The updateInterval property is used to instruct the UIAccelerometer object how often it should send updates to its delegate. In this case I set it to .1 seconds - so I'll get updates 10 times a second. Lastly, I simply set the delegate to the UIViewController.

We're actually pretty much done. All that's left to do is implement the delegate's method to receive accelerometer updates.

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
  labelX.text = [NSString stringWithFormat:@"%@%f", @"X: ", acceleration.x];
  labelY.text = [NSString stringWithFormat:@"%@%f", @"Y: ", acceleration.y];
  labelZ.text = [NSString stringWithFormat:@"%@%f", @"Z: ", acceleration.z];
 
  self.progressX.progress = ABS(acceleration.x);
  self.progressY.progress = ABS(acceleration.y);
  self.progressZ.progress = ABS(acceleration.z);
}

The raw acceleration values are stored in the UIAcceleration object passed into this message. The values are simply what the hardware is reading - where +1 is approximately equal to 1G of acceleration. I used a simple string format to update my labels, then take the absolute value of each reading for the progress bar - since progress bars can only be values between 0 and 1. Below is an image from Apple's documentation that explains the values returned for each axis.

And that's it! We now have a working application that uses the accelerometer and displays its values on the screen. The values returned are not filtered in any way, so Apple recommends doing some averaging on the data before using it in a real application. Now that you know how to use the accelerometer, it's completely up to you now to figure out inventive ways to use the data. The example application we created today can be downloaded below, and please don't hesitate to ask any questions.

Gavin O'Brien
09/28/2009 - 08:34

Just wanted to say thanks for a quick and simple tutorial that shows off something really cool!

reply

Abdulla Q
10/20/2009 - 09:47

My Delegate and my View Controllers are instances of UIView so I keep getting the warning message: Does Not Implement UIAccelerometerDelegate

The examples I have looked at all are instances of NSObject... Which is not the case in my application. I am using a TabBar with 3 views. I only need the accelerometer in the one view.

Any Help?

reply

Abdulla Q
10/20/2009 - 10:08

Hahahaha

After analyzing your example I fixed this by adding to my @interface

@interface FirstViewController : UIViewController <UIAccelerometerDelegate> {

Thanks for your help!

Peace.

reply

YESS!!
02/13/2010 - 04:19

Thank``s a lot, really usefull and simple!

GO ON WORKING LIKE THISSS!

reply

Jooo
02/20/2010 - 16:56

How can i test in simulator (i dont have iphone )

reply

Robert
03/05/2010 - 15:38

Jooo, I don't think you can test accelerometer functions without a phone.

Thanks for the great code. I'm new to obj-c, do you have any hints on how I would store say 15 seconds of accelerometer data? Would I create an array and stick it in there?

reply

The Reddest
03/05/2010 - 16:47

I'd create an NSMutableArray to hold the UIAcceleration objects. Whenever it's read, simply call addObject on the array and supply the object.

reply

rd42
03/08/2010 - 10:10

Thanks The Reddest. I will try that out and for an encore I will try to email it as a message or attachment or ftp it out.

reply

Scorpiocos
03/24/2010 - 18:05

Hey :)

Cool & simple tutorial.

One question though - I want to use my iphone to measure the direction which i am heading to.
How can i isolate the right coordinates from the accelerometer?

Thanks!!!

reply

The Reddest
03/24/2010 - 18:22

You can't get direction from the accelerometer, you'll have to use the CoreLocation framework.

reply

Anonymous
04/20/2010 - 22:55

does this concept work on samsung omnia accelerometer ? C# vs2008

reply

Shivaji
08/27/2010 - 08:03

Thanks Buddy, Cool

reply

Add Comment

Put code snippets inside language tags:
[language] [/language]

Examples:
[javascript] [/javascript]
[actionscript] [/actionscript]
[csharp] [/csharp]

See here for supported languages.

Javascript must be enabled to submit anonymous comments - or you can login.

Sponsors