【IOS之BLE蓝牙读取数据与写入数据】1.本篇文章归纳了详细的蓝牙读取,与蓝牙写入的通信。
2.借助公司最近一直研发蓝牙设备项目,博主一路走过来,也遇到不少的坑,希望在此能够给予更多看官的帮助。
- 蓝牙的读取
- UUID的主要类文件,归纳放置在一个文件:Constants.h
#define APP_NAME@"DishTemp"//温度值功能: 发送实时温度数据, 572.0ㄈ(共7个字节),字符串形式.1
#define BOOT_TEMPVALUE_UUID [CBUUID UUIDWithString:@"此处为你们硬件工程师提供的UUID"]/* OTA Upgrade */
#pragma mark - OTA Upgrade#define FLASH_ARRAY_ID@"flashArrayID"
#define FLASH_ROW_NUMBER@"flashRowNumber"#define COMMAND_START_BYTE0x01
#define COMMAND_END_BYTE0x17
//Bootloader command codes#define VERIFY_CHECKSUM0x31
#define GET_FLASH_SIZE0x32
#define SEND_DATA0x37
#define ENTER_BOOTLOADER0x38
#define PROGRAM_ROW0x39
#define VERIFY_ROW0x3A
#define EXIT_BOOTLOADER0x3B// Bootloader status/Error codes#define SUCCESS@"0x00"
#define ERROR_FILE@"0x01"
#define ERROR_EOF@"0x02"
#define ERROR_LENGTH@"0x03"
#define ERROR_DATA@"0x04"
#define ERROR_COMMAND@"0x05"
#define ERROR_DEVICE@"0x06"
#define ERROR_VERSION@"0x07"
#define ERROR_CHECKSUM@"0x08"
#define ERROR_ARRAY@"0x09"
#define ERROR_ROW@"0x0A"
#define ERROR_BOOTLOADER@"0x0B"
#define ERROR_APPLICATION@"0x0C"
#define ERROR_ACTIVE@"0x0D"
#define ERROR_UNKNOWN@"0x0F"
#define ERROR_ABORT@"0xFF"#define UPGRADE_BTN_TITLE_FOR_SEPERATE_SELECTION@"NEXT"
#define UPGRADE_BTN_TITLE_DEFAULT@"UPGRADE"#define COMMAND_START_BYTE0x01
#define COMMAND_END_BYTE0x17#define CHECK_SUM@"checkSum"
#define CRC_16@"crc_16"
#define ROW_DATA@"rowData"/* File parsing alerts */
#define FILE_FORMAT_ERROR@"FileFormatError"
#define PARSING_ERROR@"ParsingError"
#define FILE_EMPTY_ERROR@"FileEmpty"#define LOCALIZEDSTRING(string) NSLocalizedString(string, nil)
蓝牙链接上之后,读取到服务:BlueHelp.m
//只要扫描到特征就会调用,其中的外设和服务就是特征所在的外设和服务
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(nonnull CBService *)service error:(nullable NSError *)error{
if(error){
NSLog(@"扫描特征出现错误,错误原因:%@",error);
}else{
//遍历特征,拿到需要的特征进行处理
for (CBCharacteristic *characteristic in service.characteristics){
NSLog(@"characteristic is %@",characteristic.UUID);
//如果是温度数据处理
if([characteristic.UUID isEqual:BOOT_TEMPVALUE_UUID]){
//将全部的特征信息打印出来
_isconnected = true;
_peripheral = peripheral;
_sendtempcharateristic = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}//Tempunit
else if([characteristic.UUID isEqual:BOOT_TEMPUNIT_UUID]){
_sendtempunitcharateristic = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
else{
..........
}
}
}
}
得到蓝牙温度,现在就需要解析温度数据
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
BOOL ota = [_userDefaults getOta];
NSLog(@"ISOTA is %d",ota);
//不是OTA的情况 也不是发送数据的情况
//顺序依次为 温度是否正常->温度值->温度符号->温度地址->温度报警值->温度报警静音->温度报警开关->电压提示
if(!ota&&!_isSendData){
NSString *temp=[self getTempTMWData:characteristic];
NSArray *tmp = [temp componentsSeparatedByString:@","];
NSString *nomal = tmp[0];
NSString *temptemp = tmp[1];
NSString *tempunit = tmp[2];
int tempaddre = [tmp[3] intValue];
// NSLog(@"DSADASFDSGFG%@sss%@www%@",nomal,temptemp,tempunit);
self.currentDate = [NSDate date];
NSString *dateString = [_dateformatter stringFromDate:self.currentDate];
NSDate *logDate = [_dateformatter dateFromString:dateString];
long logTime= (long)[logDate timeIntervalSince1970];
//如果要等于F的时候
if(_currentTime!=logTime){
if([tempunit isEqualToString:@"F"]){
//float floatString = [temptemp floatValue];
//float aa = [_commonUtil convertFahrenheitToCelcius:floatString];
//正常的时候
if(tempaddre==0){
//NSString *ftempWendu =[NSString stringWithFormat:@"%f",aa];
//NSString *ftempSymbol = @"C";
//[_tempDB saveTempname:_deviceName saveTempaddre:tempaddre saveTempTemp:ftempWendu saveTempSymbol:ftempSymbol saveTemptime:logTime];
}else if(tempaddre==1){
//NSString *ftempSymbol = @"C";
//[_tempDB saveTempname:_deviceName saveTempaddre:tempaddre saveTempTemp:@"999" saveTempSymbol:ftempSymbol saveTemptime:logTime];
}
}else{
if(tempaddre==0){
//[_tempDB saveTempname:_deviceName saveTempaddre:tempaddre saveTempTemp:temptemp saveTempSymbol:tempunit saveTemptime:logTime];
}else if(tempaddre==1){
//[_tempDB saveTempname:_deviceName saveTempaddre:tempaddre saveTempTemp:@"999" saveTempSymbol:tempunit saveTemptime:logTime];
}
}
_currentTime = logTime;
}//发送所有数据
NSDictionary *tempDict = [NSDictionary dictionaryWithObject:temp forKey:@"tempData"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"tempNofiction" object:nil userInfo:tempDict];
}
引入BlueHelp.h文件
#import
//导入蓝牙框架
#import
#import "DeviceModel.h"
#import "Constants.h"
#import "CommonUserDefaults.h"
#import "CommonUtil.h"
#import "TempDB.h"#define COMMAND_PACKET_MIN_SIZE7@interface BlueHelp : NSObject//蓝牙的设备搜索显示在列表中
@property (nonatomic, strong) NSMutableArray *periperals;
//连接peripheral
@property(nonatomic,strong) CBPeripheral *peripheral;
//连接peripheral
@property(nonatomic,strong) CBPeripheral *selectperipheral;
//中心管理者
@property (nonatomic, strong) CBCentralManager *centerManager;
@property (nonatomic,strong) DeviceModel *deviceModel;
//设备列表
@property (nonatomic,strong) NSMutableArray *deviceList;
@property (nonatomic,strong) NSMutableArray *commandArray;
//是否进行ota升级
@property (nonatomic) BOOL isOta;
@property (nonatomic) BOOL isWritePacketDataSuccess;
@property (strong,nonatomic) NSString * checkSumType;
/*!
*@property isApplicationValid
*
*@discussion flag used to check whether the application writing is success
*
*/
@property (nonatomic) BOOL isApplicationValid;
/*!
*@property checkSum
*
*@discussion checkSum received from the device for writing a single row
*
*/
@property (assign) uint8_t checkSum;
/*!
*@property startRowNumber
*
*@discussion Device flash start row number
*
*/
@property (nonatomic) int startRowNumber;
/*!
*@property endRowNumber
*
*@discussion Device flash end row number
*
*/
@property (nonatomic) int endRowNumber;
/*!
*@property siliconIDString
*
*@discussion siliconID from the device response
*
*/
@property (strong,nonatomic) NSString *siliconIDString;
/*!
*@property siliconRevString
*
*@discussion silicon rev from the device response
*
*/
@property (strong,nonatomic) NSString *siliconRevString;
//是否发送数据
@property (nonatomic) BOOL isSendData;
@property (strong,nonatomic) CommonUtil *commonUtil;
@property (strong,nonatomic) TempDB *tempDB;
@property (strong,nonatomic) NSDate *currentDate;
//时间格式化
@property(strong,nonatomic) NSDateFormatter*dateformatter;
@property(strong,nonatomic) NSString *deviceName;
//@property (nonatomic,strong) NSUserDefaults *userDefaults;
@property (nonatomic,strong) CommonUserDefaults *userDefaults;
//发送温度数据
@property (nonatomic,strong) CBCharacteristic *sendtempcharateristic;
//发送OTA数据
@property (nonatomic,strong) CBCharacteristic *sendotacharateristic;
//高/低温度数据
//@property (nonatomic,strong) CBCharacteristic *sendhighalarmcharateristic;
//
//@property (nonatomic,strong) CBCharacteristic *sendlowalarmcharateristic;
//ota
@property (nonatomic,strong) CBCharacteristic *senddfucharateristic;
//发送字符串'CR'清除机子上的最大值(3个字节)
@property (nonatomic,strong) CBCharacteristic *senddcrstrateristic;
//发送字符串'PD'机子关机(3个字节)
@property (nonatomic,strong) CBCharacteristic *senddoutstrateristic;
//静音
@property (strong,nonatomic) CBCharacteristic *sendmutealarmcharateristic;
//calset
@property(strong,nonatomic) CBCharacteristic *sendcalsetcharateristic;
//intervaltime
@property(strong,nonatomic) CBCharacteristic *sendintervaltimecharateristic;
//alarmswitch
@property(strong,nonatomic) CBCharacteristic *sendalarmswitchcharateristic;
//tempunit
@property(strong,nonatomic) CBCharacteristic *sendtempunitcharateristic;
@property(strong,nonatomic) CBCharacteristic *sendlowalarmswitchcharateristic;
///<===============方法区块=======================>
+ (id)sharedManager;
-(NSMutableArray *)getDeviceList;
-(NSMutableArray *)getPeriperalList;
-(void)startScan;
//连接蓝牙
-(void)contentBlue:(int) row;
//断开蓝牙
-(void)disContentBle;
//断开ota的蓝牙连接
-(void)disContentOtaBle;
-(void) discoverCharacteristicsWithCompletionHandler:(void (^) (BOOL success, NSError *error)) handler;
-(void)updateValueForCharacteristicWithCompletionHandler:(void (^) (BOOL success,id command,NSError *error)) handler;
-(void) stopUpdate;
-(void) setCheckSumType:(NSString *) type;
-(NSData *) createCommandPacketWithCommand:(uint8_t)commandCode dataLength:(unsigned short)dataLength data:(NSDictionary *)packetDataDictionary;
-(void) writeValueToCharacteristicWithData:(NSData *)data bootLoaderCommandCode:(unsigned short)commandCode;
/*
* 停止扫描
*/
-(void)stopScan;
//是否是第一次连接设备
@property(assign,nonatomic) BOOL isconnected;
@end
此时就是显示的界面,接收蓝牙的广播
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(tempCompletion:) name:@"tempNofiction" object:nil];
接收到广播,把信息展示出来
-(void)tempCompletion:(NSNotification*)notification{
//第一次加载的时候需要这么执行
if(_onceLoad){
[_progress closeLoadingView];
_tempView.leftView.hidden = FALSE;
_tempView.rightView.hidden = FALSE;
_onceLoad = FALSE;
}//顺序依次为 温度是否正常->温度值->温度符号->温度地址->温度报警值->温度报警静音->温度报警开关->电压提示-静音报警开关
// 0-1-2-3-4-5-6-7-8
NSDictionary *temp = [notification userInfo];
NSString *tempData = https://www.it610.com/article/[temp objectForKey:@"tempData"];
//测试打印
//NSLog(@"传过来的温度是:%@",tempData);
NSArray *tp = [tempData componentsSeparatedByString:@","];
_temptemp = tp[0];
//时实温度
_TmaxTemp = tp[1];
//最大温度
_tempunit = tp[2];
//温度符号
_mutesound = [tp[3] intValue];
//低电压判断//save temp... unit.
//存储地址
[_userDefaults saveMacAddre:self.maclistdata];
[_userDefaults saveTempUnit:_tempunit macAddre:self.maclistdata];
[_userDefaults saveCorF:_tempunit macAddre:self.maclistdata];
//save high alarm.//当为第一次运行的时候 都统一默认为5秒
if(_onceRun&&!_onceRunApp){_tempView.txtaddre.text = self.maclistdata;
//存入蓝牙地址
if(self.maclistdata!=nil){
[_userDefaults saveMacAddre:self.maclistdata];
}
//存入温度符号
if(_tempunit!=nil){
[_userDefaults saveTempUnit:_tempunit macAddre:self.maclistdata];
}//获取当前的时间
NSString *time = [_userDefaults getUpdateTime:self.maclistdata];
if(time!=nil){
[_blueHelp writeIntervalTime:time];
}else{
[_blueHelp writeIntervalTime:@"5"];
}//调式程序
//[_blueHelp writeHighAlarm:@"-10"];
//发送cal值
NSString *cal = [_userDefaults getCal:self.maclistdata currentSymbol:_tempunit];
if([cal isEqualToString:@""]||cal==nil){
cal = @"0";
}
NSString *calSymbol = [_userDefaults getCalSymbol:self.maclistdata];
if([_tempunit isEqualToString:calSymbol]){
[self sendCalSet:cal];
}else{
if([_tempunit isEqualToString:@"°C"]){
if([calSymbol isEqualToString:@"°F"]){
float a = [cal floatValue];
float b = [_commonUtil convertFahrenheitCalCelcius:a];
NSString *bb = [NSString stringWithFormat:@"%0.1f",b];
[self sendCalSet:bb];
}
}else{
if([calSymbol isEqualToString:@"°C"]){
float a = [cal floatValue];
float b = [_commonUtil convertCelciusCalFahren:a];
NSString *bb = [NSString stringWithFormat:@"%0.1f",b];
[self sendCalSet:bb];
}
}
}
_onceRun = FALSE;
}/*
* 更新于 2017/11/16 14:44
*/
//为1的时候显示 低电量 当为低电量的时候所有的事件也要执行
[self displayFont:_voltage];
[self showData];
}
2.写入蓝牙的功能
- 首先根据自己的项目需求
- 然后跟硬件工程师协商好
- 发送的字符规格,节数等等
NSString *otapd = @"PD";
[_blueHelp writeBluePD:otapd];
//调用写入的类,发送pd
//PD设备关机
-(void)writeBluePD:(NSString *)value{
_isSendData = https://www.it610.com/article/TRUE;
[self writeClearPD:value forCharacteristic:_senddoutstrateristic];
}
//写入PD的区块
-(void)writeClearPD:(NSString *)value forCharacteristic:(CBCharacteristic *)characteristic
{
NSData *data = https://www.it610.com/article/[value dataUsingEncoding:NSUTF8StringEncoding];
NSLog(@"send data pd and is:%@",data);
//is no write bluetooth data
if(_senddoutstrateristic.properties & CBCharacteristicPropertyWriteWithoutResponse)
{
//send phone on bluetooth data
[_selectperipheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse];
}else
{
[_selectperipheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
}
//NSLog(@"已经向外设%@的特征值%@写入数据",_peripheral.name,characteristic.description);
_isSendData = https://www.it610.com/article/FALSE;
}
BlueHelp.h文件
//发送字符串'PD'机子关机(3个字节)
@property (nonatomic,strong) CBCharacteristic *senddoutstrateristic;
//写入设备的开关按钮
-(void)writeBluePD:(NSString *)value;
BuleHelp.m文件
读取到蓝牙UUID服务的时候,加上这个
//发送字符串'PD'机子关机(3个字节)
else if([characteristic.UUID isEqual:BOOT_OUTSTRING_UUID]){
_senddoutstrateristic = characteristic;
[peripheral setNotifyValue:YES forCharacteristic:characteristic];
}
最后,经过测试完毕,蓝牙的读取和写入就阐述到此,如有不懂的可以留言。若有帮助,麻烦点个赞,谢谢您的阅读!~