Search code examples
objective-ciphonexcodeaccelerometercalibration

Accelerometer and calibration - iPhone SDK


I need to use the functionality of an accelerometer in my iPhone game. I just have to move an image by tilting the device. However most videos on YouTube just show the tilt feature that is somehow inverted and forget to include the calibration.

I want the user to calibrate their device to whatever position they're in. Does anyone know how I should get started on this?


Solution

  • I made an app like this once. I'll post it here, but it's for iOS 4...

    To calibrate:

    int tapCount = 0;
    - (void)cancelDoubleTap {
        if (tapCount < 2) {
            tapCount = 0;
        }
    }
    - (void)reset {
        [[NSUserDefaults standardUserDefaults] setFloat:0 forKey:@"X-Calibrate"];
        [[NSUserDefaults standardUserDefaults] setFloat:0 forKey:@"Y-Calibrate"];
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Reset!" message:@"Calibration reset." delegate:nil cancelButtonTitle:@"Okay." otherButtonTitles:nil];
        [alert show];
        [alert release];
    }
    - (void)calibrate {
        if (tapCount == 3) {
            tapCount = 0;
            return;
        }
        [[NSUserDefaults standardUserDefaults] setFloat:accelX forKey:@"X-Calibrate"];
        [[NSUserDefaults standardUserDefaults] setFloat:accelY forKey:@"Y-Calibrate"];
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Calibrated!" message:[NSString stringWithFormat:@"Calibrated to: %.2f %.2f.", accelX, accelY] delegate:nil cancelButtonTitle:@"Okay." otherButtonTitles:nil];
        [alert show];
        [alert release];
        tapCount = 0;
    }
    - (BOOL)canBecomeFirstResponder {
        return YES;
    }
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
        NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(cancelDoubleTap) userInfo:nil repeats:NO];
        tapCount ++;
        if (tapCount == 3) {
            [timer invalidate];
            [self reset];
            return;
        }
        if (tapCount == 2) {
            [timer invalidate];
            timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(calibrate) userInfo:nil repeats:NO];
        }  
    }
    

    And...

     - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
        but = [[UIButton alloc] initWithFrame:window.frame];
        [but addTarget:self action:@selector(touchesEnded:withEvent:) forControlEvents:UIControlEventTouchUpInside];
        [window addSubview:but];
         // Override point for customization after application launch.
        box = [[UIView alloc] initWithFrame:CGRectMake(self.window.center.x - 50, self.window.center.y - 50, 100, 100)];
      [window makeKeyAndVisible];
        box.backgroundColor = [UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:0.75];
        [window addSubview:box];
        [[UIAccelerometer sharedAccelerometer] setDelegate:self];
        [[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1/100.0)];
        slider = [[UISlider alloc] initWithFrame:CGRectMake(20, 438, 280, 22)];
        [slider setMinimumValue:2.0];
        [slider setMaximumValue:50.0];
        [window addSubview:slider];
        return YES;
     }
    

    .h file:

    #import <UIKit/UIKit.h>
    
    @interface TilterAppDelegate : NSObject <UIApplicationDelegate, UIAccelerometerDelegate> {
        UIWindow *window;
        UIView *box;
        UISlider *slider;
        UIButton *but;
    }
    
    @property (nonatomic, retain) IBOutlet UIButton *but;
    @property (nonatomic, retain) IBOutlet UISlider *slider;
    @property (nonatomic, retain) IBOutlet UIView *box;
    @property (nonatomic, retain) IBOutlet UIWindow *window;
    
    @end
    

    Move code:

     - (void)moveBoxByX:(float)x byY:(float)y {
        float newX = box.center.x + x;
        float newY = box.center.y + y;
        if (newX < 50)
            newX = 50;
        if (newX > 270)
            newX = 270;
        if (newY < 50)
            newY = 50;
        if (newY > 430)
            newY = 430;
        box.center = CGPointMake(newX, newY);
    }
    

    Should work most of the time.