Reading Gyro info from iPhone Tutorial

Nikša on

blog-gyro-image1

Reading position (gyro) data from iPhone is not something new, however, it’s rarely used. Gyro data can be used to monitor users footsteps in health applications, as game controls where tilting of your phone causes characters to do different actions and so on… Now, the unbelievable thing behind this stuff is that it can be written in under 100 lines of code (new lines included :P)!

Let’s start with creating a new project and importing CoreMotion framework. Then create a simple UIViewController subclass, which will have connections to all the labels and one button that starts/stops gyro readings.

#import <UIKit/UIKit.h>
#import <CoreMotion/CoreMotion.h>

@interface GYRootViewController : UIViewController {
    CMMotionManager *motionManager;
}

@property (strong, nonatomic) IBOutlet UILabel *labelCounterX;
@property (strong, nonatomic) IBOutlet UILabel *labelCounterY;
@property (strong, nonatomic) IBOutlet UILabel *labelCounterZ;

@property (strong, nonatomic) IBOutlet UILabel *labelYawDegrees;
@property (strong, nonatomic) IBOutlet UILabel *labelPitchDegrees;
@property (strong, nonatomic) IBOutlet UILabel *labelRollDegrees;

- (IBAction)toggleGyro:(id)sender;

@end

Stop/start button is really basic stuff if button says “Start” than you need to start gyro readings, and write “Stop” on it and vice versa, you get the idea.

- (IBAction)toggleGyro:(UIButton*)sender {

    if ([[sender titleForState:UIControlStateNormal] isEqualToString:@"Stop"]) {
        [self stopGyro];
        [sender setTitle:@"Start" forState:UIControlStateNormal];
    } else {
        [self startGyro];
        [sender setTitle:@"Stop" forState:UIControlStateNormal];
    }
}

You should now have basic UI and essential user interaction. So, fire up the gyro! Most important class is CCMotionManager, instantiate it and store the object in your UIViewController subclass. There are 4 types of data this class can monitor; acceleration, rotation acceleration, attitude and magnetism. Who needs all that? I wanted only rotation acceleration and attitude. Just set desired update interval for each data type you want to monitor, and update labels with new data in block methods of your CCMotionManager object. You’ll also need to define how degrees are calculated.

#define degrees(x) (180 * x / M_PI)

- (void)startGyro {

    if (motionManager) {
        [self stopGyro];
    }

    motionManager = [[CMMotionManager alloc] init];
    motionManager.gyroUpdateInterval = 0.01;
    motionManager.deviceMotionUpdateInterval = 0.01;

    if ([motionManager isGyroAvailable]) {
        [motionManager startGyroUpdatesToQueue:[NSOperationQueue mainQueue]
            withHandler:^(CMGyroData *gyroData, NSError *error) {
                _labelCounterX.text = [NSString stringWithFormat:@"%.3f",
                    gyroData.rotationRate.x];
                _labelCounterY.text = [NSString stringWithFormat:@"%.3f",
                    gyroData.rotationRate.y];
                _labelCounterZ.text = [NSString stringWithFormat:@"%.3f",
                    gyroData.rotationRate.z];
        }];
        [motionManager startDeviceMotionUpdatesToQueue:
            [NSOperationQueue mainQueue]
            withHandler:^(CMDeviceMotion *motion, NSError *error) {
                CMAttitude *attitude = motion.attitude;
                _labelYawDegrees.text = [NSString stringWithFormat:@"%.3f",
                    degrees(attitude.yaw)];
                _labelPitchDegrees.text = [NSString stringWithFormat:@"%.3f",
                    degrees(attitude.pitch)];
                _labelRollDegrees.text = [NSString stringWithFormat:@"%.3f",
                    degrees(attitude.roll)];
        }];
    }
}

Since all good things come to an end, so needs the gyro. Stoping gyro is easy, just stop updates for all data types that you started monitoring and set your CCMotionManager object to nil, so that memory can be freed.

- (void)stopGyro {

    [motionManager stopGyroUpdates];
    [motionManager stopDeviceMotionUpdates];
    motionManager = nil
}
Leave Your Comment

You’re more than welcome to leave your own comment!

Just please, pretty please: don’t spam. Thank you :)