一: 介紹
近幾年,智慧裝置越來越火,這些智慧裝置中,有很大一部分是通過手機來控制硬體裝置,來達到預期的效果,這中間少不了要使用到藍芽功能,通過藍芽來通訊來控制裝置。
藍芽分為藍芽2.0和藍芽4.0。 藍芽2.0為傳統藍芽,傳統藍芽也稱為經典藍芽。 藍芽4.0因為低耗電,所以也叫做低功耗藍(BLE),它將三種規格集一體,包括傳統藍芽技術、高速技術和低耗能技術。
這篇文章用來介紹BLE 4.0的使用以及相關問題的解決。
二:BLE的兩種模式
BLE的兩種模式分為CBCentralMannager 中心模式 和CBPeripheralManager 外設模式,在這裡主要和大家分享CBCentralMannager 中心模式的開發和使用。
CBCentralMannager 中心模式
以手機(app)作為中心,連線其他外設的場景。詳細流程如下:
- 建立中心角色
- 掃描外設
- 發現外設
- 連線外設 4.1 連線失敗 4.2 連線斷開 4.3 連線成功
- 掃描外設中的服務 5.1 發現並獲取外設中的服務
- 掃描外設對應服務的特徵 6.1 發現並獲取外設對應服務的特徵 6.2 給對應特徵寫資料
- 訂閱特徵的通知 7.1 根據特徵讀取資料
CBPeripheralManager 外設模式
使用手機作為外設連線其他中心裝置操作的場景。 PS:因為蘋果裝置的安全性和封閉性,蘋果裝置不能通過與其他裝置藍芽連結進行檔案傳輸等功能,所以在iOS與藍芽開發的程式設計中是CBCentralMannager 中心模式程式設計居多.
- 建立外設角色
- 設定本地外設的服務和特徵
- 釋出外設和特徵
- 廣播服務
- 響應中心的讀寫請求
- 傳送更新的特徵值,訂閱中心
三:BLE開發步驟
在介紹CBCentralMannager 中心模式開發步驟之前,首先需要對專案進行如下配置:
#import "ESPFBYBLEHelper.h"
#import <CoreBluetooth/CoreBluetooth.h>
@interface ESPFBYBLEHelper ()<CBCentralManagerDelegate,CBPeripheralDelegate>
// 中心管理者(管理裝置的掃描和連線)
@property (nonatomic, strong) CBCentralManager *centralManager;
// 儲存的裝置
@property (nonatomic, strong) NSMutableArray *peripherals;
// 掃描到的裝置
@property (nonatomic, strong) CBPeripheral *cbPeripheral;
// 外設狀態
@property (nonatomic, assign) CBManagerState peripheralState;
@end
// 藍芽4.0裝置名
static NSString * const kBlePeripheralName = @"lighte290";
// 通知服務
static NSString * const kNotifyServerUUID = @"FF03";
// 寫服務
static NSString * const kWriteServerUUID = @"FFFF";
// 通知特徵值
static NSString * const kNotifyCharacteristicUUID = @"FF05";
// 寫特徵值
static NSString * const kWriteCharacteristicUUID = @"FF08";
@implementation ESPFBYBLEHelper
複製程式碼
這其中需要匯入CoreBluetooth框架
#import <CoreBluetooth/CoreBluetooth.h>
複製程式碼
遵守CBCentralManagerDelegate,CBPeripheralDelegate協議
@interface ESPFBYBLEHelper ()<CBCentralManagerDelegate,CBPeripheralDelegate>
複製程式碼
然後需要檢測藍芽狀態,程式碼如下:
// 狀態更新時呼叫
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
switch (central.state) {
case CBManagerStateUnknown:{
NSLog(@"為知狀態");
self.peripheralState = central.state;
}
break;
case CBManagerStateResetting:
{
NSLog(@"重置狀態");
self.peripheralState = central.state;
}
break;
case CBManagerStateUnsupported:
{
NSLog(@"不支援的狀態");
self.peripheralState = central.state;
}
break;
case CBManagerStateUnauthorized:
{
NSLog(@"未授權的狀態");
self.peripheralState = central.state;
}
break;
case CBManagerStatePoweredOff:
{
NSLog(@"關閉狀態");
self.peripheralState = central.state;
}
break;
case CBManagerStatePoweredOn:
{
NSLog(@"開啟狀態-可用狀態");
self.peripheralState = central.state;
NSLog(@"%ld",(long)self.peripheralState);
}
break;
default:
break;
}
}
複製程式碼
新增屬性和常量,常量需要根據自己的專案來進行配置。 下面只需要根據實現流程一步步實現即可,核心程式碼如下:
1. 建立中心角色
self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
複製程式碼
2. 掃描外設
if (self.peripheralState == CBManagerStatePoweredOn){
[self.centralManager scanForPeripheralsWithServices:nil options:nil];
}
複製程式碼
3. 發現外設
/**
掃描到裝置
@param central 中心管理者
@param peripheral 掃描到的裝置
@param advertisementData 廣告資訊
@param RSSI 訊號強度
*/
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI
{
NSLog(@"%@",[NSString stringWithFormat:@"發現裝置,裝置名:%@",peripheral.name]);
}
複製程式碼
4. 連線外設
[self.centralManager connectPeripheral:peripheral options:nil];
複製程式碼
- 4.1 連線失敗 didFailToConnectPeripheral
/**
連線失敗
@param central 中心管理者
@param peripheral 連線失敗的裝置
@param error 錯誤資訊
*/
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
NSLog(@"%@",@"連線失敗");
}
複製程式碼
- 4.2 連線斷開
/**
連線斷開
@param central 中心管理者
@param peripheral 連線斷開的裝置
@param error 錯誤資訊
*/
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
NSLog(@"%@",@"斷開連線");
}
複製程式碼
- 4.3 連線成功
/**
連線成功
@param central 中心管理者
@param peripheral 連線成功的裝置
*/
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
NSLog(@"連線裝置:%@成功",peripheral.name);
[self.centralManager stopScan];
}
複製程式碼
5. 掃描外設中的服務
// 設定裝置的代理
peripheral.delegate = self;
// services:傳入nil 代表掃描所有服務
[peripheral discoverServices:nil];
複製程式碼
5.1 發現並獲取外設中的服務
/**
掃描到服務
@param peripheral 服務對應的裝置
@param error 掃描錯誤資訊
*/
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
// 遍歷所有的服務
for (CBService *service in peripheral.services)
{
NSLog(@"服務:%@",service.UUID.UUIDString);
}
}
複製程式碼
6. 掃描外設對應服務的特徵
// 獲取對應的服務
if (![service.UUID.UUIDString isEqualToString:kWriteServerUUID])
{
return;
}
// 根據服務去掃描特徵
[peripheral discoverCharacteristics:nil forService:service];
複製程式碼
6.1 發現並獲取外設對應服務的特徵
/**
掃描到對應的特徵
@param peripheral 裝置
@param service 特徵對應的服務
@param error 錯誤資訊
*/
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
NSLog(@"%@",peripheral);
}
複製程式碼
6.2 給對應特徵寫資料
[peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
複製程式碼
7. 訂閱特徵的通知
if ([characteristic.UUID.UUIDString isEqualToString:kNotifyCharacteristicUUID]){
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
複製程式碼
7.1 根據特徵讀取資料 didUpdateValueForCharacteristic
/**
根據特徵讀到資料
@param peripheral 讀取到資料對應的裝置
@param characteristic 特徵
@param error 錯誤資訊
*/
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(nonnull CBCharacteristic *)characteristic error:(nullable NSError *)error
{
if ([characteristic.UUID.UUIDString isEqualToString:kNotifyCharacteristicUUID])
{
NSData *data = characteristic.value;
NSLog(@"%@",data);
}
}
複製程式碼
四:原始碼Demo獲取方法
如果需要原始碼demo,歡迎關注 【網羅開發】微信公眾號,回覆【94】便可領取。 網羅天下方法,方便你我開發,所有文件會持續更新,歡迎關注一起成長!
歡迎關注公眾號「網羅開發」