Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Improving timing accuracy by only using single advertisement channel?

Hi everyone,

thanks for this discussion - this question addresses almost exactly a potential use case I've been looking into.

I'd like to try and implement something this using just BLE advertising first, without using the timeslot API; the only thing I could not figure out how to do is in MartinBL's reply:

  • Configure it to advertise on a single advertising channel.
  • Have all your other nodes scan continuously on the same channel.

How do I do that? I'm currently using SD130 on nRF51 platform, and I have already tried something along the following lines:

ble_gap_opt_ch_map_t foo;
foo.conn_handle = 0;
foo.ch_map[0] = 0;
foo.ch_map[1] = 0;
foo.ch_map[2] = 0;
foo.ch_map[3] = 0;
foo.ch_map[4] = 0x10;
sd_ble_opt_set(BLE_GAP_OPT_CH_MAP,(const ble_opt_t*)(&foo));

That should disable all channels except 37, but as far as I can tell, it doesn't have any effect.

I've already done a first experiment for measuring the latency (just toggle a pin as soon as an advertisement has been received, and compare across several boards with logic analyzer), but I'm still seeing something around 2-4 ms of difference, so I'm assuming the advertisement channel scan is still happening...

Best regards, Florian

  • Hi Florian,

    regarding the peaks you see at 700 and 1400 us, it would be interesting to get some insight into the radio hardware timing. For example, at what time the RADIO.END event is triggered (on both the advertiser and scanner boards).

    This can be achieved by using PPI to trigger an GPIOTE.OUT task when the RADIO.END event fires.The GPIO assigned to the corresponding GPIOTE channel (configured to toggle the pin) can be monitored using your logic analyzer.

    On the advertiser side, the RADIO.END event will tell us at what time a packet has finished transmitting.

    On the scanner side, the same event will tell us when a packet has been received. Note that this event is still triggered even if there is a CRC error, or the packet content is invalid. 

    Specifically, I wonder if the advertiser is transmitting one or multiple packets per advertising event. Normally three packets are transmitted back-to-back (one for each advertising channel), but I don't know the exact interval between each packet in an event on the S130 softdevice. The BT spec only states that there should be maximum 10 ms between each packet in an advertising event. 

    Furthermore, using PPI and the RADIO.END event would offer better accuracy than a software timing mechanism. You can use the RADIO.END event to trigger a TIMER.CAPTURE task to accurately capture the reception time, and subsequently decide whether or not to use the captured timer value once the software validates the advertisement payload. 

    Best regards,

    Audun

  • As Audun stated, you can't do anything in software with pin toggles and expect accurate timing.  There is no way to infer or anticipate delays.  The ISRs are just created, queued and processed as they come.

    You would have to do this with radio events and PPI.  Also, since you don't use the crystal 32768 your devices can be up to 500usec apart in just one second and that assumes you are actually running the cal routine.  So either you will have to sync a lot or use LF_synth.

  •  and , thank you for your comments.

    Another side note: I don't really have control over the advertiser - in the scenario I'm exploring, I'm trying to use any arbitrary advertiser (in particular, any recent smartphone) to serve as a trigger for the observers.

    Specifically, I wonder if the advertiser is transmitting one or multiple packets per advertising event. Normally three packets are transmitted back-to-back (one for each advertising channel), but I don't know the exact interval between each packet in an event on the S130 softdevice. The BT spec only states that there should be maximum 10 ms between each packet in an advertising event. 

    After some more digging, I think this is the core issue. I was originally thinking that I had tricked the softdevice into scanning on one channel only (by setting window, timeout and interval all to equal values of 10 seconds and restarting the scan after the timeout).

    However, I'm quite certain now that the softdevice is still cycling through channels 37/38/39 in subsequent scans, and the time difference is simply the delay between the individual advertisements on the three channels. If I reset both observers at roughly the same time (even if there is 1-2 second of delay in between), then nearly all signals arrive within 20 µs of each other, meaning (IMHO) that they both are scanning on the same channel for most of the time. OTOH, if I wait for 10 seconds after resetting the first device and then reset the second one, the delay is almost exclusively 700 µs, meaning that they are almost always scanning on adjacent channels.

    EDIT: confirmed, I've just printed 2400+NRF_RADIO->FREQUENCY on the serial console, and yes, it's cycling through 2402, 2426 and 2480, just as I suspected.

    So I'm sort of back at my original question: is there any way to force SD130 to a single channel for scanning? If not, can I do that with SD132?

  • As far as I can see, it is possible to choose a subset of the advertising channels when scanning using the S132 SoftDevice on nRF52832. See the channel_mask parameter in sd_ble_gap_scan_start().

    Using the S130, even if you won't be able to avoid certain channels altogether, you can probably choose to ignore packets received on unwanted channels. For example, you might be able to read the RADIO.FREQUENCY register immediately after you've received an advertisement packet and get an accurate channel selection. Note that this register will be updated regularly, so there might be a race condition there.. I'm not entirely sure whether or not the S130 softdevice stays on the same channel for the duration of the scan window. If it does, you can keep track of when the scan window opened to determine if the RADIO.FREQUENCY value is correct for the received packet, or if it has just been updated to scan on a new channel. 

    Otherwise, using the radio notification API to manually set up BLE scanning on a single channel might be the most robust approach. SDK 11 had an example of this: http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.sdk5.v11.0.0/ble_sdk_app_multi_activity.html?cp=4_0_9_4_2_2_25 (removed in subsequent releases)

  • Thank you! This is the answer I was looking for.

    For the record, I also found a Horrible Hack (TM) that has the same effect: in the softdevice binary, there is exactly one occurence of the byte sequence 0x25 0x26 0x27 (i.e. the three advertising channels). I patched the binary to 0x25 0x25 0x25, thereby hard-locking the softdevice to channel 37, and the result is below:

    So I can now reliably trigger two observers within 20 µs. Over a sampling period of 500 s, with a total of 1748 advertisements sent, both observers received 1744 simultaneous advertisements. That result is more than good enough for me :-)

    Once again, thank you very much for your thorough analysis!

Related