第二篇、通过蓝牙连接外设
简介:
很早前就像总结一下手机通过蓝牙连接外设的知识点,但是由于项目比较急,也没有时间去总结。今天刚好看到一篇别人的博客,我就结合的总结了一下。
实现的流程:
建立中心角色
扫描外设(discover)
连接外设(connect)
扫描外设中的服务和特征(discover)
- 4.1 获取外设的services
- 4.2 获取外设的Characteristics,获取Characteristics的值,获取Characteristics的Descriptor和Descriptor的值
5. 与外设做数据交互(explore and interact)
6. 订阅Characteristic的通知
7.断开连接(disconnect)
8.模拟器蓝牙调试,慎用,最好还是用真机去调试。
代码实现:
#import <Foundation/Foundation.h> #import <CoreBluetooth/CoreBluetooth.h>#define MyPeripheralName @"MyPeripheralName" #define MySUUID @"XXXX" #define MyCUUID @"XXXX"#define kNotificationConnected @"kNotificationConnected" #define kNotificationDisconnected @"kNotificationDisconnected"typedef enum _EN_Command_Type {EN_Command_Invalid = -1,EN_Command_Start = 0x0,EN_Command_Mode1 = 0x1,EN_Command_Mode2,EN_Command_Mode3,EN_Command_Mode4,EN_Command_Mode5,EN_Command_Mode6,EN_Command_Mode7,EN_Command_Mode8,EN_Command_Mode9,EN_Command_Stop,EN_Command_Shutdown,//关机 }EN_CommandType;@interface MSBluetoothManager : NSObject<CBCentralManagerDelegate,CBPeripheralDelegate>@property (nonatomic,assign)BOOL bluetoothPowerOn;/*** 单例方法** @return 单例*/ +(MSBluetoothManager*)shareInstance;/*** 开始扫描*/ -(void)startScan;/*** 停止扫描*/ -(void)stopScan;/*** 连接*/ -(void)startconnect;/*** 取消连接*/ -(void)cancelConnect;/*** 向设备写数据*/ -(BOOL)writeData:(NSData*)data;/*** 是否可以准备好写数据** @return 是否可以准备好写数据*/ -(BOOL)isReady;/*** 发送命令** @param command 命令内容** @return 是否发送成功*/ -(BOOL)sendCommand:(EN_CommandType)command;@end
View Code
由于代理方法比较多,我就不一一做介绍 了
#import "MSBluetoothManager.h" #import "TKAlertCenter.h" #define SCACN_INTERVALS 1.5@interface MSBluetoothManager() @property BOOL cbReady; @property (nonatomic,strong) CBCentralManager *cbCM; @property (strong,nonatomic) NSMutableArray *nDevices; @property (strong,nonatomic) NSMutableArray *nServices; @property (strong,nonatomic) NSMutableArray *nCharacteristics;@property (strong,nonatomic) CBPeripheral *cbPeripheral; @property (strong,nonatomic) CBService *cbServices; @property (strong,nonatomic) CBCharacteristic *cbCharacteristcs;@end@implementation MSBluetoothManager+(MSBluetoothManager*)shareInstance {static dispatch_once_t pred = 0;__strong static MSBluetoothManager *_sharedObject = nil;dispatch_once(&pred, ^{_sharedObject = [[self alloc] init]; // or some other init method });return _sharedObject; }#pragma mark -对外接口 /*** 开始扫描*/ -(void)startScan {if(_bluetoothPowerOn){if( !_cbReady ){[self updateLog:@"Scan for Peripheral..."];[_cbCM scanForPeripheralsWithServices:nil options:nil];// [self performSelector:@selector(startScan) withObject:nil afterDelay:SCACN_INTERVALS]; }}else{//弹框提示,请去系统中打开蓝牙[[TKAlertCenter defaultCenter]postAlertWithMessage:NSLocalizedString(@"Please open the Bluetooth on system settings", @"请到系统设置中打开蓝牙")];}}/*** 停止扫描*/ -(void)stopScan {[self updateLog:@"stop scan..."];[_cbCM stopScan];[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(startScan) object:nil]; }/*** 连接*/ -(void)startconnect {if (_cbReady ==false){[self.cbCM connectPeripheral:_cbPeripheral options:nil];} }/*** 取消连接*/ -(void)cancelConnect {if(_cbReady){[_cbCM cancelPeripheralConnection:_cbPeripheral];}}/*** 向设备写数据*/ -(BOOL)writeData:(NSData*)data {BOOL ret = NO;if([data length] >0){[self writeCharacteristic:_cbPeripheral sUUID:MySUUID cUUID:MyCUUID data:data];ret = YES;}return ret; }/*** 是否可以准备好写数据** @return 是否可以准备好写数据*/ -(BOOL)isReady {return _cbReady; }/*** 发送命令** @param command 命令内容** @return 是否发送成功*/ -(BOOL)sendCommand:(EN_CommandType)command {NSLog(@"begin send command:%d",command);BOOL ret = NO;if([self isReady]){unsigned char data [6]= {0};data[0] = 0xa5;*(data+1) = 0x01;*(data+2) = 0x01;switch (command) {case EN_Command_Start:{}break;case EN_Command_Stop:{command = 0x00;}break;case EN_Command_Mode1:break;case EN_Command_Mode2:break;case EN_Command_Mode3:break;case EN_Command_Mode4:case EN_Command_Mode5:case EN_Command_Mode6:case EN_Command_Mode7:case EN_Command_Mode8:case EN_Command_Mode9:{ // datastr = [NSString stringWithFormat:@"%d",command]; }break;case EN_Command_Shutdown:{command = 0x5a;}default:break;}NSLog(@"send command:%d",command);*(data+3) = command;// datastr = @"1234567890";// NSNumber* num = @(0x01);// NSData* data = [datastr dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; do_crc(data,6);// char a[10]= {0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2};NSData *nsdata = [NSData dataWithBytes:data length: sizeof(char)*6];NSLog(@"send data: %@",nsdata);//真正发送命令ret = [self writeData:nsdata];}return ret; }#pragma mark -CBCentralManagerDelegate - (void)centralManagerDidUpdateState:(CBCentralManager *)central {switch (central.state) {case CBCentralManagerStatePoweredOff:[self updateLog:@"CoreBluetooth BLE hardware is Powered off"];//对外抛出断开连接的通知[[NSNotificationCenter defaultCenter] postNotificationName:kNotificationDisconnected object:nil];_cbReady = FALSE;_bluetoothPowerOn = FALSE;break;case CBCentralManagerStatePoweredOn:[self updateLog:@"CoreBluetooth BLE hardware is Powered on and ready"];_bluetoothPowerOn = YES;break;//cbReady = true;case CBCentralManagerStateResetting: // _cbReady = FALSE;[self updateLog:@"CoreBluetooth BLE hardware is resetting"];break;case CBCentralManagerStateUnauthorized:[self updateLog:@"CoreBluetooth BLE state is unauthorized"]; // _cbReady = FALSE;break;case CBCentralManagerStateUnknown:[self updateLog:@"CoreBluetooth BLE state is unknown"];break;case CBCentralManagerStateUnsupported: // _cbReady = FALSE;[self updateLog:@"CoreBluetooth BLE hardware is unsupported on this platform"];break;default:break;} }//已发现从机设备 - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {[self updateLog:[NSString stringWithFormat:@"Did discover peripheral. peripheral: %@ rssi: %@, UUID: %@ advertisementData: %@ ", peripheral, RSSI, peripheral.identifier, advertisementData]];BOOL replace = NO;// Match if we have this device from beforefor (int ii=0; ii < _nDevices.count; ii++) {CBPeripheral *p = [_nDevices objectAtIndex:ii];if ([p isEqual:peripheral]) {[_nDevices replaceObjectAtIndex:ii withObject:peripheral];replace = YES;}}if (!replace) {if ([peripheral.name isEqualToString:MyPeripheralName]) {[_nDevices addObject:peripheral];[self updateLog:@"has found MyPeripheralName!\r\n"];_cbPeripheral = peripheral;}}if(_cbPeripheral ){//开始连接 [self startconnect];} }//已链接到从机 - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {//取消重连[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(startScan) object:nil];[self updateLog:[NSString stringWithFormat:@"Connection successfull to peripheral: %@ with UUID: %@",peripheral,peripheral.identifier]];//Do somenthing after successfull connection.//发现services//设置peripheral的delegate未self非常重要,否则,didDiscoverServices无法回调peripheral.delegate = self;[_cbPeripheral discoverServices:nil];_cbReady = true;[self updateLog:@"didConnectPeripheral"];//对外抛出连接的通知[[NSNotificationCenter defaultCenter] postNotificationName:kNotificationConnected object:nil];//统计[AVAnalytics event:@"ConnectToHardWare"];}//已断开从机的链接 - (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {[self updateLog:[NSString stringWithFormat:@"Disconnected from peripheral: %@ with UUID: %@",peripheral,peripheral.identifier]];//Do something when a peripheral is disconnected._cbReady = false;//对外抛出断开连接的通知[[NSNotificationCenter defaultCenter] postNotificationName:kNotificationDisconnected object:nil];//统计[AVAnalytics event:@"DisconnectToHardWare"];//尝试重连dispatch_async(dispatch_get_main_queue(), ^{[self startScan];}); }- (void) centralManager:(CBCentralManager *)central didRetrieveConnectedPeripherals:(NSArray *)peripherals {[self updateLog:[NSString stringWithFormat:@"Currently connected peripherals :"]];int i = 0;for(CBPeripheral *peripheral in peripherals) {[self updateLog:[NSString stringWithFormat:@"[%d] - peripheral : %@ with UUID : %@",i,peripheral,peripheral.identifier]];i++;//Do something on each connected peripheral. }}- (void) centralManager:(CBCentralManager *)central didRetrievePeripherals:(NSArray *)peripherals {[self updateLog:[NSString stringWithFormat:@"Currently known peripherals :"]];int i = 0;for(CBPeripheral *peripheral in peripherals) {[self updateLog:[NSString stringWithFormat:@"[%d] - peripheral : %@ with UUID : %@",i,peripheral,peripheral.identifier]];i++;//Do something on each known peripheral. } }//delegate of CBPeripheral //已搜索到services -(void) peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{[self updateLog:@"Found Services."];int i=0;for (CBService *s in peripheral.services) {[self.nServices addObject:s];}for (CBService *s in peripheral.services) {[self updateLog:[NSString stringWithFormat:@"%d :Service UUID: %@(%@)",i,s.UUID.data,s.UUID]];i++;[peripheral discoverCharacteristics:nil forService:s];} }#pragma mark -CBPeripheralDelegate // ////已读到char //-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{ // if (error) { // return; // } // unsigned char data[characteristic.value.length]; // [characteristic.value getBytes:&data]; // // //}//已搜索到Characteristics -(void) peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{[self updateLog:[NSString stringWithFormat:@"Found Characteristics in Service:%@ (%@)",service.UUID.data ,service.UUID]];for (CBCharacteristic *c in service.characteristics) {[self updateLog:[NSString stringWithFormat:@"Characteristic UUID: %@ (%@)",c.UUID.data,c.UUID]];[_nCharacteristics addObject:c];} }//已读到char -(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{if (error) {return;}unsigned char data[characteristic.value.length];[characteristic.value getBytes:&data];NSDate*date = [NSDate date];NSCalendar*calendar = [NSCalendar currentCalendar];NSDateComponents*comps;comps =[calendar components:(NSHourCalendarUnit | NSMinuteCalendarUnit |NSSecondCalendarUnit) fromDate:date];NSInteger hour = [comps hour];NSInteger minute = [comps minute];NSInteger second = [comps second];[self updateLog:[NSString stringWithFormat:@"char update! [%ld:%ld:%ld],char = %d",hour,minute,second,data[0]]]; }#pragma mark -内部函数 -(id)init {if(self = [super init]){_cbCM = [[CBCentralManager alloc] initWithDelegate:self queue:nil];_cbServices =[[CBService alloc]init];_cbCharacteristcs =[[CBCharacteristic alloc]init];//列表初始化_nDevices = [[NSMutableArray alloc]init];_nServices = [[NSMutableArray alloc]init];_nCharacteristics = [[NSMutableArray alloc]init];_cbReady = FALSE;_bluetoothPowerOn = FALSE;}return self; }-(void)updateLog:(NSString *)s {//用回NSLog,NSLog(@"%@",s ); }-(void)writeCharacteristic:(CBPeripheral *)peripheral sUUID:(NSString *)sUUID cUUID:(NSString *)cUUID data:(NSData *)data {// Sends data to BLE peripheral to process HID and send EHIF command to PCfor ( CBService *service in peripheral.services ) {if ([service.UUID isEqual:[CBUUID UUIDWithString:sUUID]]) {for ( CBCharacteristic *characteristic in service.characteristics ) {if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:cUUID]]) {[self updateLog:@"has reached\r\n"];/* EVERYTHING IS FOUND, WRITE characteristic ! */[peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];}}}} }-(void)setNotificationForCharacteristic:(CBPeripheral *)peripheral sUUID:(NSString *)sUUID cUUID:(NSString *)cUUID enable:(BOOL)enable {for ( CBService *service in peripheral.services ) {if ([service.UUID isEqual:[CBUUID UUIDWithString:sUUID]]) {for (CBCharacteristic *characteristic in service.characteristics ) {if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:cUUID]]){/* Everything is found, set notification ! */[peripheral setNotifyValue:enable forCharacteristic:characteristic];}}}} }- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{[self updateLog:[NSString stringWithFormat:@"%@",error]];}void do_crc(unsigned char *data,unsigned short int length) {//此处为加密算法,略去 }@end
View Code
转载于:https://www.cnblogs.com/HJQ2016/p/5790347.html
第二篇、通过蓝牙连接外设相关推荐
- B站黑马测试第二篇P204:navicat连接本地tpshop2.0数据库
一.前置条件 1.下载phpStudy 2.下载TPshop软件 下载地址:点击这里黑马老师的博客后,ctrl+f键搜索关键字:'phpStudy'和'TPshop'下载. 二.环境部署 参考视频:B ...
- 第二篇:可靠连接,TCP协议全解析
文章目录 一.前言 二.TCP报文结构 三.TCP连接(重点:三次握手和四次挥手) 3.1 三次握手建立连接 3.2 四次挥手释放连接 3.3 wireshark演示 四.TCP可靠连接 4.1 序号 ...
- 自己动手实现蓝牙MESH应用系列 | 第一篇:蓝牙MESH基础概念介绍
文章目录 1. 前言 2. 概述 2.1. 蓝牙风格(Flavors) 2.2. mesh网络的动机 2.3. mesh网络中的消息传输方式 2.3.1. 以消息为中心的通信 - 发布/订阅(publ ...
- tcp连接多久会自动断开_苹果M1 Mac用户报告蓝牙连接问题:外设经常会断开
IT之家 11 月 25 日消息 据外媒 AppleInsider 报道,一些新的 M1 MacBook Air.13 英寸 MacBook Pro 和 Mac mini 的用户正面临蓝牙连接问题,并 ...
- iOS 蓝牙开发(二)iOS 连接外设的代码实现
上一篇文章介绍了蓝牙的技术知识,这里我们具体说明一下中心模式的应用场景.主设备(手机去扫描连接外设,发现外设服务和属性,操作服务和属性的应用.一般来说,外设(蓝牙设备,比如智能手环之类的东西),会由硬 ...
- 苹果M1 Mac遇到蓝牙连外设连接不稳定经常断开怎么办?
外媒指出,许多新的 M1 MacBook Air,MacBook Pro 和 Mac mini 用户遇到了蓝牙连接的问题,这对于独立的 Mac mini 来说尤其令人烦恼.问题包括经常与外设断开连接, ...
- Noah Mt4跟单系统制作第二篇 Mt4TradeApi连接服务器篇
Noah Mt4跟单系统制作第二篇 Mt4TradeApi连接服务器篇 using System; using Mt4TradeApi;namespace Demo {class Program{st ...
- Android 蓝牙连接 ESC/POS 热敏打印机打印(ESC/POS指令篇)
上一篇 主要介绍了如何通过蓝牙连接到打印机.这一篇,我们就介绍如何向打印机发送打印指令,来打印字符和图片. =====================2017.05.09 更新============ ...
- 杰理之测试盒蓝牙连接提示音使能【篇】
该配置为1时,则提示音使能.在蓝牙连接成功会测试盒会播放"connected"的提示音,蓝牙断开会播放"disconnected"的提示音.(加载默认配置是为1 ...
最新文章
- Dokku和Docker的完美配合
- 关于java使用javacomm20-win32实践总结 (转)
- oralce之 10046对Hash Join分析
- android+note2+分辨率,魅蓝Note2的屏幕尺寸是多少?魅蓝Note2的分辨率是多少?
- [UOJ299][CTSC2017] 游戏
- window统计文本字节_【NLP】机器如何认识文本 ?NLP中的Tokenization方法总结
- Hdu 1794 【二维成段更新】.cpp
- 新手程序员必读的十本经典著作
- 查看ESP32模组中Flash颗粒以及芯片信息
- NetSuite 精益实施的ALV实践
- 爱因斯坦的逻辑思维题
- 怎么在python提取别的数据了_别再问如何用python提取PDF内容了!
- PADS(7)——在PADS Layout一次性添加泪滴
- 打瓶颈,破性能,性能大牛教你怎么玩转性能测试
- Android 6种加载网络图片的第三方详解
- 哪吒之魔童降世视听语言影评_《哪吒之魔童降世》影评4篇
- 微服务架构集成RabbitMQ给用户推送消息(发送短信,发送邮件,发送站内信息)
- 多分类模型Accuracy, Precision, Recall和F1-score的超级无敌深入探讨
- 元宇宙六大技术全景图
- AD18为PCB文件添加LOGO图标