iOS-加速計 傳感器 藍牙

一.加速計

加速計的作用

用於檢測設備的運動(比如搖晃)

加速計的經典應用場景

搖一搖
計步器 

加速計的原理

檢測設備在XYZ軸上的加速度 (哪個方向有力的作用,哪個方向運動了)

根據加速度數值,就可以判斷出在各個方向上的作用力度 


各個方向上,加速度的大小如下( 加速度的取值在 (-1,1) 之間 


加速計程序的開發

加速計程序的開發
iOS5以前:使用UIAccelerometer,用法非常簡單

iOS5開始:CoreMotion.framework

雖然UIAccelerometer已經過期,但由於其用法極其簡單,很多程序裏面都還有殘留 


1.使用UIAccelerometer實現手機晃動的時候,小球的位置都是跟着重力的往下掉,並且碰到屏幕邊緣回彈

UIAccelerometer的使用代碼如下:

//  HMViewController.m

#import "HMViewController.h"
#import "UIView+Extension.h"

@interface HMViewController () <UIAccelerometerDelegate>
@property (weak, nonatomic) IBOutlet UIImageView *ball;
@property (nonatomic, assign) CGPoint velocity;
@end

@implementation HMViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    // 1.獲得單例對象(過期:不再更新,並不一定代表不能用)
    UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];
    
    // 2.設置代理
    accelerometer.delegate = self;
    
    // 3.設置採樣間隔(每隔多少秒採樣一次數據)
    accelerometer.updateInterval = 1 / 30.0;
}

#pragma mark - UIAccelerometerDelegate
/**
 *  當採樣到加速計數據時,就會調用一次(調用頻率一般比較高)
 */
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
    // 1.累加速度
    // v = a * t = a1 + a2 + a3 + ...... + at
    _velocity.x += acceleration.x;
    _velocity.y -= acceleration.y;
    
    // 2.累加位移
    // s = v * t = v1 + v2 + v3 + ...... + vt
    self.ball.x += _velocity.x;
    self.ball.y += _velocity.y;
    
    // 3.邊界判斷
    if (self.ball.x <= 0) { // x超出屏幕左邊
        self.ball.x = 0;
        // 速度取反,削弱速度
        _velocity.x *= -0.5;
    }
    if (self.ball.maxX >= self.view.width) { // x超出屏幕右邊
        self.ball.maxX = self.view.width;
        
        // 速度取反,削弱速度
        _velocity.x *= -0.5;
    }
    if (self.ball.y <= 0) { // y超出屏幕上邊
        self.ball.y = 0;
        // 速度取反,削弱速度
        _velocity.y *= -0.5;
    }
    if (self.ball.maxY >= self.view.height) { // y超出屏幕下邊
        self.ball.maxY = self.view.height;
        // 速度取反,削弱速度
        _velocity.y *= -0.5;
    }
}
@end
晃動手機的時候效果圖如下:



2.CoreMotion.framework的使用

①.CoreMotion簡介


②.push和pull的區別


使用代碼如下:

//  HMViewController.m

#import "HMViewController.h"
#import <CoreMotion/CoreMotion.h>

@interface HMViewController ()
@property (nonatomic, strong) CMMotionManager *mgr;
@end

@implementation HMViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    // 1.創建motion管理者
    self.mgr = [[CMMotionManager alloc] init];
    
    // 2.判斷加速計是否可用
    if (self.mgr.isAccelerometerAvailable) {
        [self pull];
    } else {
        NSLog(@"---加速計不可用-----");
    }
}
/**
 * ******* pull *******
 */
- (void)pull
{
    [self.mgr startAccelerometerUpdates];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    CMAcceleration acceleration = self.mgr.accelerometerData.acceleration;
    NSLog(@"%f %f %f", acceleration.x, acceleration.y, acceleration.z);
}

/**
 * ******* push *******
 */
- (void)push
{
    // 3.設置採樣間隔
    self.mgr.accelerometerUpdateInterval = 1 / 30.0;
    
    // 4.開始採樣(採集加速度數據)
    [self.mgr startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
        // 如果在block中執行較好時的操作,queue最好不是主隊列
        // 如果在block中要刷新UI界面,queue最好是主隊列
        NSLog(@"%f %f %f", accelerometerData.acceleration.x, accelerometerData.acceleration.y, accelerometerData.acceleration.z);
    }];
}

@end


3.搖一搖的功能實現

使用iOS自帶的shake搖晃的API實現,只要是響應者就能監聽這方法

代碼如下:

//  HMViewController.m

#import "HMViewController.h"

@interface HMViewController ()

@end

@implementation HMViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
}

#pragma mark - 實現相應的響應者方法
/** 開始搖一搖 */
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    NSLog(@"motionBegan");
}

/** 搖一搖結束(需要在這裏處理結束後的代碼) */
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    // 不是搖一搖運動事件
    if (motion != UIEventSubtypeMotionShake) return;
    
    NSLog(@"motionEnded");
}

/** 搖一搖取消(被中斷,比如突然來電) */
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    NSLog(@"motionCancelled");
}
@end

二.傳感器

1.傳感器介紹

什麼是傳感器
●  傳感器是一種感應\檢測裝置,目前已經廣泛應用於智能手機上
●  傳感器的作用
●  用於感應\檢測設備周邊的信息
●  不同類型的傳感器,檢測的信息也不一樣
●  iPhone中的下面現象都是由傳感器完成的
●  在地圖應用中,能判斷出手機頭面向的方向
●  一關燈, iPhone會自動降低亮度讓屏幕顯得不是那麼刺眼
●  打電話時,人臉貼近iPhone屏幕時,屏幕會自動鎖屏,達到省電的目的 

傳感器的類型

●  iPhone5中內置的傳感器有
●  運動傳感器\加速度傳感器\加速計(Motion/Accelerometer Sensor)
●  環境光傳感器(Ambient Light Sensor)
●  距離傳感器(Proximity Sensor)
●  磁力計傳感器(Magnetometer Sensor)
●  內部溫度傳感器(Internal Temperature Sensor)
●  溼度傳感器(Moisture Sensor)
●  陀螺儀(Gyroscope

環境光傳感 (Ambient Light Sensor)

●  iOSMac設備中最爲古老的傳感器成員
●  它能夠讓你在使用MaciPhoneiPad時,眼睛更爲舒適

●  從一個明亮的室外走入相對黑暗的室內後,iOS設備會自動調低亮度,讓屏幕顯得不再那麼光亮刺眼

●  當你使用iPhone拍照時,閃光燈會在一定條件下自動開啓
●  幾乎所有的Mac都帶有背光鍵盤,當週圍光線弱到一定條件時,會自動開啓鍵盤背光

距離傳感 (Proximity Sensor)

●  用於檢測是否有其他物體靠近設備屏幕
●  當你打電話或接電話時將電話屏幕貼近耳邊,iPhone會自動關閉屏幕 ,好處是
●  節省電量
●  防止耳朵或面部不小心觸摸屏幕而引發一些不想要的意外操作 

磁力計傳感 (Magnetometer Sensor)

可以感應地球磁場, 獲得方向信息, 使位置服務數據更精準可以用於電子羅盤和導航應用
iPadSmart Cover盒蓋睡眠操作就是基於磁力計傳感器 

內部溫度傳感 (Internal Temperature Sensor)
iPad一代開始,iOS設備都加入了一個內部溫度傳感器,用於檢測內部組件
溫度,當溫度超過系統設定的閾值時,會出現以下提示

內部溫度傳感器,對於提升iOS設備自身安全性與穩定性有很大的幫助 

溼度傳感 (Moisture Sensor)
溼度傳感器跟其他基於微電子的傳感器不同,是一個簡單的物理傳感器

簡單來說,溼度傳感器就是一張遇水變紅的試紙
Apple的維修人員就是通過檢測試紙是否變紅,來判斷設備是否進水

陀螺儀(Gyroscope)
陀螺儀是隨着iPhone4的上市首次出現在iOS設備上的傳感器
陀螺儀可以用於檢測設備的持握方式
陀螺儀的原理是檢測設備在XYZ軸上所旋轉的角速度
陀螺儀在賽車類遊戲中有重大作用

模擬汽車駕駛時方向盤旋轉的動作

使得這類遊戲的操控體驗更爲真實

運動傳感\加速度傳感\加速計(Motion/Accelerometer Sensor)

最早出現在iOS設備上的傳感器之一

加速計用於檢測設備在XYZ軸上的加速度 (哪個方向有力的作用)

加速計可以用於檢測設備的搖晃,經典應用場景

搖一搖  計步器 

距離傳感器的使用:

//  HMViewController.m

#import "HMViewController.h"

@interface HMViewController ()

@end

@implementation HMViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    // 打開距離傳感器,開啓距離檢測功能
//    [UIApplication sharedApplication].proximitySensingEnabled = YES; 過期
    [UIDevice currentDevice].proximityMonitoringEnabled = YES;
    
    // 監聽距離改變
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(proximityStateDidChange:) name:UIDeviceProximityStateDidChangeNotification object:nil];
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)proximityStateDidChange:(NSNotification *)note
{
    if ([UIDevice currentDevice].proximityState) {
        NSLog(@"有物體靠近設備屏幕");
    } else {
        NSLog(@"有物體遠離設備屏幕");
    }
}
@end

三.藍牙

iOS中藍牙的實現方案


1.GameKit的使用

要求:在模擬器和真機家裏連接,選擇真機裏的圖片.顯示到imageView上,點擊發送,發送到模擬器上,模擬器把圖片保存到相冊

如下圖:



代碼如下:

//  HMViewController.m

#import "HMViewController.h"
#import <GameKit/GameKit.h>

@interface HMViewController () <GKPeerPickerControllerDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate>
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@property (nonatomic, strong) GKSession *session;
- (IBAction)buildConnect;
- (IBAction)sendData;
//點擊imageView的手勢
- (IBAction)selectImage:(UITapGestureRecognizer *)sender;
@end

@implementation HMViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
}

//建立連接
- (IBAction)buildConnect {
    // 1.創建設備列表控制器
    GKPeerPickerController *ppc = [[GKPeerPickerController alloc] init];
    
    // 2.設置代理
    ppc.delegate = self;
    
    // 3.顯示控制器
    [ppc show];
}

//發送數據
- (IBAction)sendData {
    if (self.imageView.image == nil) return;
    
    // 壓縮圖片數據
    NSData *data = UIImagePNGRepresentation(self.imageView.image);
//    Pet *p = [];
//    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:p];
    
    // 發送數據
    [self.session sendDataToAllPeers:data withDataMode:GKSendDataReliable error:nil];
}

//點擊imageView的的手勢
- (IBAction)selectImage:(UITapGestureRecognizer *)sender {
    if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) return;
    
    // 1.創建圖片選擇控制器
    UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
    ipc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    
    // 2.設置代理
    ipc.delegate = self;
    
    // 3.顯示
    [self presentViewController:ipc animated:YES completion:nil];
}

#pragma mark - 監聽圖片選擇
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    // 1.銷燬圖片選擇控制器
    [picker dismissViewControllerAnimated:YES completion:nil];
    
    // 2.顯示圖片
    self.imageView.image = info[UIImagePickerControllerOriginalImage];
}

#pragma mark - GKPeerPickerControllerDelegate
/**
 *  連接到某個設備就會調用
 *
 *  @param peerID  設備的藍牙ID
 *  @param session 連接會話(通過session傳輸和接收數據)
 */
- (void)peerPickerController:(GKPeerPickerController *)picker didConnectPeer:(NSString *)peerID toSession:(GKSession *)session
{
    // 1.銷燬顯示設備的控制器
    [picker dismiss];
    
    // 2.保存session
    self.session = session;
    
    // 3.處理接收的數據(接收到藍牙設備傳輸的數據時,就會調用self的receiveData:fromPeer:inSession:context:)
    [self.session setDataReceiveHandler:self withContext:nil];
}

#pragma mark - 接收到藍牙設備傳輸的數據,就會調用
- (void)receiveData:(NSData *)data fromPeer:(NSString *)peer inSession:(GKSession *)session context:(void *)context
{
    self.imageView.image = [UIImage imageWithData:data];
    
    // 寫入相冊
    UIImageWriteToSavedPhotosAlbum(self.imageView.image, nil, nil, nil);
}
@end


2.CoreBluetooth的使用

①.CoreBluetooth


②.核心類


③.CoreBuletooth基本常識


④.開發步驟



代碼實現步驟如下:

//  HMViewController.m

#import "HMViewController.h"
#import <CoreBluetooth/CoreBluetooth.h>

@interface HMViewController () <CBCentralManagerDelegate, CBPeripheralDelegate>
@property (nonatomic, strong) CBCentralManager *mgr;
@property (nonatomic, strong) NSMutableArray *peripherals;

@property (nonatomic, strong) CBCharacteristic *dataInteractCharacteristic;
@property (nonatomic, strong) CBCharacteristic *peripheralInfoCharacteristic;
@end

@implementation HMViewController

- (NSMutableArray *)peripherals
{
    if (!_peripherals) {
        self.peripherals = [NSMutableArray array];
    }
    return _peripherals;
}

- (CBCentralManager *)mgr
{
    if (!_mgr) {
        // 1.創建中心設備管理者,用來管理中心設備
        self.mgr = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
    }
    return _mgr;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    // 2.掃描外設
#warning 通過傳入一個存放服務UDID的數組進去,過濾掉一些不要的外設
    [self.mgr scanForPeripheralsWithServices:@[@"434", @"435435"] options:nil];
}

/**
 *  3.點擊按鈕,建立連接
 */
- (void)buildConnect
{
    for (CBPeripheral *peripheral in self.peripherals) {
        [self.mgr connectPeripheral:peripheral options:nil];
    }
}


#pragma mark - CBCentralManagerDelegate
/**
 *  掃描後,發現外圍設備的時候調用
 */
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
    // 添加外圍設備
    if (![self.peripherals containsObject:peripheral]) {
        // 設置外設的代理
        peripheral.delegate = self;
        [self.peripherals addObject:peripheral];
    }
}

/**
 *  連接到某個外設的時候調用
 */
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
    // 查找外設中的所有服務
#warning 通過傳入一個存放服務UDID的數組進去,過濾掉一些不要的服務
    [peripheral discoverServices:@[@"434", @"435435"]];
}

/**
 *  跟某個外設失去連接
 */
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{

}

#pragma mark - CBPeripheralDelegate
/**
 *  外設已經查找到服務
 */
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
    // 遍歷所有的服務
    for (CBService *service in peripheral.services) {
        // 過濾掉不想要的服務
        if ([service.UUID isEqual:@"123"]) {
            // 找到想要的服務
            
            // 掃描服務下面的特徵
#warning 通過傳入一個存放特徵UDID的數組進去,過濾掉一些不要的特徵
            [peripheral discoverCharacteristics:@[@"435", @"6456"] forService:service];
        }
    }
}
//查找到特徵的時候調用
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
    // 遍歷所有的特徵
    for (CBCharacteristic *characteristic in service.characteristics) {
        // 過濾掉不想要的特徵
        if ([characteristic.UUID isEqual:@"456"]) {
            // 找到想要的特徵
            self.dataInteractCharacteristic = characteristic;
        } else if ([characteristic.UUID isEqual:@"789"]) {
            self.peripheralInfoCharacteristic = characteristic;
        }
    }
}
@end

補充:藍牙現狀




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章