IOS Bluetooth development

IOS Bluetooth data receive and send

  1. Terms: Central (central equipment), Peripheral (peripheral device), advertising (AD), Services (service), Characteristic (feature)
  2. New Central Manager instance for Bluetooth management
  3. Search peripheral
  4. Connect peripheral
  5. Access to peripheral services
  6. Features of service acquisition
  7. Send data to peripheral
  8. Read data from peripheral

Bluetooth introduction

This article describes the CoreBluetooth, which is specifically designed for communication with BLE devices. And now many Bluetooth devices support 4.0,4.0, so it is known for its low power consumption, so it is also called BLE (Bluetoothlow energy), so it is also a recommended method of development in iOS.

CoreBluetooth introduction

There are two main parts in CoreBluetooth, Central and Peripheral, and CBPeripheralManager as peripheral devices. CBCentralManager as central device. All available iOS devices can act as peripheral (Peripheral) and can also serve as central (Central), but not simultaneously, as well as peripheral and central.

  1. Peripheral equipment (Peripheral) is the data of the broadcast device, and the central device (Central) is the device that manages and uses the data.
  2. That is to say the surrounding (Peripheral) to send a broadcast around, told around the central equipment (Central) (Peripheral) (it around here are data, and that the services and features can provide the value (to get connection),
  3. In fact, the Bluetooth transmission value corresponds to the network interface hardware, service UUID and characteristic UUID,
    to make an analogy: service UUID corresponds to the main address, characteristic UUID is equivalent to short short links, links must be the main branch address, together is the interface, Bluetooth transmission format and your hardware the set is similar to JSON, the two sides can identify the data, because the Bluetooth support only 16 band, and can only transfer 20 bytes, so the information flow into both sides can identify 16 hexadecimal

Implementation methods are introduced

  • .h import header file
#import < CoreBluetooth/CoreBluetooth.h>
  • Custom settings enumeration status
Typedef NS_ENUM (NSInteger, BluetoothState) {BluetoothStateDisconnect = 0, BluetoothStateScanSuccess, BluetoothStateScaning, BluetoothStateConnected, BluetoothStateConnecting}; typedef NS_ENUM (NSInteger, BluetoothFailState) {BluetoothFailStateUnExit = 0, BluetoothFailStateUnKnow, BluetoothFailStateByHW, BluetoothFailStateByOff, BluetoothFailStateUnauthorized, BluetoothFailStateByTimeout};
  • Set proxy
< CBCentralManagerDelegate; CBPeripheralDelegate>
  • Add attributes
@property (strong, nonatomic) UITableView *tableView (strong, nonatomic); @property CBCentralManager *manager; / / central equipment (assign, nonatomic) @property BluetoothFailState bluetoothFailState (assign, nonatomic); @property BluetoothState bluetoothState; @property (strong, nonatomic) CBPeripheral * discoveredPeripheral; / / @property peripheral equipment (strong, nonatomic) CBCharacteristic *characteristic1; / / peripheral equipment service characteristics of @property (strong, nonatomic) NSMutableArray *BleViewPerArr;
  • Create UITableView
- (void) setTableView{[[UITableView alloc]initWithFrame:CGRectMake (_tableView = 0, 20, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height) style:UITableViewStyleGrouped]; _tableView.delegate = self; _tableView.dataSource = self; _tableView.backgroundColor = [UIColor whiteColor]; [self.view addSubview:_tableView];}
  • Next, write tableView’s dalegate
- (UITableViewCell) tableView: (UITableView * tableView) cellForRowAtIndexPath: (NSIndexPath * indexPath{) UITableViewCell = *cell (UITableViewCell * [tableView) dequeueReusableCellWithIdentifier:@ "IsConnect"]; if (cell = = Nil) {cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@ "IsConnect"];} / / Bluetooth peripherals object is connected, remove the name display, Bluetooth / object will find out in the following aspects, was put into the BleViewPerArr array, CBPeripheral object CBPeripheral *per= (CBPeripheral *) _BleViewPerArr[indexPath.row]; NSString *bleName=[per.name substringWithRange:NSMakeRange (0, 9)]; cell.textLabel.text = per.name; return cell;} - (CGFloat) tableView: (UITableView * TableView) heightForRowAtIndexPath: (NSIndexPath *) indexPath{return 44;} - (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) section{return _BleViewPerArr.count;}
  • Create an instance, set the proxy, and create an array management peripheral,
Self.manager = [[CBCentralManager, alloc]initWithDelegate:self, queue:dispatch_get_main_queue ()]; self.manager.delegate = self; self.BleViewPerArr = [[NSMutableArray, alloc]initWithCapacity:1];
  • Start scanning
- (void) scan{/ / first determine the state parameters of peripheral equipment for air will scan devices can be connected to you / / can specify a CBUUID object to only scan equipment registered with the //scanForPeripheralsWithServices method to specify service calls after the call agent CBCentralManagerDelegate //- all (void) centralManager: (CBCentralManager *) Central didDiscoverPeripheral: (CBPeripheral * peripheral) advertisementData: (NSDictionary * advertisementData) RSSI: (NSNumber *) RSSI [self.manager scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey @NO method:}]; / / record is currently scanning _bluetoothState = BluetoothStateScaning; / / [self.BleViewPerArr removeAllOb array is empty all peripherals Jects]; / / if Bluetooth state is not open, that open the Bluetooth if (_bluetoothFailState==BluetoothFailStateByOff) {NSLog ("% @ @ @", "check your Bluetooth is turned on again");}}
  • Next, Bluetooth status is detected
- (void) centralManagerDidUpdateState: (CBCentralManager * central) {if (central.state! = CBCentralManagerStatePoweredOn) {NSLog ("fail, state is @ off."); switch (central.state) {case CBCentralManagerStatePoweredOff: NSLog (@ /n connection failed please check your mobile phone Bluetooth is on /n, and then try again. "); _bluetoothFailState = BluetoothFailStateByOff; break; case CBCentralManagerStateResetting: _bluetoothFailState=BluetoothFailStateByTimeout; break case; CBCentralManagerStateUnsupported: NSLog (@ detects your mobile phone does not support Bluetooth 4.0/n so do not recommend replacing your connection. Try again on /n's mobile phone. "); _bluetoothFailState = BluetoothFailStateByHW; break; case CBCentralManagerStateUnauthorized: NSLog (@ /n connection failed please check your mobile phone Bluetooth is turned on /n, and then try again"); _bluetoothFailState = BluetoothFailStateUnauthorized; break case CBCentralManagerStateUnknown:; _bluetoothFailState = BluetoothFailStateUnKnow; break; default: break return;}}; _bluetoothFailState = BluetoothFailStateUnExit so start scanning;} / /...
  • After the central device starts scanning, we need to implement the centralManager:didDiscoverPeripheral:advertisementData:RSSI: to retrieve the device through the callback.
    this callback illustrates the broadcast data and signal quality (RSSI-Received, Signal, Strength, Indicator) peripherals are found. The quality of the signal can be used to determine the distance of the peripheral from the central device.
- (void) centralManager: (CBCentralManager * central) didDiscoverPeripheral: (CBPeripheral * peripheral) advertisementData: (NSDictionary * advertisementData) RSSI: (NSNumber * RSSI) {if (peripheral = = nil||peripheral.identifier = = nil/*|| peripheral.name = = nil*/) {return} NSString; *pername=[NSString stringWithFormat:@ peripheral.name]; / / "% @, @ to determine whether there is" your device name "NSRange range=[pername rangeOfString:@," your device name "]; / / if the device name from the search to find the specified device, and BleViewPerArr array without its address / / add BleViewPerArr array if (range.location =NSNotFound& & [_BleViewPerArr! ContainsObject:peripheral]==NO) {[_BleViewPerArr addObject : peripheral];} _bluetoothFailState = BluetoothFailStateUnExit; _bluetoothState = BluetoothStateScanSuccess; [_tableView reloadData];}

Scan device output desk log:

< CBPeripheral:, 0x14e625f80, identifier = 954DBF72-104A-E041-19F8-D9538DBA7C23, name = brand, state = disconnected>

Bluetooth broadcast can carry some information, it is best to MAC address also broadcast here!!!
scan device, advertisementData output station, log:

Printing, description, of, advertisementData:, {kCBAdvDataIsConnectable = 1; kCBAdvDataLocalName = brand; kCBAdvDataTxPowerLevel = 2;}
  • After scanning the device, it’s a link device, of course. There’s a UITableView, and the connection method is written in the tableview click method
- (void) tableView: (UITableView * tableView) didSelectRowAtIndexPath: (NSIndexPath *) indexPath{CBPeripheral *peripheral= (CBPeripheral * _BleViewPerArr[indexPath.row]); / / set of peripheral equipment, designated agents _discoveredPeripheral = peripheral; _discoveredPeripheral.delegate = self; / / [_manager connectPeripheral:peripheral options:@{CBConnectPeripheralOptionNotifyOnConnectionKey:@YES}]} connected devices;

Note: click the cell connected with the corresponding equipment, the equipment called proxy connection call this method after – (void) centralManager: (CBCentralManager * central) didConnectPeripheral: (CBPeripheral * peripheral) that connect equipment

The connection failure will call – – (void) centralManager: (CBCentralManager *), central, didFailToConnectPeripheral: (CBPeripheral *), peripheral, error: (NSError *) error

  • Connected to this device, you can obtain information about the current device
/ / get the current equipment - (void) centralManager: (CBCentralManager * central) didConnectPeripheral: (CBPeripheral * peripheral) {NSLog ("% @ @", peripheral); / / setDelegate:self] / / [peripheral set equipment agent; about access to services and features [peripheral discoverServices:nil]; / / UUID array may only get your Bluetooth equipment service, or a a //[peripheral discoverServices:@[[CBUUID UUIDWithString:@ "[CBUUID" UUIDWithString:@ "],"]]]; NSLog (@ "Peripheral Connected"); [_manager stopScan]; NSLog (@ "Scanning stopped"); _bluetoothState=BluetoothStateConnected;}
  • Various services

Note: in this method we want to find the services we need to find the characteristics of
and then call the discoverCharacteristics method we need the discoverCharacteristics method call after call agent CBPeripheralDelegate (void) – peripheral: (CBPeripheral * peripheral) didDiscoverCharacteristicsForService: (CBService * service) error: (NSError * error)

/ / get the current equipment service services - (void) peripheral: (CBPeripheral * peripheral) didDiscoverServices: (NSError * error) {if (error) {NSLog (@ Error discovering services:, [error localizedDescription]% @ "); return;} NSLog (@" all servicesUUID%@ ", peripheral.services); / / service for (CBService traversal of all *service in peripheral.services (NSLog) {@"% @ service ", service.UUID); / / find you need servicesuuid ([service.UUID if isEqual:[CBUUID UUIDWithString:@" your equipment service "UUID") [peripheral discoverCharacteristics:nil forService:service] {/ / monitoring it;}} NSLog (@ "at the link peripheral:%@, peripheral);}
  • Feature acquisition

Description: the state change of the characteristic in this method we need to find our desired service and then call the setNotifyValue method to inform us of this monitoring service characteristics when the call to the setNotifyValue method call agent CBPeripheralDelegate – (void) peripheral: (CBPeripheral * peripheral) didUpdateNotificationStateForCharacteristic: (CBCharacteristic * characteristic) error: (NSError * error)

- (void) peripheral: (CBPeripheral * peripheral) didDiscoverCharacteristicsForService: (CBService * service) error: (NSError * error) {if (error) {NSLog (@ Discovered characteristics for with error:% @% @ "service.UUID, [error, localizedDescription]); return;} NSLog (@"% @: service ", service.UUID); / / characteristics for (CBCharacteristic *characteristic in service.characteristics (NSLog) {@"% @ ", characteristic.UUID); / / / / Note: UUID discovery feature is divided into readable, writable, should be treated differently!!! If ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@ "UUID" you ") {NSLog (@"% @ characteristic monitoring: "); / / characteristic / / monitoring features characteristic value after the object / / save information is also sent with the UUID _characteristic1 [_discoveredPeripheral setNotifyValue:YES = characteristic; forCharacteristic:characteristic];} / / of course, you can also monitor a plurality of characteristic eigenvalues if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:@" UUID "you") {/ / also use a variable to hold the demo, there is no need to declare a variable declaration, / / _characteristic2 / / [peripheral = characteristic; setNotifyValue:Y ES forCharacteristic:_characteristic2]; / / NSLog (@ monitor:% @ ", characteristic);}}} / / monitoring features
  • read
- (void) peripheral: (CBPeripheral * peripheral) didUpdateValueForCharacteristic: (CBCharacteristic * characteristic) error: (NSError * error) {if (error) {NSLog ("Error updating value for characteristic @% @ error:% @" characteristic.UUID, [error, localizedDescription]); return;} NSLog (@ "received data:% @", characteristic.value)};

Bluetooth value transfer

Bluetooth wrote here, basic usage has been described, the code change change, the same ideas, then introduce value, because my project is a bracelet, I would like to document our Bluetooth interface hardware engineer to introduce how to interact with hardware,
is Bluetooth value in the network interface hardware of service UUID plus characteristic UUID
, an analogy: service UUID corresponds to the main address, characteristic UUID is equivalent to short short links, links must be the main branch address, together is the interface, Bluetooth transmission format and your hardware settings similar to JSON, the two sides can identify the data, because the Bluetooth support only 16 229, and can only transfer 20 bytes, so the information flow into both sides can identify 16 hexadecimal

  1. Here is the bracelet interface document

APP requests movement mode, the total number of split packets when basic data is transmitted

Byte serial number parameter values
Zero 0xa5
One 0x06
Two 0x03
3~4 2 bytes of time, such as January, 2 daily, 0x0102 said.
Five XOR checksum

It can be seen that 0, 1 and 2 bytes are fixed, 3 bytes are monthly (16 hexadecimal), 4 bytes are day (16 hexadecimal), and 5 bytes are XOR check and sum

Well then:

The number of split / / APP request general motion model based data transmission - (NSData * sportBao) {Byte reg[6]; reg[0]=0xa5; reg[1]=0x06; reg[2]=0x03; reg[3]=0x01; reg[4]=0x02; reg[5]= (Byte) (reg[0]^reg[1]^reg[2]^reg[3]^reg[4]); NSData *data=[NSData dataWithBytes:reg length:6]; return data;}

At this point, send the request command to the bracelet, and send the characteristic values of the characteristic1 to the Bluetooth device that has just recorded the discoveredPeripheral

The contractor gets / / number - (void) getAltogether data NSData {/ / generation package number *d1 = [self sportBao]; NSLog (@ "% @ write", D1); NSLog (@ "% @", discoveredPeripheral); [discoveredPeripheral writeValue:d1 forCharacteristic:characteristic1 type: CBCharacteristicWriteWithResponse];}

When the send is complete, the bracelet returns the data, and the
data is in the following format:

Bracelet back movement mode, the basic data transmission, split the total number of packages

Byte serial number parameter values
Zero 0xa5
One 0x06
Two 0x83
3~4 The total number of split messages in this motion mode data transmission
Five XOR checksum

As a result: 0, 1, 2 bytes are fixed, 3-4 bytes is the total number of packages (16 hexadecimal), and 5 bytes are XOR checksum

So: we need to convert 3-4 bytes of 16 hex to get the total number

- (void) SetAltogether: (NSData * DayData) {Byte *testByte = (Byte * [DayData) bytes]; if (DayData.length = = 6) {/ / after receipt of the data, to see whether the XOR check, data integrity and correct if (testByte[5]== (testByte[0]^testByte[1]^ testByte[2]^testByte[3]^testByte[4])) {/ / this record number int contractor totalBao = 0; totalBao = testByte[4]*256+testByte[3];}}}

The format of the parsed data already exists, then when the data is received

- (void) peripheral: (CBPeripheral * peripheral) didUpdateValueForCharacteristic: (CBCharacteristic * characteristic) error: (NSError *) error{if (error) {NSLog (@ "read"); return;} NSLog (@ "received data:% @", characteristic.value); NSString *str = [NSString stringWithFormat:@ characteristic.value]; "% @". The number of if (str.length> / / sports package; 7& & [[str substringWithRange:NSMakeRange (1, 2)]isEqualToString:@ "A5"]& & [[str; substringWithRange:NSMakeRange (5, 2)]isEqualToString:@ 83]) {/ / call number [self SetAltogether:characteristic.value] general analytical method;}}

Data transmission is introduced, the basic usage has been described