iosbluetootharduinoadafruit

Bluetooth Peripheral Stuck in "Connecting" State On iOS


I am trying to connect to my Arduino project that is using the BlueFruit BLE spi module. I am having an issue when trying to connect using my iOS app. After I have found the device I try to connect to it but the state gets stuck in 'connecting' state=1. This prevent me from searching the services and such because a 'connected' state isn't achieved Here is a code snip...

//check state of the bluetooth on phone
func centralManagerDidUpdateState(_ central: CBCentralManager) {
    if central.state == .poweredOff{
        //TODO: ADD SAVE DATA TO REALM BEFORE DISSMISSING
        errorView.isHidden = false
    }
    if central.state == .poweredOn{
        errorView.isHidden = true
        //scan for peripherals with the service i created
        central.scanForPeripherals(withServices: nil, options: nil)
    }
}

//devices found(should only be ours because we will create Unique serviceID)
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
    // get advertisement data and check to make sure the name is matching. set it as the peripheral then make connection
    if let peripheralName = advertisementData[CBAdvertisementDataLocalNameKey] as? String {
        print("NEXT PERIPHERAL NAME: \(peripheralName)")
        print("NEXT PERIPHERAL UUID: \(peripheral.identifier.uuidString)")

    if peripheralName == nameID{
        manager.stopScan()
        self.peripheralHalo = peripheral
        peripheralHalo!.delegate = self
        manager.connect(peripheral, options: nil)

       while(peripheralHalo?.state.rawValue == 1)
       {
            if(manager.retrieveConnectedPeripherals(withServices: [serviceID]).count > 0 ){
                print("\(manager.retrieveConnectedPeripherals(withServices: [serviceID]))")
            }
        }
    }
        print("Connected!!")
    }

When I call manager.connect(peripheral, options: nil) , the peripheral tries to connect. I add the following while loop for testing and always shows the state as "connecting". I have tried the LightBlue iOS app and i can properly connect and receive notifications of characteristic value changes so the Arduino firmware should be all good.PLEASE HELP!!!


Solution

  • You don't want that while loop; This will just block the Core Bluetooth delegate thread. After issuing the connect you will get a call to the didConnect CBCentralManagerDelegate method. Once the peripheral is connected you need to call discoverServices on the peripheral, which will give a callback to the peripheral:didDiscoverServices: peripheral delegate method. You can then discover the characteristics in a similar way.

    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
    // get advertisement data and check to make sure the name is matching. set it as the peripheral then make connection
        if let peripheralName = advertisementData[CBAdvertisementDataLocalNameKey] as? String {
            print("NEXT PERIPHERAL NAME: \(peripheralName)")
            print("NEXT PERIPHERAL UUID: \(peripheral.identifier.uuidString)")
    
            if peripheralName == nameID {
                self.peripheralHalo = peripheral
                central.stopScan()
                central.connect(peripheral, options: nil)
            }
        }
    }
    
    func centralManager(_ central: CBCentralManager, 
                  didConnect peripheral: CBPeripheral) {
        print("Connected!!")
        peripheralHalo!.delegate = self
        peripheral.discoverServices([serviceID)
    }
    

    Also, if you are going to store something that identifies which peripheral you want to connect to, I suggest you use the identifier and not the name as the name can change.