Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Mockup & CodeGen, iPhone & iPad
($9.99)

Make your own iPhone apps
and run them live!
(free)

Manu
($0.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Tutorials

Reply
 
LinkBack Thread Tools Display Modes
Old 01-27-2009, 05:24 PM   #1 (permalink)
Tutorial Author
 
Join Date: Jan 2009
Posts: 144
Default UIAccelerometer tutorial

If you like this tutorial, feel free to send me a donation at baseballer1149@aol.com via paypal.
First off, the UIAccelerometer is something that a lot of apps use. It's that thing that automatically detects when the user has moved his/her iphone. It measures on 3 axis, and they are the following.

X: When the user moves iphone left/right
Y: When the user moves iphone forward/backward
Z: When the user moves the iphone up/down

Now, to use this in an application.
Go ahead and open up a new View-based application.
Lets name is accel.
Now, open up accelViewController.h and add an IBOutlet for a UILabel

Code:
// code
@interface accelViewController : UIViewController < UIAccelerometerDelegate >{
IBOutlet UILabel *label;
}
@property (nonatomic, retain) IBOutlet UIlabel *label;
// end of code
quickly open up the *.m file and put in the following (underneath @implementation)

Code:
@synthesize label;
this will create getter and setter methods for changing values about our label

now, open up the .nib file for this view.
Drag on a UILabel, and in connections inspector drag from "New Referencing Outlet" to files owner, and select the label outlet.

Now, head back to the *.m file

uncomment the viewDidLoad method (towards the bottom of the file)
And inside of the viewDidLoad method, put the following:

Code:
[label setText:@"fixed"]
UIAccelerometer *accel = [UIAccelerometer sharedAccelerometer];
accel.delegate = self;
accel.updateInterval = 1.0f/60.0f;
Ok, now an explanation:

Code:
[label setText:@"fixed"];
sets our label to "fixed"

Code:
UIAccelerometer *accel = [UIAccelerometer sharedAccelerometer];
gets a reference to the devices shared accelerometer.

Code:
accel.delegate = self;
accel.updateInterval = 1.0f/60.0f;
sets the delegate, and how many times it will check per second.
Increasing that value 1.0f/60.0f may put strain on the battery

Now, all thats left is to implement the accelerometer:didAccelerate method

somewhere in the file, add this method:

Code:
- (void)accelerometer:(UIAccelerometer *)acel didAccelerate:(UIAcceleration *)aceler {

if (fabsf(aceler.x) > 1.5 || fabsf(aceler.y) > 1.5 || fabsf(aceler.z) > 1.5)
{
if ([label.text isEqualToString:@"Broken"] == YES)
{
[label setText:@"Fixed"];
}
else
{
[label setText:@"Broken"];
}
             }
now, you're good. One thing left to explain. UIAcceleration has 3 values to it, X, Y, and Z. In order to assure the gesture wasn't by accident, we test to see if each value is above 1.5. You can use this in numerous ways, you just have to think of creative things. Instead of buttons, sometimes think of all the other things the iphone can do, and use those (accelerometer, microphone, etc.)

Have fun and post comments if you need help

Oh, and don't forget to build-run the app!

Last edited by meowmix23F; 04-03-2009 at 03:17 PM. Reason: Added code tags.
meowmix23F is offline   Reply With Quote
Old 01-28-2009, 07:59 PM   #2 (permalink)
Administrator
 
Chris Stewart's Avatar
 
Join Date: Mar 2008
Location: Richmond, VA
Age: 29
Posts: 746
Default

Here's a hang up I had while following the above code, the UIAccelerometerDelegate protocol. Add this to your header file's implementation section:

Code:
@interface RootViewController : UITableViewController
__________________
Founder, Locomo Labs, LLC
SocialBlast -- iPhone/iPad -- Update Twitter/Facebook/LinkedIn/Foursquare

Previous owner, and original founder, of iPhone Dev SDK
Chris Stewart is offline   Reply With Quote
Old 01-28-2009, 08:23 PM   #3 (permalink)
Tutorial Author
 
Join Date: Jan 2009
Posts: 144
Default

Actually that is in there. For some reason though, the forum picks it up as regular forum commands and doesn't show it.

For all people here

where it sais @interface accelViewController : UIViewController {

change it to @interface accelViewController : UIViewController < UIAccelerometerDelegate >

but with no spaces in between ***Delegate > and < UIAc***
meowmix23F is offline   Reply With Quote
Old 02-02-2009, 03:24 AM   #4 (permalink)
Beast Mode
 
Join Date: Dec 2008
Age: 21
Posts: 1,890
Default

thanks for this! its a good start that i needed
__________________
I really do this.
Bertrand21 is offline   Reply With Quote
Old 02-07-2009, 03:24 PM   #5 (permalink)
Tutorial Author
 
Join Date: Jan 2009
Posts: 144
Default

Quote:
Originally Posted by Bertrand21 View Post
thanks for this! its a good start that i needed
No Problem, just glad to help.

Any other tutorial ideas?
meowmix23F is offline   Reply With Quote
Old 02-07-2009, 05:25 PM   #6 (permalink)
Pro. Game Developer
iPhone Dev SDK Supporter
 
Join Date: Feb 2009
Location: żLa Islas Hermosas?
Posts: 2,178
Default

This looks a lot like the sample given in the Beginning iPhone Development book. The thing I'm not crazy about is how the motion detection check is performed. Each axis of the acceleration vector is examined independent of the others, which -- while adequate enough for the sake of the tutorial -- isn't the most accurate approach.

IMHO, a better (i.e. more accurate) technique involves treating the acceleration vector that is sent to the callback as, well, a vector. So, rather than testing any single axis for motion beyond a threshold, as in the original code,
Code:
- (void)accelerometer:(UIAccelerometer *)acel didAccelerate:(UIAcceleration *)aceler
{
    if ( fabsf(aceler.x) > 1.5 || fabsf(aceler.y) > 1.5 || fabsf(aceler.z) > 1.5 )
    {
        if ( [label.text isEqualToString:@"Broken"] == YES )
        {
            [label setText:@"Fixed"];
        }
        else
        {
            [label setText:@"Broken"];
        }
    }
}
I would opt for the following, which calculates the magnitude of the true (3D) acceleration vector and compares that to the threshold:
Code:
- (void)accelerometer:(UIAccelerometer *)acel didAccelerate:(UIAcceleration *)aceler
{
    // note: this can be optimized by removing the sqrt() call and comparing against (threshold * threshold)
    if ( sqrt(aceler.x * aceler.x + aceler.y * aceler.y + aceler.z * aceler.z) > 1.5f ) )
    {
        if ( [label.text isEqualToString:@"Broken"] == YES )
        {
            [label setText:@"Fixed"];
        }
        else
        {
            [label setText:@"Broken"];
        }
    }
}
While I recognize that what's most important in this tutorial is the instruction on how to set up the accelerometer to make the callbacks and how to write the callback handler, I thought it was worth pointing out how you can obtain the actual acceleration vector magnitude.
Kalimba is offline   Reply With Quote
Old 02-17-2009, 05:45 PM   #7 (permalink)
Registered Member
 
Join Date: Oct 2008
Posts: 37
Default

Great tutorial, many thanks. Nicely focused on the subject.

Forgive a possibly stupid question, as i am no expert in physics.

If I want to just respond to the user "shaking" the iPhone, say for dice, or like the iPod Nano does for switching to another random song, should I just check for a large difference (the delta) in the x, y, or z values ? Therefore, I should keep track of the previous values and then just check for a delta. Would there be an appropriate to check for, or maybe I should just test out different deltas and see how they work.

Many Thanks.
__________________
My Apps: Word Zapper / MyThoughts+ / MyThoughts / Nothing / Chicks Only
paulperry is offline   Reply With Quote
Old 02-18-2009, 07:35 PM   #8 (permalink)
Tutorial Author
 
Join Date: Jan 2009
Posts: 144
Default

Quote:
Originally Posted by paulperry View Post
Great tutorial, many thanks. Nicely focused on the subject.

Forgive a possibly stupid question, as i am no expert in physics.

If I want to just respond to the user "shaking" the iPhone, say for dice, or like the iPod Nano does for switching to another random song, should I just check for a large difference (the delta) in the x, y, or z values ? Therefore, I should keep track of the previous values and then just check for a delta. Would there be an appropriate to check for, or maybe I should just test out different deltas and see how they work.

Many Thanks.
Sorry it took so long for me to respond, by the way.

To check for a light shake, just check if the absolute value of the x, y, and z properties are greater than 1.5 or 2.0. 2.0 is generally a strong shake, and 1.5 is generally a light shake.
meowmix23F is offline   Reply With Quote
Old 03-04-2009, 12:50 AM   #9 (permalink)
New Member
 
Join Date: Mar 2009
Location: Calgary, Alberta, Canada
Posts: 24
Default

Total newb here... but I hit a wall here:

Quote:
now, open up the .nib file for this view.
Drag on a UILabel, and in connections inspector drag from "New Referencing Outlet" to files owner, and select the label outlet.
The only outlet option I have here is for "view".

I've just fallen off the iPhone turnip truck, so bear with me. Thanks.
speasley is offline   Reply With Quote
Old 03-04-2009, 08:59 PM   #10 (permalink)
Tutorial Author
 
Join Date: Jan 2009
Posts: 144
Default

Make sure that you added the
Code:
IBOutlet UIImageView *imageView;
in the header file, and also the @property() for it.
Also, make sure you don't open up mainwindow.xib, because that's not the right file.
meowmix23F is offline   Reply With Quote
Old 03-05-2009, 12:27 AM   #11 (permalink)
New Member
 
Join Date: Mar 2009
Location: Calgary, Alberta, Canada
Posts: 24
Default

Thanks for the reply.

Hm, I think I'm getting there. Now I'm hung up on a few errors:

Code:
"syntax error before ';' token:"
UIAccelerometer *accel = [[UIAccelerometer sharedAccelerometer];
accel.delegate = self;

"'didReceiveMemoryWarning' undeclared (first use in this function):"
"syntax error before '{' token:"
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    // Release anything that's not essential, such as cached data
}
Thanks again.
speasley is offline   Reply With Quote
Old 03-06-2009, 11:21 PM   #12 (permalink)
Tutorial Author
 
Join Date: Jan 2009
Posts: 144
Default

Oh gawd.
Code:
UIAccelerometer *accel = [[UIAccelerometer sharedAccelerometer];
accel.delegate = self;
Goes in your viewDidLoad() method! Not in the middle of the code!
meowmix23F is offline   Reply With Quote
Old 03-06-2009, 11:56 PM   #13 (permalink)
Pro. Game Developer
iPhone Dev SDK Supporter
 
Join Date: Feb 2009
Location: żLa Islas Hermosas?
Posts: 2,178
Default

Quote:
Originally Posted by meowmix23F View Post
Oh gawd.
Code:
UIAccelerometer *accel = [[UIAccelerometer sharedAccelerometer];
accel.delegate = self;
Goes in your viewDidLoad() method! Not in the middle of the code!
There is also the syntax error that the compiler is reporting. The brackets around the "UIAccelerometer sharedAccelerometer" are mismatched.
Kalimba is offline   Reply With Quote
Old 03-07-2009, 12:25 AM   #14 (permalink)
New Member
 
Join Date: Mar 2009
Location: Calgary, Alberta, Canada
Posts: 24
Default

It's actually not in the middle of my code. I was showing the error message with the relevant lines of code. I should have formatted it better.

Error: syntax error before ']' token:
Code:
UIAccelerometer *accel = [[UIAccelerometer sharedAccelerometer]];
accel.delegate = self;
accel.updateInterval = 1.0f/60.0f;
Error: 'didReceiveMemoryWarning' undeclared (first use in this function)
Code:
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    // Release anything that's not essential, such as cached data
}
Error: syntax error before '{' token:
Code:
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    // Release anything that's not essential, such as cached data
}
I'm starting to think this thread isn't a good tutorial for me right now. The posted code contains typos and being a noob, I'm getting thrown off by it pretty easily.
speasley is offline   Reply With Quote
Old 03-07-2009, 12:41 AM   #15 (permalink)
Tutorial Author
 
Join Date: Jan 2009
Posts: 144
Default

Woops, im really sorry. You were right. I updated the post with the actual way it's supposed to be done. I was working with NSFileManager so i did that without even thinking.
meowmix23F is offline   Reply With Quote
Old 03-09-2009, 06:36 PM   #16 (permalink)
Registered Member
 
Join Date: Feb 2009
Posts: 22
Default

Quote:
Originally Posted by meowmix23F View Post
Woops, im really sorry. You were right. I updated the post with the actual way it's supposed to be done. I was working with NSFileManager so i did that without even thinking.
Hi, I get 7 errors after compiling, but it are 2 different kinds of errors:
- error: syntax error before before UILabel
- error: syntax error before before '{' token

Can somebody please tell me what I am doing wrong? I think it is something with the NIB-file?
I really need this accelerovalues...

Thanks in advance
yannickd60 is offline   Reply With Quote
Old 03-12-2009, 10:52 PM   #17 (permalink)
Tutorial Author
 
Join Date: Jan 2009
Posts: 144
Default

Check updated code
meowmix23F is offline   Reply With Quote
Old 03-26-2009, 04:46 AM   #18 (permalink)
New Member
 
Join Date: Dec 2008
Posts: 1
Default

very good, i am looking for it,many thanks
myiphone is offline   Reply With Quote
Old 03-28-2009, 02:55 PM   #19 (permalink)
Registered Member
 
Join Date: Feb 2009
Location: Cary, NC
Posts: 12
Send a message via AIM to piratemc74
Default What's it supposed to do?

I have it compiled, and even pushed to the phone. Can it be "tested" in the simulator? In the viewDidLoad method, does your code come before or after [super viewDidLoad];? I'm assuming after.

I'm pretty much a newbie, so, following examples is how I'm learning, but, still not able to "dig out" what's going on here. Thanks! Keep up the examples.
__________________
Mat
24" iMac
8gb iPhone-Gen1
piratemc74 is offline   Reply With Quote
Old 04-02-2009, 02:58 AM   #20 (permalink)
Alx
New Member
 
Join Date: Jan 2009
Posts: 11
Default

Thanks for this tutorial.

I'm fighting with this Accelerometer since some days now.

I'm trying to move an object on the iphone's screen, by using the accelerometer.

When the iphone is flat, it's working fine.
Else, it's completely wrong.

I've to calibrate the iPhone.
But I can't understand how to do this.
Would someone please help me?

I'm running the app' in landscape mode.

Here is how I get the accelerometer values:

Code:
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {

    accelerometerValues[0] = acceleration.x * kFilteringFactor + accelerometerValues[0] * (1.0 - kFilteringFactor);
	accelerometerValues[1] = acceleration.y * kFilteringFactor + accelerometerValues[1] * (1.0 - kFilteringFactor);
	accelerometerValues[2] = acceleration.z * kFilteringFactor + accelerometerValues[2] * (1.0 - kFilteringFactor);
}
Here is how I compute the new position of my object:
Code:
- (void) tick
{
	if (gameFinished)
		return;
	
	float                dTime;
    CFTimeInterval        time;
	
    time = CFAbsoluteTimeGetCurrent();
    dTime = time - lastTime;
	
	float accelerationX = (accelerometerValues[1]) * dTime * 1000;
    float accelerationY = (accelerometerValues[0]) * dTime * 1000;
	
	float newX=m_TargetImgView.center.x+accelerationX;
	float newY=m_TargetImgView.center.y+accelerationY;
	
	if (newX < 0)
		newX=0;
	else if (newX > 480)
		newX = 480;
	
	if (newY < 0)
		newY=0;
	else if (newY > 320)
		newY = 320;
	
	m_myImgView.center=CGPointMake(newX,newY);
	
	lastTime = time;
}
Thanks in advance for any help

Alx
Alx is offline   Reply With Quote
Old 04-02-2009, 09:53 AM   #21 (permalink)
Pro. Game Developer
iPhone Dev SDK Supporter
 
Join Date: Feb 2009
Location: żLa Islas Hermosas?
Posts: 2,178
Default

Quote:
Originally Posted by Alx View Post
Thanks for this tutorial.

I'm fighting with this Accelerometer since some days now.

I'm trying to move an object on the iphone's screen, by using the accelerometer.

When the iphone is flat, it's working fine.
Else, it's completely wrong.

I've to calibrate the iPhone.
But I can't understand how to do this.
Would someone please help me?

I'm running the app' in landscape mode.

Here is how I get the accelerometer values:

Code:
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {

    accelerometerValues[0] = acceleration.x * kFilteringFactor + accelerometerValues[0] * (1.0 - kFilteringFactor);
	accelerometerValues[1] = acceleration.y * kFilteringFactor + accelerometerValues[1] * (1.0 - kFilteringFactor);
	accelerometerValues[2] = acceleration.z * kFilteringFactor + accelerometerValues[2] * (1.0 - kFilteringFactor);
}
Here is how I compute the new position of my object:
Code:
- (void) tick
{
	if (gameFinished)
		return;
	
	float                dTime;
    CFTimeInterval        time;
	
    time = CFAbsoluteTimeGetCurrent();
    dTime = time - lastTime;
	
	float accelerationX = (accelerometerValues[1]) * dTime * 1000;
    float accelerationY = (accelerometerValues[0]) * dTime * 1000;
	
	float newX=m_TargetImgView.center.x+accelerationX;
	float newY=m_TargetImgView.center.y+accelerationY;
	
	if (newX < 0)
		newX=0;
	else if (newX > 480)
		newX = 480;
	
	if (newY < 0)
		newY=0;
	else if (newY > 320)
		newY = 320;
	
	m_myImgView.center=CGPointMake(newX,newY);
	
	lastTime = time;
}
Thanks in advance for any help

Alx
What specifically about your code isn't working? Are you seeing any movement? Is the movement too great? Is the movement in the wrong direction? It's difficult to diagnose a problem without knowing what the symptoms are.
Kalimba is offline   Reply With Quote
Old 04-03-2009, 05:38 AM   #22 (permalink)
Alx
New Member
 
Join Date: Jan 2009
Posts: 11
Default

Quote:
Originally Posted by Kalimba View Post
What specifically about your code isn't working? Are you seeing any movement? Is the movement too great? Is the movement in the wrong direction? It's difficult to diagnose a problem without knowing what the symptoms are.
Sorry, you're right, I didn't give details.
Bu I've solved my problem, so my post can be deleted now.

Anyway, thanks.
Alx is offline   Reply With Quote
Old 04-03-2009, 02:41 PM   #23 (permalink)
New Member
 
Join Date: Apr 2009
Location: NY NY
Posts: 35
Thumbs up great tutorial!

meowmix: this is a great tutorial - very helpful! thank you!
home_dev is offline   Reply With Quote
Old 04-03-2009, 03:15 PM   #24 (permalink)
Tutorial Author
 
Join Date: Jan 2009
Posts: 144
Default

Quote:
Originally Posted by home_dev View Post
meowmix: this is a great tutorial - very helpful! thank you!
Thanks, glad to hear.
meowmix23F is offline   Reply With Quote
Old 04-17-2009, 10:47 AM   #25 (permalink)
Registered Member
 
Join Date: Apr 2009
Posts: 23
Default

Quote:
Originally Posted by meowmix23F View Post
Make sure that you added the
Code:
IBOutlet UIImageView *imageView;
in the header file, and also the @property() for it.
Also, make sure you don't open up mainwindow.xib, because that's not the right file.
Is this missing from the code at the top?

Sorry another Newb here - could the original post be updated if it is.

I'm getting this error
2009-04-17 15:37:26.599 accel[1328:107] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIViewController _loadViewFromNibNamed:bundle:] loaded the "accelViewController" nib but the view outlet was not set.'


Cheers
Chris

Last edited by netsmith; 04-17-2009 at 10:49 AM.
netsmith is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is On
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 344
20 members and 324 guests
ADY, Dani77, e2applets, Herbie, JasonR, keeshux, linkmx, mer10, Monstertaco, piesia, prchn4christ, Promo Dispenser, Robiwan, sebasx, sly24, Touchmint, twerner, zulfishah
Most users ever online was 1,187, 10-11-2011 at 08:09 AM.
» Stats
Members: 158,880
Threads: 89,228
Posts: 380,760
Top Poster: BrianSlick (7,129)
Welcome to our newest member, @sandris
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 01:32 PM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0