Search code examples
iosios5core-bluetooth

Core Bluetooth - constant RSSI updates of in-range devices


I just started with the core bluetooth framework for iOS and I'm developing an app that needs to constantly scan for BLE devices so that I can retrieve their RSSI number every minute or so.

Currently I have:

manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:FALSE], CBCentralManagerScanOptionAllowDuplicatesKey, nil];
[manager scanForPeripheralsWithServices:nil options:options];

this starts my app scanning for BLE devices and calls this delegate method when a device is discovered:

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI {
    NSLog(@"Did discover peripheral. peripheral: %@ rssi: %@, UUID: %@ advertisementData: %@ ", peripheral, RSSI, peripheral.UUID, advertisementData);
    //Do something when a peripheral is discovered.

    rssiLabel.text = [RSSI stringValue];

    [manager retrievePeripherals:[NSArray arrayWithObject:(id)peripheral.UUID]];}

this method gets me the peripheral's RSSI number which i can display. The last line then calls this delegate method:

- (void) centralManager:(CBCentralManager *)central didRetrievePeripherals:(NSArray *)peripherals {

    NSLog(@"Currently known peripherals :");
    int i = 0;
    for(CBPeripheral *peripheral in peripherals) {
        NSLog(@"[%d] - peripheral : %@ with UUID : %@",i,peripheral,peripheral.UUID);

    }

     NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:FALSE], CBCentralManagerScanOptionAllowDuplicatesKey, nil];
     [manager scanForPeripheralsWithServices:nil options:options];

}

This code seems to be working and doing a scan roughly every 1 minute, but I don't exactly know why it working...

The documentation on core bluetooth is pretty sparse so if anyone has any idea on how to do this, or has a better way to do what I'm trying to accomplish I'd appreciate the help!


Solution

  • Have you tried changing the scan option to YES?

    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber  numberWithBool:YES], CBCentralManagerScanOptionAllowDuplicatesKey, nil];
    [manager scanForPeripheralsWithServices:nil options:options];
    

    If you do this you will get your "didDiscoverPeripheral" callback with every ad packet that is seen by your iPhone, which would normally be about every 100ms (although I see this callback timing varying a lot for the same device). This includes the RSSI of each device it sees.

    This should be a lot faster than your ~1 minute update rate.