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

Sniffing min max connection interval with nRF Sniffer

Hello,

I'm new to sniffing BLE. I'd like to determine the min and max connection interval and other connection parameters (MTU, slave latency, supervisory timeout, etc.) of a peripheral. I don't have access to the firmware. I have Wireshark+nRF Sniffer for BLE 3.0.0 installed and running my my Mac (10.14.6). I can see advertising, connection requests, etc. I've attached a screen capture. Where do I look to find these connection parameters?

Many thanks,

Tim

Parents
  • Hi Tim, 

    you'll find the connection interval, slave latency and supervision timeout in the connection request ( CONNECT_REQ) under Bluetooth Low Energy Link Layer -> Link Layer Data

    For the MTU size you need to look for Exchange MTU Request/Response packets 

    If you do not see any Exchange MTU Request/Response packets, then the default MTU size of 23 is used. 

    Best regards

    Bjørn

  • Thanks Bjørn. Appreciate your response. I'm trying to understand a performance difference between two BLE peripherals. One is a Simblee-based peripheral (long since discontinued). The other is a Laird BL652-based peripheral for which I'm writing code using Nordic SDK 15.3, SD112 v6.1.1. The Simblee was proprietary and used nRF51822. Not sure how the peripheral app was developed. It allowed developers to write code using Arduino IDE and it provided a simple NUS-like API to exchange messages between central and peripheral.

    The BL652-based peripheral, which we are developing to replace the discontinued Simblee-based product, uses nRF52832. I started with the BLE UART example (which uses NUS) and have trimmed and extended for our needs. All works well.

    The app is measuring time between sensor events on two different peripherals and is generally accurate enough. I realize there are many possibilities for latency and latency variation in delivery of messages, including latency between receiving packets at the iOS device radio and notification in our iOS app. Generally we measured 10 ms accuracy timing with Simblee peripherals. With BL652-based peripherals, we're getting 20 ms accuracy and I'm trying to understand what might cause the difference. (Same iOS device acting as central.)

    I've sniffed connection parameters and see the following:

    Simblee
    Window Size: 3 (3.75 msec)
    Window Offset: 12 (15 msec)
    Interval: 24 (30 msec)
    Latency: 0
    Timeout: 72 (720 msec)

    BL652
    Window Size: 3 (3.75 msec)
    Window Offset: 21 (26.25 msec)
    Interval (24 (30 msec)
    Latency: 0
    Timeout: 72 (720)

    Is it possible that the differing Window Offset is causing the difference? Any other parameters to consider in explaining this? Possible that there's some latency in the SoftDevice or other aspects of Nordic software?

    Thanks for any guidance here. Much appreciated.

    Tim

  • Hi Tim, 

    Yes, the window offset may have a role to play. I think this is determined based of the clock accuracy of the peer. Which LF CLK configuration are you using on the nRF52832(i.e. BL652) side? Is it LFXO or LFRC?

    Best regards

    Bjørn

  • Thanks again Bjørn. I'm new to clock source, frequency, accuracy. Here's what I know that might be relevant. I've been testing our code both with two nRF52 dev kits and also with two of our custom boards with BL652 module, and comparing with Simblee. I understand with the Dev Kit, there's an on-board external 20 ppm crystal (X2) and is connected to P0.00/XL1/P0.01/XL2 via solder bridges SB1, SB2.

    For our peripheral app, sdk_config.h has:

    // <o> NRF_SDH_CLOCK_LF_SRC  - SoftDevice clock source.
     
    // <0=> NRF_CLOCK_LF_SRC_RC 
    // <1=> NRF_CLOCK_LF_SRC_XTAL 
    // <2=> NRF_CLOCK_LF_SRC_SYNTH 
    
    #ifndef NRF_SDH_CLOCK_LF_SRC
    #define NRF_SDH_CLOCK_LF_SRC 1
    #endif
    
    // <o> NRF_SDH_CLOCK_LF_RC_CTIV - SoftDevice calibration timer interval. 
    #ifndef NRF_SDH_CLOCK_LF_RC_CTIV
    #define NRF_SDH_CLOCK_LF_RC_CTIV 0
    #endif
    
    // <o> NRF_SDH_CLOCK_LF_RC_TEMP_CTIV - SoftDevice calibration timer interval under constant temperature. 
    // <i> How often (in number of calibration intervals) the RC oscillator shall be calibrated
    // <i>  if the temperature has not changed.
    
    #ifndef NRF_SDH_CLOCK_LF_RC_TEMP_CTIV
    #define NRF_SDH_CLOCK_LF_RC_TEMP_CTIV 0
    #endif
    
    // <o> NRF_SDH_CLOCK_LF_ACCURACY  - External clock accuracy used in the LL to compute timing.
     
    // <0=> NRF_CLOCK_LF_ACCURACY_250_PPM 
    // <1=> NRF_CLOCK_LF_ACCURACY_500_PPM 
    // <2=> NRF_CLOCK_LF_ACCURACY_150_PPM 
    // <3=> NRF_CLOCK_LF_ACCURACY_100_PPM 
    // <4=> NRF_CLOCK_LF_ACCURACY_75_PPM 
    // <5=> NRF_CLOCK_LF_ACCURACY_50_PPM 
    // <6=> NRF_CLOCK_LF_ACCURACY_30_PPM 
    // <7=> NRF_CLOCK_LF_ACCURACY_20_PPM 
    // <8=> NRF_CLOCK_LF_ACCURACY_10_PPM 
    // <9=> NRF_CLOCK_LF_ACCURACY_5_PPM 
    // <10=> NRF_CLOCK_LF_ACCURACY_2_PPM 
    // <11=> NRF_CLOCK_LF_ACCURACY_1_PPM 
    
    #ifndef NRF_SDH_CLOCK_LF_ACCURACY
    #define NRF_SDH_CLOCK_LF_ACCURACY 7
    #endif

    That all looks correct to me. Clock source is the external crystal with 20 ppm accuracy.

    I also learned in the past that to achieve higher timing accuracy (TIMER1, TIMER2, etc.), app needs to request the high frequency clock after initializing BLE. So after app calls ble_stack_init(), I've added the following code:

    uint32_t is_running;
    sd_clock_hfclk_request();
    do { 
        sd_clock_hfclk_is_running(&is_running);
    } while (is_running==0);

    Do both the low and high frequency clocks run off of either RC or XTAL?

    Finally, our custom board uses a 5 ppm-accurate crystal. I presume this will further increase accuracy. Also presume need to define NRF_SDH_CLOCK_LF_ACCURACY as 9 (<9=> NRF_CLOCK_LF_ACCURACY_5_PPM), which I've done.

    Given all of that, sniffer traces show the following in connection requests:

    Simblee:
    Window Size: 3 (3.75 msec)
    Window Offset: 3 (3.75 msec)
    Interval: 24 (30 msec)
    Latency: 0
    Timeout: 72 (720 msec)

    nRF52 DK:
    Window Size: 3 (3.75 msec)
    Window Offset: 9 (11.25 msec)
    Interval: 24 (30 msec)
    Latency: 0
    Timeout: 72 (720 msec)

    BL652:
    Window Size: 3 (3.75 msec)
    Window Offset: 15 (18.75 msec)
    Interval: 24 (30 msec)
    Latency: 0
    Timeout: 72 (720 msec)

    I also see that MTU is 23 bytes in all cases. I've attached the three sniffer traces (captured with Wireshark+nRF Sniffer. For each, peripheral starts advertising, connection with central (iOS device) occurs, a few messages are exchanged, then central disconnects and peripheral begins advertising again.

    What doe Window Size/Offset do? Possible impact on latency? Possible that the peripheral set these?

    Many thanks Bjørn.

    Tim

    Simblee.pcapngnRF52 DK.pcapngBL652 5 ppm.pcapng

  • Tim said:
    Do both the low and high frequency clocks run off of either RC or XTAL?

     Yes, both the HFCLK and the LFCLK may run off an internal oscillator or an XTAL, see CLOCK — Clock control in the nRF52832 Product Specification 

    • 64 MHz on-chip oscillator
    • 64 MHz crystal oscillator, using external 32 MHz crystal
    • 32.768 kHz +/-250 ppm RC oscillator
    • 32.768 kHz crystal oscillator, using external 32.768 kHz crystal
    Tim said:
    What doe Window Size/Offset do? Possible impact on latency? Possible that the peripheral set these?

     I have been looking at the Bluetooth Specification and the Window offset is used to inform the peripheral that it should start listening for the first data packet . 

    Its the Central that dictates the Window offset and the central uses the Window offset to place the first connection event away from other BLE events that have already been scheduled, e.g. other connection events, to avoid collisions.  

    So the Window offset only decides the time between the connection request packet and the first connection event, after the first connection event the peripheral will listen for data packets from the central at the connection interval. 

    Hence, I do not think that this the cause of the latency you're seeing. How do you measure the latency, you stated that your app is measuring time between sensor events on two different peripherals. So the iOS app connect to multiple nRF52's ( Simblee, BL652 or nRF52 DK) , but I am not quite sure how you measure the latency. Do you measuree the time difference between the reception between the first and last sensor data packet with a specific sequence number?  Could you elaborate on how you measure the accuracy?

    -Bjørn

  • Ongoing thanks Bjørn. Correct, an iOS app (central), which we have developed, connects to 2 peripherals. We first used Simblee BLE modules, now switching to BL652. On each peripheral, a sensor is connected to a GPIO pin. We use GPIOTE to watch for sensor event (digital HiToLo). GPIOTE_IRQHandler() is called and app sends message to central via ble_nus_data_send(...) (NUS). iOS app notes time of arrival of message (CBPeripheral method didUpdateValueForCharacteristic). Then the second peripheral does the same when its sensor goes HiToLo. The iOS app now has arrival time of message from first peripheral and same for second peripheral and calculates the difference to find the time between events.

    For testing, I use a 2-channel function generator and connect channel 1 to the GPIO pin on the first peripheral, channel 2 to the same on the second peripheral. I configure the function generator to pulse channels 1 and 2 at a specific offset (say, 4.35 seconds) and watch the times that the iOS apps sees upon receipt of the messages from peripherals. (I actually apply a bit more logic by determining the time for a message to go roundtrip, then divide that by 2 to get roughly the time for the message to go one way, then use that to adjust the iOS message arrival time.)

    I realize that there are many possibilities for latency and latency variation. With Simblee-based boards, I measured roughly 10 ms accuracy. With BL652 boards, I'm seeing around 20 ms. I will do more testing and measurements and provide some helpful data in the coming days.

    Our plan is to implement this solution for synchronizing the clocks on multiple peripherals:

    https://devzone.nordicsemi.com/nordic/nordic-blog/b/blog/posts/wireless-timer-synchronization-among-nrf5-devices

    In the meantime, would like to tune code to provide the best accuracy given current implementation.

    Many thanks for guidance, suggestions.

    Tim

Reply
  • Ongoing thanks Bjørn. Correct, an iOS app (central), which we have developed, connects to 2 peripherals. We first used Simblee BLE modules, now switching to BL652. On each peripheral, a sensor is connected to a GPIO pin. We use GPIOTE to watch for sensor event (digital HiToLo). GPIOTE_IRQHandler() is called and app sends message to central via ble_nus_data_send(...) (NUS). iOS app notes time of arrival of message (CBPeripheral method didUpdateValueForCharacteristic). Then the second peripheral does the same when its sensor goes HiToLo. The iOS app now has arrival time of message from first peripheral and same for second peripheral and calculates the difference to find the time between events.

    For testing, I use a 2-channel function generator and connect channel 1 to the GPIO pin on the first peripheral, channel 2 to the same on the second peripheral. I configure the function generator to pulse channels 1 and 2 at a specific offset (say, 4.35 seconds) and watch the times that the iOS apps sees upon receipt of the messages from peripherals. (I actually apply a bit more logic by determining the time for a message to go roundtrip, then divide that by 2 to get roughly the time for the message to go one way, then use that to adjust the iOS message arrival time.)

    I realize that there are many possibilities for latency and latency variation. With Simblee-based boards, I measured roughly 10 ms accuracy. With BL652 boards, I'm seeing around 20 ms. I will do more testing and measurements and provide some helpful data in the coming days.

    Our plan is to implement this solution for synchronizing the clocks on multiple peripherals:

    https://devzone.nordicsemi.com/nordic/nordic-blog/b/blog/posts/wireless-timer-synchronization-among-nrf5-devices

    In the meantime, would like to tune code to provide the best accuracy given current implementation.

    Many thanks for guidance, suggestions.

    Tim

Children
  • Hi Tim, 

    Since a BLE central will communicate with each peer in sequentially, i.e. first peer 1, then peer 2, peer 3 etc, you will always see a fixed time difference between the reception of packets from different peers. This will be different for each peripheral pair, depending on how far the respective connection events are scheduled by the 

    You also do not know when the GPIO event occured relative to the connection event, so if you call ble_nus_data_send() right after a connection event or just before a connection event will greatly affect the time it takes from the GPIO event occcuring and the packet being received by the central. 

    Lastly, just looking at the reception time does not take into account packet loss or re-transmissions. You will at least need to add some logic to detect and compensate this in some way. 

    So my suggestion, which you are already looking at, would be to synchronize the clock of the peripherals and then timestamp the GPIO events and compare the timestamps and not the reception time. 

    So if your goal at this stage is to synchronize the two peripherals as far as possible without synching the internal timers, then you can look at lowering the connection interval and possibly look at optimizing the the interrupt handling of the GPIO event, i.e. minimize the time from the GPIO interrupt to  sd_ble_gatts_hvx() being called. 

    Is current consumption a priority? If not then you can use the Constant latency mode, which ensures that the wakeup latency is kept at a minimum, see Sub power modes

    Best regards

    Bjørn

  • Thanks Bjørn. Yes, your understanding is correct. For now, I need to synchronize two peripherals as far as possible without syncing internal timers. We do plan to implement internal clock syncing as presented in this blog post.

    I'm seeing very little latency between GPIO interrupt and call to sd_ble_gatts_hvx(). About 0.091551ms. I'm seeing quite a variation in time between call to sd_ble_gatts_hvx() and SoftDevice calling on_hvx_tx_complete(). Range is from 34 to 84 ms. Is this variation due to packet loss, re-transmission? Or connection interval/window? It would be helpful if I could understand the variation and account for it.

    Power consumption is not critical. Our peripherals run on two AA batteries. They are used for a couple hours at a time, usually a few times a week.

    The central is an iOS device so I don't have any control or access to low level BLE.

    Lastly, as we look to a solution for synchronizing internal peripheral clocks, would you recommend the blog post I link to above? All we need is 10ms accuracy between two peripherals. Wondering if the blog post solution is overkill and we could achieve our 10ms requirement with something simpler.

    I appreciate your replies, Bjørn. Learning a lot, which is helpful.

    Tim

  • Hi Tim, 

    Tim said:
    I'm seeing very little latency between GPIO interrupt and call to sd_ble_gatts_hvx(). About 0.091551ms. I'm seeing quite a variation in time between call to sd_ble_gatts_hvx() and SoftDevice calling on_hvx_tx_complete(). Range is from 34 to 84 ms. Is this variation due to packet loss, re-transmission? Or connection interval/window? It would be helpful if I could understand the variation and account for it.

    Yes, retransmissions due to packets being dropped may be the cause for the delay that is larger than the connection interval, i.e. 30ms. In order to minimize the time between calling sd_ble_gatts_hvx and the packet going on air my suggestion would be to lower the connection interval to its lowest setting, i.e. 7.5ms.

    You could also use use the 2Mbps Phy, which will shorten the time it takes for the RADIO to transmit all the bytes compared to the 1Mbps PHY. 

    Tim said:
    Lastly, as we look to a solution for synchronizing internal peripheral clocks, would you recommend the blog post I link to above? All we need is 10ms accuracy between two peripherals. Wondering if the blog post solution is overkill and we could achieve our 10ms requirement with something simpler.

    I think this is the only synchronization solution that we have any source code for I am afraid. Try lowering the connection interval first.

    Best regards

    Bjørn

     

     

Related