Rectangle 27 18

Checking for large negative values does not tell you whether the phone is being dropped.

  • First, the user could just move the phone with a rapid gesture, this would also result in a large (maybe negative) value.
  • Secondly, the phone could fall in another direction than you imagine, and therefore, the acceleration could be positive, although the phone is moving towards the ground.

You could just calculate the total acceleration (a = sqrt(ax^2 + ay^2 + az^2)) and check whether this total acceleration corresponds approximately to earth acceleration (9.81). The phone is falling if the acceleration corresponds to earth acceleration for some time.

You would however have to test yourself, what means "total acceleration corresponds approximately to earth acceleration" and "for some time" in your case.

Let's assume you drop your phone in a way, that the y axis of the phone shows upwards. Then the x and z accelerations will be 0 and the y acceleration will be like this:

The acceleration will be 0 in the beginning, will then reach -9.81 the moment, you release your phone. Then it will hit the ground, which you see in the small acceleration peak, and then the acceleration is zero again.

However you can't use only the acceleration in y direction, because your phone may fall in a different angle.

So you have to watch the total acceleration of your phone:

Here you don't see a negative acceleration anymore. However, here it doesn't matter anymore in which direction your phone is facing, as a free fall will always be characterized by an acceleration of 9.81.

To your edits: 1. Why would you want to round off the values of acceleration to 3 decimal places? If you test 0.9 < x < 1.1, it doesn't matter if x is 0.914698 or 0.915. 2. What if someone drops the phone but then catches it again, so the total acceleration does not necessarily have to go down again. Additionally, there should be a large acceleration value (a sudden deceleration) the moment the phone hits the floor. Maybe the reason one does not see this in your values is that it is so short, that it falls between two consecutive measurements. However this could be measured, so don't suppose that immediately after the free fall, the acceleration should decrease again.

Thanks Misch for pointing out total acceleration, really appreciate your effort. I've updated my question, if you can add something please do. I'm accepting your answer! :) thanks

Will this apply also to a car crash? If you are driving say 40 km/h and crash, will there be a sudden change of movement (deceleration) equal to earth acceleration or will it be significantly higher?

ios - Detect programmatically if iPhone is dropped using CoreMotion/Ac...

ios accelerometer physics
Rectangle 27 14

The double integration method is really the only way to get the information you are looking for using only an accelerometer. You found the problem with this method. The error increases over time and generally doesn't give the accuracy many are looking for.

Kalman filtering usually requires 2 devices and basically takes the best of both devices and filters out the bad. See example below.

Kalman filtering is a really tough subject that I tried to dive into for senior design, but never found any meaningful results with my limited testing. A great place to start understanding this subject is with this youtube video series .

This is the guy that won the DARPA challenge with Stanford and explains the topic in an easy to understand way. The whole course is a 6 unit video series about programming robots to move and understand their location in an unknown environment. Worth a watch if you have the time and interest.

It sounds like you're trying to do something similar to what I did for senior design in give really specific relative location information.

Another great Kalman filtering read this (if this link doesn't work google Kalman filter balance bot and click the TKJ blog link). Basically this guy uses an accelerometer and gyroscope to track orientation in the real world.

Something else to look into wiki Real Time Kinematic. This goes on tractors and combines to provide really accurate location information. John Deere sells a system, but it's like $20,000. Here is the poor man's version using GPS and beagleboard

calculating distances using accelerometer - Stack Overflow

accelerometer
Rectangle 27 6

I have searched whithin iOS SDK for functions related to accelerometer. It seems like everything boils down to one of two frameworks (other frameworks rely on one of these): SpringBoardServices (Private) and CoreMotion.

@interface SBSAccelerometer : XXUnknownSuperclass {
    id<SBSAccelerometerDelegate> _delegate;
    CFRunLoopSourceRef _accelerometerEventsSource;
    CFRunLoopRef _accelerometerEventsRunLoop;
    double _interval;
    NSLock* _lock;
    BOOL _orientationEventsEnabled;
    int _orientationEventsToken;
    NSThread* _orientationEventsThread;
    float _xThreshold;
    float _yThreshold;
    float _zThreshold;
}
@property(assign, nonatomic) id<SBSAccelerometerDelegate> delegate;
@property(assign, nonatomic) BOOL orientationEventsEnabled;
@property(assign, nonatomic) float zThreshold;
@property(assign, nonatomic) float yThreshold;
@property(assign, nonatomic) float xThreshold;
@property(assign, nonatomic) double updateInterval;
@property(assign, nonatomic) BOOL accelerometerEventsEnabled;
-(id)init;
-(void)dealloc;
-(void)_checkIn;
-(void)_checkOut;
-(void)_serverWasRestarted;
-(int)currentDeviceOrientation;
-(id)_orientationEventsThread;
-(void)_orientationDidChange;
@end
int SBAccelerometer_server(struct unknown *in, struct unknown *out); //returns 1 on success, 0 otherwise
int SBAccelerometer_server_routine(struct unknown *in); // retuns 0 on error;
(?) SBSetAccelerometerClientEventsEnabled(...);
(?) SBSetAccelerometerDeviceOrientationChangedEventsEnabled(...);
(?) SBSetAccelerometerRawEventsInterval(...);
(?) SBXXDeliverAccelerometerEvent(...);
(NSString* or char*) _SBXXSBAccelerometer_subsystem;

CoreMotion framework low-level API is C++ API. I won't publish all the API (it's much bigger than SpingBoardServices'), but there are most promising parts:

CLSensorFusionAccelerometerOnly::reset(float)
CLSensorNetworkProtocol::isAccelerometerPacket(__CFData const*)
CLSensorNetworkProtocol::serializeAccelerometerPacket(CLAccelerometer::Sample const&)
CLSensorNetworkProtocol::deserializeAccelerometerPacket(__CFData const*)
CLSensorInterface::setAccelerometerCallbackAndInfo(void (*)(void*, CLMotionTypeVector3 const&, double const&), void*)

ios - Set iPhone accelerometer to ±8g mode - Stack Overflow

ios iphone accelerometer
Rectangle 27 287

In 3.0, there's now an easier way - hook into the new motion events.

The main trick is that you need to have some UIView (not UIViewController) that you want as firstResponder to receive the shake event messages. Here's the code that you can use in any UIView to get shake events:

@implementation ShakingView

- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    if ( event.subtype == UIEventSubtypeMotionShake )
    {
        // Put in code here to handle shake
    }

    if ( [super respondsToSelector:@selector(motionEnded:withEvent:)] )
        [super motionEnded:motion withEvent:event];
}

- (BOOL)canBecomeFirstResponder
{ return YES; }

@end

You can easily transform any UIView (even system views) into a view that can get the shake event simply by subclassing the view with only these methods (and then selecting this new type instead of the base type in IB, or using it when allocating a view).

- (void) viewWillAppear:(BOOL)animated
{
    [shakeView becomeFirstResponder];
    [super viewWillAppear:animated];
}
- (void) viewWillDisappear:(BOOL)animated
{
    [shakeView resignFirstResponder];
    [super viewWillDisappear:animated];
}

Don't forget that if you have other views that become first responder from user actions (like a search bar or text entry field) you'll also need to restore the shaking view first responder status when the other view resigns!

This didn't quite work for me: I needed to override my controller's viewDidAppear instead of viewWillAppear. I'm not sure why; maybe the view needs to be visible before it can do whatever it does to start receiving the shake events?

This is easier but not necessarily better. If you want to detect a long, continuous shake this approach is not useful as the iPhone likes to fire motionEnded before the shake has actually stopped. So using this approach you get a disjointed series of short shakes instead of one long one. The other answer works much better in this case.

@Kendall - UIViewControllers implement UIResponder and are in the responder chain. The topmost UIWindow is as well. developer.apple.com/library/ios/DOCUMENTATION/EventHandling/

[super respondsToSelector:
[self respondsToSelector:
YES
[[ShakingView superclass] instancesRespondToSelector:

Instead of using: if ( event.subtype == UIEventSubtypeMotionShake ) you can use: if ( motion == UIEventSubtypeMotionShake )

ios - How do I detect when someone shakes an iPhone? - Stack Overflow

ios accelerometer motion-detection shake
Rectangle 27 179

// Ensures the shake is strong enough on at least two axes before declaring it a shake.
// "Strong enough" means "greater than a client-supplied threshold" in G's.
static BOOL L0AccelerationIsShaking(UIAcceleration* last, UIAcceleration* current, double threshold) {
    double
        deltaX = fabs(last.x - current.x),
        deltaY = fabs(last.y - current.y),
        deltaZ = fabs(last.z - current.z);

    return
        (deltaX > threshold && deltaY > threshold) ||
        (deltaX > threshold && deltaZ > threshold) ||
        (deltaY > threshold && deltaZ > threshold);
}

@interface L0AppDelegate : NSObject <UIApplicationDelegate> {
    BOOL histeresisExcited;
    UIAcceleration* lastAcceleration;
}

@property(retain) UIAcceleration* lastAcceleration;

@end

@implementation L0AppDelegate

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    [UIAccelerometer sharedAccelerometer].delegate = self;
}

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

    if (self.lastAcceleration) {
        if (!histeresisExcited && L0AccelerationIsShaking(self.lastAcceleration, acceleration, 0.7)) {
            histeresisExcited = YES;

            /* SHAKE DETECTED. DO HERE WHAT YOU WANT. */

        } else if (histeresisExcited && !L0AccelerationIsShaking(self.lastAcceleration, acceleration, 0.2)) {
            histeresisExcited = NO;
        }
    }

    self.lastAcceleration = acceleration;
}

// and proper @synthesize and -dealloc boilerplate code

@end

The histeresis prevents the shake event from triggering multiple times until the user stops the shake.

What happens if they're shaking it precisely on a particular axis?

The best answer, because the iOS 3.0 motionBegan and motionEnded events are not very precise or accurate in terms of detecting the exact start and end of a shake. This approach allows you to be as precise as you want.

ios - How do I detect when someone shakes an iPhone? - Stack Overflow

ios accelerometer motion-detection shake
Rectangle 27 153

I finally made it work using code examples from this Undo/Redo Manager Tutorial. This is exactly what you need to do:

  • Set the applicationSupportsShakeToEdit property in the App's Delegate:
- (void)applicationDidFinishLaunching:(UIApplication *)application {

        application.applicationSupportsShakeToEdit = YES;

        [window addSubview:viewController.view];
        [window makeKeyAndVisible];
}
  • Add/Override canBecomeFirstResponder, viewDidAppear: and viewWillDisappear: methods in your View Controller:
-(BOOL)canBecomeFirstResponder {
    return YES;
}

-(void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [self becomeFirstResponder];
}

- (void)viewWillDisappear:(BOOL)animated {
    [self resignFirstResponder];
    [super viewWillDisappear:animated];
}
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    if (motion == UIEventSubtypeMotionShake)
    {
        // your code
    }
}

Worked perfect for me in 3.1.3, thanks!

Just to add to Eran Talmor solution : you should use a navigationcontroller instead of a viewcontroller in case of you've choose such an application in new project chooser.

Yep, works. Even on iOS 4.2 on the iPad with a UISplitView

ios - How do I detect when someone shakes an iPhone? - Stack Overflow

ios accelerometer motion-detection shake
Rectangle 27 6

Of the reading I have done you usually have 2-3 choices when determining what min/max readings an accelerometer will read. 2G is an extremely common choice for accelerometers because the next step (8G) is usually to coarse a reading to get the fine measurements needed when working with a hand movement. If you were dropping it off a building to measure the force of hitting the ground you would want to use the 8G (or 16G as some offer).

It looks like the Hz is intentionally capped at 100Hz according to the folks at Corona Labs. It is to keep from abusing the battery apparently. I had read that the accelerometer is the least power hungry sensor but I guess it's all relative or there is a sharp increase in power use at some point around 100Hz.

On range: The detailed accelerometer specs (LIS331DLH datasheet pdf p9) show range is set 2g/4g/8g. Swinging it around, I easily exceed 2g. Remember, the accelerometer always feels gravity, so you only need impart 1g to hit the 2g limit. I think 4g would be the most useful for my purposes (dead reckoning). Switching to 4g should only halve the sensitivity, right? That doesnt seem so bad I suppose it could interfere with iOS monitoring the device orientation.

On power consumption: If Im reading the accelerometer specs correctly (LIS331DLH datasheet pdf p10), power consumption only varies across "low-power mode" (10 A) vs "normal mode" (250 A). Low-power mode output is set from 0.5 to 10 Hz, while normal mode output is set from 50 to 1000 Hz. Since Apple allows 100 Hz, bumping it up to 1000 Hz should cost no more power. The detailed gyro specs (L3G4200D datasheet pdf p11) show only one active power consumption mode (6.1 mA).

:) I was not trying to defend the arbitrary decisions as I do not understand them either but I thought you would like the info. I did try to find a way to adjust the settings through iOS but I couldn't find anything. When working with Arduino or other micro-controllers it is too easy to setup a sensor to allow changes to these settings programatically (on the fly) to believe they are hardwired. Please let me know if you find a way to change them even if it is something you need an unlocked phone to execute. I'll do the same for you.

Sorry. Didn't mean for that to come off as a rebuttal. :) I did find this stackoverflow thread, where someone claims they were able to change the accelerometer range to 8g on their jailbroken iPhone with third party software. No follow up on exactly how, though.

AccelerometerGraph
CoreMotion.framework
CoreMotion.h
CMMotionManager *mm = [[CMMotionManager alloc] init];
mm.accelerometerUpdateInterval = 0.001;
mm.gyroUpdateInterval = 0.001;
NSLog(@"%f, %f", mm.accelerometerUpdateInterval, mm.gyroUpdateInterval);

ios - Changes in accelerometer / gyroscope limitations for iPhone 5 / ...

iphone ios accelerometer ipod-touch gyroscope
Rectangle 27 4

By a 9-Axis sensor I am assuming that means:

Getting a practical position estimate from this type of 9-axis sensor is not possible without the use of another sensor that uses an external reference such as GPS.

Theoretically, if you know the accelerations of an object in space and its initial position and velocity you will be able to calculate the objects new position by propagating the information about its acceleration and velocity back on to the initial position (i.e. integrating the acceleration twice). The reason that it is not possible in practice is that the accelerometer has noise. This noise will have a non-zero mean, so when integrating the acceleration signal the non-zero mean noise is continuously added and accumulates in the resulting velocity signal. This is seen as sensor drift. The velocity estimate starts out fairly correct but quickly drifts off due to this accumulated noise. Integrating a second time to get the position only worsens the situation by repeating the process.

By using an external reference such as a GPS, the Kalman filter can be used to combine the slow-updating GPS signal, and the fast-updating acceleration signal together to produce a reliable estimate of the position. The GPS has the effect of zeroing the drift that would be accumulated by performing the integration on the acceleration signal.

I would suggest taking a look at the Udacity Youtube videos that Khamey suggested. When learning the Kalman filter it helps to get a clear general overview of what the objective is and what the kalman filter is doing. Then the math and the actual steps of the algorithm will be much easier to understand. Another thing that is helpful when learning the Kalman filter is doing it for one state variable at a time instead of a whole state vector. This just helps focus your attention on what the Kalman filter is actually doing so that you don't get bogged down by the matrix algebra.

calculating distances using accelerometer - Stack Overflow

accelerometer
Rectangle 27 94

Now ... I wanted to do something similar (in iPhone OS 3.0+), only in my case I wanted it app-wide so I could alert various parts of the app when a shake occurred. Here's what I ended up doing.

First, I subclassed UIWindow. This is easy peasy. Create a new class file with an interface such as MotionWindow : UIWindow (feel free to pick your own, natch). Add a method like so:

- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
    if (event.type == UIEventTypeMotion && event.subtype == UIEventSubtypeMotionShake) {
        [[NSNotificationCenter defaultCenter] postNotificationName:@"DeviceShaken" object:self];
    }
}

Change @"DeviceShaken" to the notification name of your choice. Save the file.

Now, if you use a MainWindow.xib (stock Xcode template stuff), go in there and change the class of your Window object from UIWindow to MotionWindow or whatever you called it. Save the xib. If you set up UIWindow programmatically, use your new Window class there instead.

Now your app is using the specialized UIWindow class. Wherever you want to be told about a shake, sign up for them notifications! Like this:

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(deviceShaken) name:@"DeviceShaken" object:nil];

To remove yourself as an observer:

[[NSNotificationCenter defaultCenter] removeObserver:self];

I put mine in viewWillAppear: and viewWillDisappear: where View Controllers are concerned. Be sure your response to the shake event knows if it is "already in progress" or not. Otherwise, if the device is shaken twice in succession, you'll have a li'l traffic jam. This way you can ignore other notifications until you're truly done responding to the original notification.

Also: You may choose to cue off of motionBegan vs. motionEnded. It's up to you. In my case, the effect always needs to take place after the device is at rest (vs. when it starts shaking), so I use motionEnded. Try both and see which one makes more sense ... or detect/notify for both!

One more (curious?) observation here: Notice there's no sign of first responder management in this code. I've only tried this with Table View Controllers so far and everything seems to work quite nicely together! I can't vouch for other scenarios though.

Kendall, et. al - can anyone speak to why this might be so for UIWindow subclasses? Is it because the window is at the top of the food chain?

That's what's so weird. It works as-is. Hopefully it's not a case of "working in spite of itself" though! Please let me know what you find out in your own testing.

Momeks: If you need the notification to occur once the device is at rest (post-shake), use motionEnded instead of motionBegan. That ought to do it!

@Joe D'Andrea - It works as-is because UIWindow is in the responder chain. If something higher up the chain intercepted and consumed these events, it would not receive them. developer.apple.com/library/ios/DOCUMENTATION/EventHandling/

ios - How do I detect when someone shakes an iPhone? - Stack Overflow

ios accelerometer motion-detection shake
Rectangle 27 6

NSHipster has a good article to talk about the core motion: http://nshipster.com/cmdevicemotion/

A better way to regularly update UI with motion data is to use the patter as shown in below:

if manager.accelerometerAvailable {
     manager.accelerometerUpdateInterval = 0.1
     manager.startAccelerometerUpdatesToQueue(NSOperationQueue.mainQueue()) {
     [weak self] (data: CMAccelerometerData!, error: NSError!) in
          accelX.text = String(format: "%.2f", data.acceleration.x)
     }
}

iphone - How do I retrieve accelerometer data correctly with Swift in ...

ios iphone swift core-motion
Rectangle 27 2

You just compare the acceleration with 0

acceleration.y < 0.0
acceleration.y > 0.0

There is a free app iSimulate where you can see what values accelerometer outputs.

iphone - Accelerometer direction detection - Stack Overflow

iphone accelerometer
Rectangle 27 37

A MEMs gyroscope is a rate of change device. As the device rotates in any its axis, you can see a change in rotation. An accelerometer only provides the force along the X,Y,and Z vectors, and cannot solve for "twist". By using both sensors, you can often implement what is referred to as a 6DOF (degrees of freedom) inertial system - or dead reckoning - allowing you to find the relative physical location of the device. (Note that all inertial systems drift, so its not stable in the long term).

There is a new API for reading the gyroscope.

The new API is nice in that there's a fairly high-level API that gets you aggregate data from all the position sensors as well as access to the raw input from both accelerometers and gyros.

iphone - Gyroscope vs Accelerometer? - Stack Overflow

iphone ios4 accelerometer gyroscope
Rectangle 27 37

Actually, the accelerometer measures linear acceleration; but since force is equal to mass times acceleration, people can consider it as measuring force as well as long as it has a constant mass. Linear acceleration is the rate of change of linear velocity. A gyro on the other hand provides the angular rotational velocity measurement as oppose to the linear acceleration of movement. Both sensors measures the rate of change; they just measure the rate of change for different things.

Technically, it is possible for a linear accelerometer to measure rotational velocity. This is due to the centrifugal force the device generates when it is rotating. The centrifugal force is directly related to its rotational speed. As a matter of fact, many MEMS gyro sensors actually uses linear accelerometers to determine the rotational speed by carefully placing them in certain orientations and measuring the centrifugal forces to compute the actual rotational gyro speed.

+1 for the science! So given only a 3-axis accelerometer, how does one calculate the rotational direction and the degrees rotated?

Brad, you need two accelerometers spaced apart measuring in the same plane to deduce rotation. With three in the same plane you can make a two axis rate gyro using a little vector manipulation.

iphone - Gyroscope vs Accelerometer? - Stack Overflow

iphone ios4 accelerometer gyroscope
Rectangle 27 3

t=t0
[ x0 , y0 , z0 ]
[ vx0 , vy0 , vz0 ]

At t=t1 you read an acceleration vector of [ ax1 , ay1 , az1 ] (The average acceleration from t0 and t1).

[ vx1 , vy1 , vz1 ] = [ vx0 + ax1 * (t1 - t0) , vy0 + ay1 * (t1 - t0) , vz0 + az1 * (t1 - t0) ]
t0
t1
[ vx01 , vy01 , vz01 ] = [ (vx0 + vx1) / 2 , (vy0 + vy1) / 2 , (vz0 + vz1) / 2 ]
t=t1
[ x1 , y1 , z1 ] = [x0 + vx01 * (t1 - t0), y0 + vy01 * (t1 - t0), y0 + vy01 * (t1 - t0) ]

As you can see, the error propagates with t^2, so that's why the inertial systems need to be compensated by an external reference like a GPS.

calculating distances using accelerometer - Stack Overflow

accelerometer
Rectangle 27 5

NSHipster has a good article to talk about the core motion: http://nshipster.com/cmdevicemotion/

A better way to regularly update UI with motion data is to use the patter as shown in below:

if manager.accelerometerAvailable {
     manager.accelerometerUpdateInterval = 0.1
     manager.startAccelerometerUpdatesToQueue(NSOperationQueue.mainQueue()) {
     [weak self] (data: CMAccelerometerData!, error: NSError!) in
          accelX.text = String(format: "%.2f", data.acceleration.x)
     }
}

iphone - How do I retrieve accelerometer data correctly with Swift in ...

ios iphone swift core-motion
Rectangle 27 72

Basic calculus behind this problem is in the expression

(and similar expressions for displacements in y and z) and basic geometry is the Pythagorean theorem

So, once you have your accelerometer signals passed through a low-pass filter and binned in time with sampling interval dt, you can find the displacement in x as (pardon my C...)

float dx=0.0f;
float vx=0.0f;
for (int i=1; i<n; i++)
 {
   vx+=(acceleration_x[i-1] + acceleration_x[i])/2.0f*dt;
   dx+=vx*dt;
 }

and similarly for dy and dz. Here

float acceleration_x[n];

To find the total displacement, you just do

dl=sqrt(dx*dx + dy*dy + dz*dz);

Gyroscope is not necessary for this, but if you are measuring linear distances, you can use the gyroscope reading to control that rotation of the device was not too large. If rotation was too strong, make the user re-do the measurement.

Nice. I just saw that the questioner has never cast a vote nor accepted an answer, so +1 from me :-) In practice I ran into trouble after a few seconds because of error propagation even with Simpson rule for integration.

Thanks Kay, I had a suspicion that the devil is in the details, I am sure that it is not impossible to fix. Off the top of my head, accelerometer's response may be nonlinear in amplitude at high frequencies, or they may not be subtracting gravity accurately enough. In both cases, filtering out problem frequencies (probably, everything above 30 Hz must be suppressed) and runtime calibration (hold still for 1 second and measure drift to compensate for it) should help. I guess I have to try it on my Android now.

It's still an unresolved problem to get accurate results i.e. something you can really use for a game or whatever. Like Ali said David Sachs has done some very research on Android (s. Ali's link to its Google Tech Talk). You might find useful ideas in the link I provided in my answer below. Be prepared to do some heavy maths (Kalman filter and derivatives).

@drlemon : why are you doing - (acc_x[i-1]+acc_x[i])/2?

iphone - How can I find distance traveled with a gyroscope and acceler...

iphone accelerometer distance gyroscope
Rectangle 27 72

Basic calculus behind this problem is in the expression

(and similar expressions for displacements in y and z) and basic geometry is the Pythagorean theorem

So, once you have your accelerometer signals passed through a low-pass filter and binned in time with sampling interval dt, you can find the displacement in x as (pardon my C...)

float dx=0.0f;
float vx=0.0f;
for (int i=1; i<n; i++)
 {
   vx+=(acceleration_x[i-1] + acceleration_x[i])/2.0f*dt;
   dx+=vx*dt;
 }

and similarly for dy and dz. Here

float acceleration_x[n];

To find the total displacement, you just do

dl=sqrt(dx*dx + dy*dy + dz*dz);

Gyroscope is not necessary for this, but if you are measuring linear distances, you can use the gyroscope reading to control that rotation of the device was not too large. If rotation was too strong, make the user re-do the measurement.

Nice. I just saw that the questioner has never cast a vote nor accepted an answer, so +1 from me :-) In practice I ran into trouble after a few seconds because of error propagation even with Simpson rule for integration.

Thanks Kay, I had a suspicion that the devil is in the details, I am sure that it is not impossible to fix. Off the top of my head, accelerometer's response may be nonlinear in amplitude at high frequencies, or they may not be subtracting gravity accurately enough. In both cases, filtering out problem frequencies (probably, everything above 30 Hz must be suppressed) and runtime calibration (hold still for 1 second and measure drift to compensate for it) should help. I guess I have to try it on my Android now.

It's still an unresolved problem to get accurate results i.e. something you can really use for a game or whatever. Like Ali said David Sachs has done some very research on Android (s. Ali's link to its Google Tech Talk). You might find useful ideas in the link I provided in my answer below. Be prepared to do some heavy maths (Kalman filter and derivatives).

@drlemon : why are you doing - (acc_x[i-1]+acc_x[i])/2?

iphone - How can I find distance traveled with a gyroscope and acceler...

iphone accelerometer distance gyroscope
Rectangle 27 2

Unfortunately, there is no native way to do this. On the other hand, if you are willing to Jailbreak, there is a Cydia tweak you can get (I can't remember the name) that reduces the sensitivity of the accelerometer. If you have the sensitivity of it at 25%, it should be able to sense 8g. FYI, if you are reading the output from your app, it will still range from 2g but with the tweak, you have to remember that the readings will be scaled down by 1/4. (Meaning 2g in the app = 8g in actual space).

I am ok with jailbreaking and tweaking device. What is the name of this tweak and where I can learn more about that?

@EvgenyVinnik Sorry, I cannot remember. I had it on my iPhone because the orientation changed too easily. Now if this is your own app you can also scale the accelerometer output in your own code. i.e. accelOutput.x * 4 = X g forces ranging from -8 to +8. Sorry I can't help you more.

ios - Set iPhone accelerometer to ±8g mode - Stack Overflow

ios iphone accelerometer
Rectangle 27 33

I came across this post looking for a "shaking" implementation. millenomi's answer worked well for me, although i was looking for something that required a bit more "shaking action" to trigger. I've replaced to Boolean value with an int shakeCount. I also reimplemented the L0AccelerationIsShaking() method in Objective-C. You can tweak the ammount of shaking required by tweaking the ammount added to shakeCount. I'm not sure i've found the optimal values yet, but it seems to be working well so far. Hope this helps someone:

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
    if (self.lastAcceleration) {
        if ([self AccelerationIsShakingLast:self.lastAcceleration current:acceleration threshold:0.7] && shakeCount >= 9) {
            //Shaking here, DO stuff.
            shakeCount = 0;
        } else if ([self AccelerationIsShakingLast:self.lastAcceleration current:acceleration threshold:0.7]) {
            shakeCount = shakeCount + 5;
        }else if (![self AccelerationIsShakingLast:self.lastAcceleration current:acceleration threshold:0.2]) {
            if (shakeCount > 0) {
                shakeCount--;
            }
        }
    }
    self.lastAcceleration = acceleration;
}

- (BOOL) AccelerationIsShakingLast:(UIAcceleration *)last current:(UIAcceleration *)current threshold:(double)threshold {
    double
    deltaX = fabs(last.x - current.x),
    deltaY = fabs(last.y - current.y),
    deltaZ = fabs(last.z - current.z);

    return
    (deltaX > threshold && deltaY > threshold) ||
    (deltaX > threshold && deltaZ > threshold) ||
    (deltaY > threshold && deltaZ > threshold);
}

PS: I've set the update interval to 1/15th of a second.

[[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / 15)];

How can i detect the device movement just like as panorama?

How to identify shake if iphone is moved in X direction only? I don't want to detect shake if in Y or Z direction.

ios - How do I detect when someone shakes an iPhone? - Stack Overflow

ios accelerometer motion-detection shake
Rectangle 27 3

In iOS 4 the magnetometer is not yet included in device motion API but handled by CLLocationManager (this changed in iOS 5). So if you have a gyro and an accelerometer, deviceMotioAvailable will return true independent of magnetometer. On the other hand if the gyro is missing you will always get false and you need to stay with accelerometerData.

Because Device Motion has one timestamp for both sensors, you will get reliable interpolated values for both sensors. Otherwise Device Motion wouldn't be able to do sensor fusion, the main advantage why this is the preferred way.

You can not rely on a fix frequency for CLLocationManager. didUpdateHeading is called whenever the system 'thinks' it should be. To get the different time coordinates between CLLocationManager and CMDeviceMotion normalised, you can have a look at NSTimeInterval to unix timestamp

ios - iphone - Using the Device motion instead of Accelerometer, Gyros...

iphone ios cocoa-touch accelerometer gyroscope