To connect to a peripheral, use this method to establish a local connection to the desired peripheral. 

Download: file
centralManager?.connect(blePeripheral!, options: nil)

Add this to the didDiscover function.

Download: file
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral,advertisementData: [String : Any], rssi RSSI: NSNumber) {

    bluefruitPeripheral = peripheral
    bluefruitPeripheral.delegate = self

    print("Peripheral Discovered: \(peripheral)")
  	print("Peripheral name: \(peripheral.name)")
    print ("Advertisement Data : \(advertisementData)")
    
    centralManager?.connect(bluefruitPeripheral!, options: nil)

   }

Once the connection is made, the central manager calls the centralManager(_:didConnect) delegate function to provide incoming information about the newly connected peripheral.

Once this function is called, you'll discover a service that the peripheral is holding.

Download: file
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
   bluefruitPeripheral.discoverServices([CBUUIDs.BLEService_UUID])
}

Finishing the discovering services, you'll get a didDiscoverServices event. Iterate through all the "available" services.

Discovering Services

Now that the peripheral's services are successfully discovered, the central manager will call the didDiscoverServices() delegate function. didDiscoverService() handles and filters services, so that you can use whichever service you are interested in right away.

Download: file
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
        print("*******************************************************")

        if ((error) != nil) {
            print("Error discovering services: \(error!.localizedDescription)")
            return
        }
        guard let services = peripheral.services else {
            return
        }
        //We need to discover the all characteristic
        for service in services {
			peripheral.discoverCharacteristics(nil, for: service)
        }
        print("Discovered Services: \(services)")
    }

First, handle any possible errors returned by the central manager, then request characteristics for each service returned by calling discoverCharacteristics(_:)

Discovering Characteristics

Create two characteristic variables to reference.

Download: file
private var txCharacteristic: CBCharacteristic!
private var rxCharacteristic: CBCharacteristic!

Now call the discoverCharacteristics(_:) function, the central manager will call the didDiscoverCharacteristicsFor() delegate function and provide the discovered characteristics of the specified service. 

Download: file
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
       
           guard let characteristics = service.characteristics else {
          return
      }

      print("Found \(characteristics.count) characteristics.")

      for characteristic in characteristics {

        if characteristic.uuid.isEqual(CBUUIDs.BLE_Characteristic_uuid_Rx)  {

          rxCharacteristic = characteristic

          peripheral.setNotifyValue(true, for: rxCharacteristic!)
          peripheral.readValue(for: characteristic)

          print("RX Characteristic: \(rxCharacteristic.uuid)")
        }

        if characteristic.uuid.isEqual(CBUUIDs.BLE_Characteristic_uuid_Tx){
          
          txCharacteristic = characteristic
          
          print("TX Characteristic: \(txCharacteristic.uuid)")
        }
      }
}

A couple of things are happening in this function: 

  1. Handle errors and print characteristic info to the debug console
  2. Look through the array of characteristics for a match to desired UUIDs.
  3. Perform any necessary actions for the matching characteristics
  4. Discover descriptors for each characteristic

In this case, the specific UUIDs we're looking for are stored in the BLE_Characteristic_uuid_Rx and BLE_Characteristic_uuid_Tx variables.  

When it finds the RX characteristic, it subscribe to updates to its value by calling setNotifyValue() - this is how to receive data from the peripheral. Additionally, read the current value from the characteristic and print its information to the console.

When it finds the TX characteristic, it saves a reference to it to write values to it later - this is how to send data to the peripheral.

Disconnecting from Peripheral

To disconnect or cancels an active or pending local connection to a peripheral, use the .cancelPeripheralConnection method.

Download: file
func disconnectFromDevice () {
	if blePeripheral != nil {
	centralManager?.cancelPeripheralConnection(blePeripheral!)
    }
 }

This method is nonblocking, and any CBPeripheral class commands that are still pending to peripheral may not complete.

Because other apps may still have a connection to the peripheral, canceling a local connection doesn’t guarantee that the underlying physical link is immediately disconnected.

Now, that you've connected to our Bluetooth device, it's time to communicate send and receive data.

This guide was first published on Jul 27, 2017. It was last updated on 2021-02-23 12:51:57 -0500.

This page (Connecting to a Peripheral) was last updated on Apr 10, 2021.

Text editor powered by tinymce.