This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Ranging of connectable device based on nRF51822

Hi,

I'm developing nRF51 proximity based device using nRF51822 that acts as BLE peripheral. It advertises continuously using connectable indirect mode. User has Android smartphone with dedicated application. When user comes closer to the device than some given distance (i.e. 2 meters) smartphone app should connect to it and exchange some data. Distance measurement is based on RSSI.

Problem is that in Android during BLE scan most phones report each device only once if it's using connectable advertisements. Only for beacons (non connectable, indirect slow advertisement) RSSI is reported for each advert. packet. I want to be able to measure RSSI of multiple advertising packets and be able to connect to the device.

What I've tried so far:

  1. searching Android documentation for a way to modify default behavior of BLE scanner. I've found it for iOS but not for Android.
  2. various modifications to Android scan process (i.e. starting BLE scan for 1s, aborting it and restarting after short delay) - this works for some devices but ranging data are very unreliable and I get very little advertising packets compared to beacon and continuous scan.
  3. change advertisement parameters of nRF51 to those used by SDK beacon example while keeping BLE services set up. Ranging works fine but during connection attempt board reboots.

Last idea I have is to set up nRF51 to advertise as 2 devices - beacon and connectable device at the same time. Is it possible and if yes could you point me to some example code / documentation of how to do it?

Alternatively - is there other way to achieve my goal - forcing Android to report given device multiple times in single BLE scan while retaining ability to connect to it?

  • Hi,

    As you say some phones will only report each device once. This can be circumvented by stopping and starting scanning on the android device.

    Alternately you can have your device in multibroadcast mode where it is both a beacon and connectable, then when the beacon is within 2m range you can connect to the connectable advertiser and turn off the beacon. In SDK 11 we have a multiprotocol example that explains how concurrent protocols work in our stack.

    The multiprotocol example runs BLE concurrently with gazell, what you want is two BLE services concurrently. We have an example available on github that demonstrates this functionality. It can be found here.

    I also recommend having a look at the proximity application example from SDK11.

    Hopefully this answers your question. Best regards,

    Øyvind

  • Øyvind,

    Thanks for your answer.

    I've decided to try concurrent approach based on Github example. I've managed to compile the project under SDK10 and gcc 4.9.

    I'm afraid I don't understand exactly how it works. Could you provide barebones example of connectable service running along non-connectable time slot advertiser?

    My other questions are as follows:

    1. In order to compile this project I had to remove app_timer.c and softdevice_handler.c from my project because of duplicate declarations of SD_EVT_IRQHandler and SWI0_IRQ_Handler in advertiser code. My application uses app_timer a lot. Is there a way to use provided time slot advertiser library with app_timer? Also is it possible to use standard softdevice handler in order to use event handlers it generates (I have connectable service which has to receive ble events and for that I've used softdevice_ble_evt_handler_set())?

    2. Is there any way to pause time slot advertiser so it doesn't broadcast when user connects to the device via connectable advertising (non timeslot) part?

    3. Another issue is setting advertisement data for timeslot advertiser. Github readme mentions functions void btle_hci_adv_params_set(btle_cmd_param_le_write_advertising_parameters_t* adv_params) and void btle_hci_adv_data_set(btle_cmd_param_le_write_advertising_data_t* adv_data) but they are never used in the example code. Also time slot advertiser beacon doesn't advertise anything apart from appearance and name. Is this correct behavior?

    4. In order to compile the code I've had to define DEFAULT_DEVICE_ADDRESS in ts_controller.c. I reckon that modifying library code provided by Nordic isn't a recommended way of doing things. Is there any better solution? Specifically I'm thinking about deriving time slot advertiser address from BLE address hardcoded in each nRF51 chip but that would require further modifications to the library. Or maybe I'm missing something that should set DEFAULT_DEVICE_ADDRESS?

  • bump, can anybody advise? This issue is halting our whole project.

  • If you create a support case on My Page, you will get a closer follow-up on the case. Everything there is kept confidential, and you can even attach your project for us to have a look at it. Anyway, I will try and see if I can answer your questions here on DevZone some time today. Others that may have some input are of course also encouraged to reply.

  • Hi,

    I think instead of using the nRF51-multi-role-conn-observer-advertiser example on github, which is made for SDK 9.0, it would be worth having a look at the SDK 10.0 examples\ble_peripheral\experimental_ble_app_multiactivity_beacon_hrs_advertiser example.

    It is an extension on top of the hrs example, which originally used app_timer (and it still does). The example advertises as a beacon when connected, but it should be relatively easy to invert this behaviour. Also, in advertiser_beacon.c you can see the m_beacon struct, which contains a ble_gap_adv_params_t struct with the advertising parameters.

    I have not had time to look deeply into the example, but I do hope it proves helpful.

    Regards, Terje

Related