藍牙 BLE CoreBluetooth 初探
藍牙
Bluetooth 4.0之後就將通訊模式分為高速及低速,低速低耗能簡稱為BLE,可以連接一些量測型的感測器類型像:心跳計、血壓…等,使得iDevice可以不用再使用Dock方式製作產品,也不需要再經過MFi認證才能與iDevice連接,如此一來可以增加APP型態的多元,也能間階的降低一些成本,如果想要跟BLE週邊連接,iOS 5之後提供corebluetooth framework與週邊連接,整流程中為Discover、Connect、Explore、Interact,下面文章將會從iDevice連線至BLE周邊讀取資料為例子介紹。
Discover/Connect

依照箭頭方向由上而下為順序依序完成Discover、Connect流程。
CBCentralManager
使用CoreBluetooth Framework中,主要管理連線的是CBCentralManager這個Object,它掌控整個BLE狀態的管理,使用時要先對CBCentralManager初始化:
CBCentralManager *CM = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
現在就開始往下介紹。
centralManagerDidUpdateState
在一開始宣告初CBCentralManager時就有指定Delegate為self,並且必需要在.h內加上Delegate宣告:
@interface TestCoreBluetooth : NSObject<CBCentralManagerDelegate> {
:
:
:
}
宣告完成後,再加入centralManagerDidUpdateState這個Delegate內容,
-(void)centralManagerDidUpdateState:(CBCentralManager*)cManager
{
NSMutableString* nsmstring=[NSMutableString stringWithString:@"UpdateState:"];
BOOL isWork=FALSE;
switch (cManager.state) {
case CBCentralManagerStateUnknown:
[nsmstring appendString:@"Unknown\n"];
break;
case CBCentralManagerStateUnsupported:
[nsmstring appendString:@"Unsupported\n"];
break;
case CBCentralManagerStateUnauthorized:
[nsmstring appendString:@"Unauthorized\n"];
break;
case CBCentralManagerStateResetting:
[nsmstring appendString:@"Resetting\n"];
break;
case CBCentralManagerStatePoweredOff:
[nsmstring appendString:@"PoweredOff\n"];
if (connectedPeripheral!=NULL){
[CM cancelPeripheralConnection:connectedPeripheral];
}
break;
case CBCentralManagerStatePoweredOn:
[nsmstring appendString:@"PoweredOn\n"];
isWork=TRUE;
break;
default:
[nsmstring appendString:@"none\n"];
break;
}
NSLog(@"%@",nsmstring);
[delegate didUpdateState:isWork message:nsmstring getStatus:cManager.state];
}
centralManagerDidUpdateState的Delegate是用來得知藍牙目前的狀態,所以會有個結果是用來判斷iDevice是否支援BLE,因為BLE是在iphone 4s、New iPad之後才有的,現階段還是需要偵測使用的環境,當然可以根據這些狀態的口報來決定APP的功能或其他提示使用者的動作。
scanForPeripheralsWithServices
先前確定周邊支援BLE且運作正常後,我們就要來開啟BLE搜尋功能來尋找BLE的週邊,當週邊接收到搜尋功能的廣播訊息時,依照BLE通訊規範,週邊會在一定時間內回覆,所以我們在此可以設定2秒的Timer計時器,當時間一到就停止scan的功能。
CBCentralManager *CM = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
[CM scanForPeripheralsWithServices:nil options:options];
[NSTimer scheduledTimerWithTimeInterval:2.0f target:self selector:@selector(scanTimeout:) userInfo:nil repeats:NO];
設定2秒後觸發執行scanTimeoutmethod,再將scanForPeripheralsWithServices的值設為nil,代表搜尋的Service type不受限制,當你搜尋特定時,就必需要將它的UUID填入,像範例這樣:
NSArray *uuidArray= [NSArray arrayWithObjects:[CBUUID UUIDWithString:@"180D"], nil];
[CM scanForPeripheralsWithServices:uuidArray options:options];
其中UUIDWithString:@"180D"的180D就是Heart Rate Service type,一旦指定Service type,結果就只會將週邊有Heart Rate類型一一列出來,要了解更多的Service Type可以到Bluetooth官網查詢。
當您了解Service type是哪一種類型時就可以來做對應的流程及資料的解析,也可以製作出符合一般標準週邊的通用APP。
didDiscoverPeripheral
didDiscoverPeripheral屬於Delegate功能,所以要按照它預設的宣告將要處理的過程寫在裡面,格式如下:
-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
//處理過程
}
advertisementData會報告可以連線的週邊內容, 如果將它印出來會像這樣:
adverisement:{
kCBAdvDataLocalName = "INFOS 4090v35.05";
kCBAdvDataServiceUUIDs = (
"Unknown (<fff0>)"
);
kCBAdvDataTxPowerLevel = 0;
}
RSSI是訊號的強度,是以NSNumber Object存在,取得後可以依照NSNumber的方式整數值做處理與轉換,接下來我們將一些資訊列印出來,整個範例可以是這樣子:
-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
NSMutableString* nsmstring=[NSMutableString stringWithString:@"\n"];
[nsmstring appendString:@"Peripheral Info:"];
[nsmstring appendFormat:@"NAME: %@\n",peripheral.name];
[nsmstring appendFormat:@"RSSI: %@\n",RSSI];
if (peripheral.isConnected){
[nsmstring appendString:@"isConnected: connected"];
}else{
[nsmstring appendString:@"isConnected: disconnected"];
}
NSLog(@"adverisement:%@",advertisementData);
[nsmstring appendFormat:@"adverisement:%@",advertisementData];
[nsmstring appendString:@"didDiscoverPeripheral\n"];
NSLog(@"%@",nsmstring);
}
結果輸出:
2013-02-25 14:43:17.243 gw-health-01[141:907]
Peripheral Info:NAME: INFOS 4090v35.05
RSSI: -69
isConnected: disconnected
adverisement:{
kCBAdvDataServiceUUIDs = (
"Unknown (<fff0>)"
);
}
如果有發現可連線的BLE週邊,它就會不斷的執行didDiscoverPeripheral,並將資訊傳入,利用這個方式將每次得到的結果存入Array,就可以得到搜尋周邊的結果然後再提供給USER選擇,或是從中可以去判斷某個特別的週邊是否存在而決定要不要連線。
stopScan
執行scanForPeripheralsWithServices 掃描周邊設定2秒的Timer,當時間到時就停止scan,一般2秒內無反應就可以當作是沒有其他週邊回應,承上面scanForPeripheralsWithServices中有設定Timer去呼叫scanTimeout,所以將stopScan寫在scanTimeout裡面:
- (void) scanTimeout:(NSTimer*)timer
{
if (CM!=NULL){
[CM stopScan];
}else{
NSLog(@"CM is Null!");
}
NSLog(@"scanTimeout");
}
connectPeripheral
didDiscoverPeripheral得到的BLE週邊列表讓User選擇要連線的BLE,再將 CBPeripheral傳入connectPeripheral進行連線,格式:
[CBCentralManager connectPeripheral:CBPeripheral* options:NSDictionary*]
在此將它包裝成一個connect Method,
- (void) connect:(CBPeripheral*)peripheral
{
if (![peripheral isConnected]) {
[CM connectPeripheral:peripheral options:nil];
connectedPeripheral=peripheral;
}
}
option傳入nil,connectPeripheral傳入Method connect的值。
didConnectPeripheral
執行connectPeripheral之後並連線成功後就會引發didConnectPeripheral的Delegate:
-(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
:
:
:
}
在這裡有個重點,連線成功後引發Delegate時,就必需要針對其CBPeripheral馬上進行discoverServices的動作,去了解週邊提供什麼樣的Services
執行discoverServices之後又會引發另一個didDiscoverServicesDelegate,不過這會在Explore中介紹。
Explore

Discover/Connect 中使用CBCentralManager進行連線/搜尋BLE周邊的功能,連線之後需要靠的是CBPeripheral來傳送/接收資料。
CBPeripheral
@interface DYCoreBluetooth : NSObject<CBCentralManagerDelegate, CBPeripheralDelegate> {
:
:
:
}
之後連線的重點全都是在Delegate的互動,查看Service Type或是有什麼樣的Services可以提供。
didConnectPeripheral
前面有稍為介紹didConnectPeripheral,這是在連線成功後就會引發的Delegate,但一定要在這裡執行一些Method才可以順利的引發另一個CBPeripheral的Delegate去查看有什麼樣的Services
-(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
NSLog(@"Connect To Peripheral with name: %@\nwith UUID:%@\n",peripheral.name,CFUUIDCreateString(NULL, peripheral.UUID));
peripheral.delegate=self;
[peripheral discoverServices:nil];//一定要執行"discoverService"功能去尋找可用的Service
}
例子中已經將peripheral.delegate=self,接下來進行peripheral的任何動做引發的Delegate都在這個Object中,執行discoverServicesMethod,讓它去尋找Services,一找到Services就又會引發didDiscoverServicesDelegate,這樣我們就可以了解有什麼Services。
didDiscoverServices
從這裡開始就是最關鍵
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
NSLog(@"didDiscoverServices:\n");
if( peripheral.UUID == NULL ) return; // zach ios6 added
if (!error) {
NSLog(@"====%@\n",peripheral.name);
NSLog(@"=========== %d of service for UUID %@ ===========\n",peripheral.services.count,CFUUIDCreateString(NULL,peripheral.UUID));
for (CBService *p in peripheral.services){
NSLog(@"Service found with UUID: %@\n", p.UUID);
[peripheral discoverCharacteristics:nil forService:p];
}
}
else {
NSLog(@"Service discovery was unsuccessfull !\n");
}
}
peripheral.services.count會知道有多少個Services,在每個Servces中還會有Characteristics需要了解,所以會針對每個Service來執行 peripheral discoverCharacteristics: forService:去知道每個Service下有多少個Characteristics提供傳送/接收的溝通,在執行discoverCharacteristics後也引發didDiscoverCharacteristicsForService Delegate,最後再由didDiscoverCharacteristicsForService真正的判斷什麼樣的Service、什麼樣的Characteristic再進行之後收到的資料的處理動作,例如: 發現2A37的Characteristic,就要進行註冊通知,到時候BLE週邊發訊息過來才會立即的得到通知並得到資料。
didDiscoverCharacteristicsForService
整個最關鍵的地方就是這個Delegate,程式架構如下:
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
:
:
:
}
Interact

完成didDiscoverCharacteristicsForService之後,整個連線過程算是完成,之後的didUpdateValueForCharacteristicDelegate是整個資料接收動作都在這發生,經過接收到的資料進行即時處理就可以取得BLE週邊的訊息,如果必需要將資料傳至BLE週邊時,再使用writeValue的Method將資料出,以上為BLE連線最基本使用方式就大致上完成。
didDiscoverCharacteristicsForService
由Apple提供的資料擷取某部分來了解架構,等下程式就是利用這架構去尋訪所有的CharacteristicsForService

每個Servic下都會有很多的Characteristics,Characteristics是提供資料傳遞的重點,它會有個UUID編號,再由這個編號去Bluetooth 官方查表得到是哪種資料格式,知道格式後就能去將資料解開並加以使用。
真正的例子:
-(void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
CBService *s = [peripheral.services objectAtIndex:(peripheral.services.count - 1)];
NSLog(@"=========== Service UUID %s ===========\n",[self CBUUIDToString:service.UUID]);
if (!error) {
NSLog(@"=========== %d Characteristics of service ",service.characteristics.count);
for(CBCharacteristic *c in service.characteristics){
NSLog(@" %s \n",[ self CBUUIDToString:c.UUID]);
// CBService *s = [peripheral.services objectAtIndex:(peripheral.services.count - 1)];
if(service.UUID == NULL || s.UUID == NULL) return; // zach ios6 added
//Register notification
if ([service.UUID isEqual:[CBUUID UUIDWithString:@"180D"]])
{
if ([c.UUID isEqual:[CBUUID UUIDWithString:@"2A37"]])
{
[self notification:service.UUID characteristicUUID:c.UUID peripheral:peripheral on:YES];
NSLog(@"registered notification 2A37");
}
if ([c.UUID isEqual:[CBUUID UUIDWithString:@"2A38"]])
{
[self notification:service.UUID characteristicUUID:c.UUID peripheral:peripheral on:YES];
NSLog(@"registered notification 2A38");
}
if ([c.UUID isEqual:[CBUUID UUIDWithString:@"2A39"]])
{
[self notification:service.UUID characteristicUUID:c.UUID peripheral:peripheral on:YES];
NSLog(@"registered notification 2A39");
}
}
}
NSLog(@"=== Finished set notification ===\n");
}
else {
NSLog(@"Characteristic discorvery unsuccessfull !\n");
}
if([self compareCBUUID:service.UUID UUID2:s.UUID]) {//利用此來確定整個流程都結束後才能設定通知
[delegate didConnected:peripheral error:error];
NSLog(@"=== Finished discovering characteristics ===\n");
//全部服務都讀取完畢時才能使用!
}
}
上面 例子是以Heart Rate(180D)為主,

Heart Rate的規格來說,0x2A37可以得到心跳的數據,所以針對此項進行註冊通知,一旦有新的數據就會傳入新的數據資料並呼叫didUpdateValueForCharacteristicDelegate,來得到每次的心跳數據更新。
[(CBPeripheral *)p setNotifyValue:(BOOL) forCharacteristic:CBCharacteristic *)]
將Characteristic的Point傳入並設定setNotifyValue:on就完成註冊通知,之後如果有更新資料時就會引發didUpdateValueForCharacteristic Delegate,再進行資料處理。
notification
在設定註冊通知過程有點繁雜,所以我自行撰寫一個Method為notification,它可以從Service UUID及Characteristic UUID來找到Service與Characteristic的Object Point:。
-(void) notification:(CBUUID *) serviceUUID characteristicUUID:(CBUUID *)characteristicUUID peripheral:(CBPeripheral *)p on:(BOOL)on {
CBService *service = [self getServiceFromUUID:serviceUUID p:p];
if (!service) {
if (p.UUID == NULL) return; // zach ios6 addedche
NSLog(@"Could not find service with UUID on peripheral with UUID \n");
return;
}
CBCharacteristic *characteristic = [self getCharacteristicFromUUID:characteristicUUID service:service];
if (!characteristic) {
if (p.UUID == NULL) return; // zach ios6 added
NSLog(@"Could not find characteristic with UUID on service with UUID on peripheral with UUID\n");
return;
}
[p setNotifyValue:on forCharacteristic:characteristic];
}
-(CBService *) getServiceFromUUID:(CBUUID *)UUID p:(CBPeripheral *)p {
for (CBService* s in p.services){
if ([self compareCBUUID:s.UUID UUID2:UUID]) return s;
}
return nil; //Service not found on this peripheral
}
-(CBCharacteristic *) getCharacteristicFromUUID:(CBUUID *)UUID service:(CBService*)service {
for (CBCharacteristic* c in service.characteristics){
if ([self compareCBUUID:c.UUID UUID2:UUID]) return c;
}
return nil; //Characteristic not found on this service
}
使用時只需要將Service/Characteristic的UUID及得到週邊的Peripheral物件傳入,並設定是on(YES)或off(NO)就完成。
didUpdateValueForCharacteristic
didUpdateValueForCharacteristic在連線完成後對於數據資得的取得顯的非常重要,範例中有比對2個UUID為2A37與2A38
-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"2A37"]])
{
if( (characteristic.value) || !error )
{
}
}
if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@"2A38"]])
{
//set refresh int
uint8_t val = 1;
NSData* valData = [NSData dataWithBytes:(void*)&val length:sizeof(val)];
[peripheral writeValue:valData forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
}
}
針對這兩個UUID成立時在這個Delegate做對應處理的工作,範例中以2A38來解說一下:
當更新資料為2A38時,程式將直接寫入 1 ,為什麼寫入1呢?在下表中可以了解,1所代表的就是Chest

意思是告訴心跳感測器量測的位置是在胸部的部分。
注意
整個didUpdateValueForCharacteristic在處理時請注意資料格式的解釋,往往是因為格式解釋錯誤才會得到不正確的資料。
延伸閱讀
目前已經完成CoreBluetooth For Centeral系列文章,下面為文章的標題:
CoreBluetooth for Central (1) ~ (7)
這是講述CoreBluetooth For Central使用方式,整篇文章最後會完成Heart Rate Measurement連接Polar H7的例子結束Central的學習。
6.Explore Services from Device
更新資訊
| 日期 | 內容 |
|---|---|
| 2015/01/27 | 增加延伸閱讀 |
最近在研究藍牙技術,想要讓i device連接非i device,似乎只有MFi認證的裝置,或是jailbreak的裝置,才能順利連接。
Bluetooth Low Energy似乎是目前每個平台能共通的方式之一,有不理解之處可以提出來一起討論
您好,請問您藍芽設備,有可能像藍芽耳機訪問ios設備嗎?
一般的BLE 需要由程式來自行搜尋BLE設備並自行用程式連接,無法使用內建的藍芽選項來與藍芽配對。
您好,請問一下ios是不是沒辦法抓到BLE的mac address,還是說peripheral 的 uuid 就是mac format過的值?
iOS的BLE週邊是以它提供的Peripheral的UUID為主當連線的依據,Android是以mac address來連線!
不好意思可否問一下,那是否有辦法能在ios下取得BLE的mac address???
iOS有管制,所以無法得知mac address,只會得到UUID,且UUID是當下你這台iDevice所產生與MAC對應的UUID,同樣的BLE Device在每台iDevice產生的都不同
因為我看其他的專案,有使用kCBAdvDataManufacturerData這個key取得mac address,是否要ble device端做開放才能取得??
對,沒提供的話就是空資料
請問您是否有過斷線的情形
我用iphone 4 測試程式 回在收到大約3~4次數值後 斷線
藍牙如果有多重連接時可能會不穩定(ex:已連藍牙機聽音樂),有時WiFi開啟時也會造成不穩定情況,我BLE應該是iphone 4s後才有喔?
謝謝你的回覆 我是不清楚機型 不過我想那應該就是4s(都還收得到UUID) 我關WIFI在做測試
請問如果先在 iOS 設定 -> 藍芽 ..裡面把 BLE 裝置連線上 APP有辦法取得 iOS 目前已經連上的裝置 然後去收送資料嗎?? 主要是希望可以使用 iOS 配對 and Bonding後才在APP內取得此連線做溝通
於iOS設定上配對成功時只是告知週邊與iOS上間的配對已經功成並無連線關系,有些週邊會利用是否有配點去管控Characteristic的權限,連線還是必需要利用手動的方式連線,這是目前我知道的訊息供您參考。
謝謝回覆..那如果是在設定 -> 藍芽 手動連線上裝置後 打開 自有的 APP , 有辦法可以取得目前本機連線的 BLE 裝置嗎 因為目前看起來都要先 APP 內 SCAN 然後 APP 內 Connect 之後 APP 取到 peripheral 再去做讀寫
如果知道周邊在iOS上產生的UUID是不需要透過SCAN就能嘗試直接連線取得peripheral再進行讀寫的!否則還是需要經過SCAN的方式得知iOS Device身邊有哪些BLE供連線
基本上BLE + 配對可能不是你所了解如此,根據我測試結果,第一次iOS需要跟BLE連線後再看其中屬性找到需要配點的Characteristic,此時系統會自帶配對的Dialog後請你輸入配對密碼,如果正確,週邊會自行記憶此訊息,並且App要自行記錄與管理連線UUID,下次直接連線時就不需要再配點,但會在”iOS設定”上看到配點過的週邊名稱,有錯誤請指正討論^^
你好, 我目前實測過了..第一次連線時..會出現配對視窗, 配對好後.. 設定->藍芽 裡面會有連線中的裝置 之後 APP 斷線, 也將 UUID 儲存下來了,… 但是下次device開啟時, iOS 後端會直接連線 (設定 -> 藍芽裡面)
此時.. APP 內..無法 scan , 也無法直接 connect, 我儲存的 UUID 變成不知道該怎麼去存取device 請問此時我該怎麼去透過已經儲存下來的 UUID 以及 iOS 已經自動連線的情況下去對 Device 做存取呢?
你這個Case跟我所了解的不太一樣,目前無法給你好的建議,能確定它是BLE的裝置嗎?也有可能是MFi的Bluetooth喔!還是您能提供是什麼樣的設備我研究一下它的資訊
呵呵, 確定是 BLE 裝置, 因為是自己公司做的 BLE Device 目前就是卡在 第一次配對後, 之後 iOS 在背景後端會直接連上 BLE Device 但是 APP 就不知道該怎麼去跟 iOS 要來存取了
目前我實驗結果得知的結論是: BLE具有配對模式功能時會在iOS上的設定-藍牙上能被搜尋並且進行配對,但配對後你具備的GATT並非iOS預設,即時連線後也不會有功能,所以這朝這方向配對目前還找不到參考資料可以取得已連線的BLE Peripheral直接給APP使用。 APP可能做法為: APP->Scan->Connect-(具配對功能BLE Device,iOS會自動跳出配對對話框,配對成功能連線會成功,失敗大部分都會斷線)->Read/Write……. 以上供您參考.
感謝回覆耶~~
有稍微實驗過, 有找到方法了
如果是第一次連線, 可以按照你的方法去實現, 但是如果APP關掉後, iOS會持續連接BLE Device
此時開啟APP就不能 Scan -> Connect 了, 因為 Scan 也沒辦法找到東西.. (被 iOS 連接中)
必須取得跟 iOS 連線中的 Peripheral 給 APP 使用..
目前已經成功取到, 也可以正常拿來 Read/Write 了… ( K 了很久的 API , 慢慢嘗試 =.=)
也很謝謝您的幫忙跟這幾篇文章, 從完全不懂開始就慢慢懂了.. THX
可否分享一下是如何取到的呢?
當然沒問題的嚕!!!!在這邊也得到不少幫助
進入 APP 後 利用 CBCentralManager 裡面的 retrieveConnectedPeripheralsWithServices
就可以取到透過 iOS or 其他方式連接的 BLE Device 的 CBPeripheral Array
如果沒有任何連線 Array 當然就抓到 0 嚕
此方法是使用 Service 去抓, 如果不知道 Service 的話, 就沒輒啦, 通常應該會知道啦
如果有相同 Service 的 Device , CBPeripheral 抓回來後, 可以透過比對 UUID or NAME 去區分
然後取用這個 CBPeripheral 就可以 Read/Write 了
如果有不詳細的地方再告知一下嚕, 大家一起加油~~~
你也真的太厲害了,這要一個一個API看完才會發現,謝謝提供這麼重要的訊息!iOS考慮的這麼周詳,連這也考慮到了,不過這樣APP就要做多重判斷來連接BLE Device吧?
沒有很厲害啦, 只是覺得不太可能是 iOS 不給用 (終究 BLE 都開放了)
所以只好進去 API 一個一個看說明..找比較有可能的 function 一個一個去試試看
其實.. APP 也沒有很複雜的判斷..在自己要去連接 BLE 前面加入一小段 Code 而已
大概像下面這樣而已, 詳細的 code 就是依照每個人專案不同去寫嚕
//==================== if([array count] > 0 ) //這樣就是 iOS 端有連線的裝置 { for(NSUUID *tmp in array) { UUID 有自己要的直接拿來取用的 functon
}
原本自己主動去連 BLE 的 Function //=====================
大家一起努力加油
感謝你提供的訊息交換,這次非常有心得,往後我會再補上這個方式的連接讓篇幅完整,方便透露是什麼樣的BLE產品嗎?產品開賣別忘了回來通知我
哈..我們不是做攜帶型產品唷..所以不是手錶, 等等之類的攜帶式裝置
我們是將 BLE 加裝在原本安全系統內, 多添增一個管道去用 APP 跟 Product 溝通並控制 😀
安全系統有支援BLE也很不錯啊!之前我還想自已弄一個BLE 的switch去當開關,你們BLE那端的firmware是自已寫嗎?
是的, FW 也是自己寫, 所以靈活度比較高, 中間的協定也都自己定義..
只是差在.. iOS 靈活度終究沒有 Android 高 >_<… 所以才有點困擾
不過慢慢都找到方法解決了…也算一個練習啦 ..
android那邊你有測過連線時突然間把ble device那段電源斷線後,android回報disconnect比ios慢的問題嗎?我這測的反應android都大約5~8秒,iOS很快就斷了
哈~我們不適用 TI 的, 我們使用 AMICCOM 的, 目前測試起來, iOS 滿平均的 Android 有部分手機 ok , 部分手機比 iOS 慢一些, 實際幾秒沒有測試過 所以可以試試看多拿幾隻 Android 試試看 , 我們是把全公司不同的 Android 都試一次了
通常它寫”連線中”就已經被連線,scan會關閉,所以目前無解,是不是您公司的BLE device GATT符合apple health app中的的類似心跳之類的,如果有在之中選擇它的”來源”就有可能自動連線
請問~~有沒有辦法在APP中知道已經配對的裝置
利用CBCentralManager 裡面的 retrieveConnectedPeripheralsWithServices,以Service的UUID方式去找已經配對好的裝置,細節可以參考下面Timman與我討論的內容。
有看了,所以目前也只能透過UUID的方式找已經配對好的裝置嗎? 因為目前的需求是想要把以配對的都列出來選擇要使用的裝置
目前能配點的BLE裝置都是能符合Health Kit的Service UUID,像:180D(心跳)、1808(血糖)…這些,所以你可以試著利用這些uuid來列舉所有已配對好的裝置,主要是利用後這取得peripheral就能知道裝置名稱
我有成功的找到了已配對且連線的裝置,但app卻無法跟他connect和discoverService。在設定裡面看裝置是連線狀態
取得到”peripheral”就能直接用,因為它本身已經連線
下面有個圖您參考一下。