简体   繁体   中英

Change interval time reading beacon RSSI on iOS with CoreBluetooth

I try to read the RSSI of the beacon(estimote) more offen than once per second. I know that using Core Location nd method locationManager (manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon] inRegion region: CLBeaconRegion) it is not possible.

I found suggestions to use Core Bluetooth. My implementation looks like this:

class Bluetooth : NSObject, CBCentralManagerDelegate, CBPeripheralDelegate {
    var manager: CBCentralManager!
    lazy var peripherals = [NSUUID:CBPeripheral]()


    static let sharedInstance = Bluetooth()

    private override init() {
        super.init()
        manager = CBCentralManager()
        manager.delegate = self
    }

    func centralManagerDidUpdateState(central: CBCentralManager) {
        switch(central.state) {
            case .PoweredOn:
                print("powered on")
                manager.scanForPeripheralsWithServices(nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey: NSNumber(bool: true)])
                break
            default:
                print("Unknown status")
        }
    }

    func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) {   
        //fot testo only one becon
        if(peripheral.name == "EST" && peripherals.count == 0) {            
            manager.connectPeripheral(peripheral, options: nil)         
            peripherals[peripheral.identifier] = peripheral
            peripherals[peripheral.identifier]?.delegate = self     
            manager.stopScan()
        }
    }

    func centralManager(central: CBCentralManager, didConnectPeripheral peripheral: CBPeripheral) {
        print("Connect peripheral \(peripheral.name) \(peripheral.identifier)")
        peripheral.delegate = self
        peripheral.readRSSI()
    }

    func peripheral(peripheral: CBPeripheral, didReadRSSI RSSI: NSNumber, error: NSError?) {
        let currentTime = CACurrentMediaTime();
        print("\(currentTime) \(RSSI)")
        peripheral.readRSSI()
    }
}

I set advertising interval to 100ms on beacon, after all it seems that the peripheral (peripheral: CBPeripheral, didReadRSSI RSSI: NSNumber, error: NSError?) not invoke more offen than once per second.

Is there any way to read the RSSI every 100ms?

And extra question - in the code above method peripheral (peripheral: CBPeripheral, didReadRSSI RSSI) runs only about 10 times, then stops. Is it possible that beacon "hung up" and I need to re-connect with him?

I use for test iPhone 6s plus with iOS9.

Two tips:

  1. Configure your beacon so it is transmitting at 10 Hz, not 1Hz. You only get a callback to CoreBluetooth each time an advertisement is detected. If it is advertising only once per second, you can only get an RSSI reading that often.

  2. Remove the code that calls connectPeripheral . If you connect to a Bluetooth LE device, it stops advertising and you can no longer get advertisement callbacks.

Be aware that using this technique you cannot guarantee you are reading the RSSI values for your beacon vs any other Bluetooth device in the vicinity, because CoreBluetooth does not let you read beacon identifiers. So this will work reliably only when a single Bluetooth device is around.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM