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

How to sent a 200 bytes data packet via NUS every 20ms between nRF52832 and nRF52840

Hello, I'm making a system with NUS of nRF52832 and nRF52840 to sample data with SAADC. I started the system with "ble_app_uart__saadc_timer_driven__scan_mode_03" from Github "NordicPlayground". The link is below: nRF52-ADC-examples/README.md at master · NordicPlayground/nRF52-ADC-examples (github.com).

The source code is based on timer driven to sample the data and transmit via NUS(Nordic UART Service) in a nRF52832 board. The data is transmit to NRF52840 DK board which served as central board and sent to the computer via UART port. 

Now I need to realize a 1kHz sample rate with 4 channels and 12bit resolution. It is too frequency to send data every 1ms. So I save the data in an buffer and transfer the data every 10 samples. In the source code, the sample rate is define as below.

#define SAADC_SAMPLES_IN_BUFFER         4
#define SAADC_SAMPLE_RATE               5                                         /**< SAADC sample rate in ms. */    

I can decease the sample interval to 4 or 5 and the data can be transfer to computer with no problem. But when I decrease the sample interval to 1ms and increase the sample rate to 1kHz, the BLE connection has some problem and data cannot be sent to central board and computer. What cause the problem? I have adjusted the advertising time of the peripherals and scan time of the central, but it didn't work. I have posted some questions before and got some suggestion about that, the typical answer is based on https://infocenter.nordicsemi.com/topic/sds_s140/SDS/s1xx/multilink_scheduling/central_connection_timing.html . I can partly understand that but I didn't know how to match the timing parameter between the website and the source code. Would you please help me solve that? Any help will be appreciated. 

Parents
  • Hi,

    I suggest to check out this page that describe some good tips:
    https://www.novelbits.io/bluetooth-5-speed-maximum-throughput/

    To find what may be reducing the throughput further we may need an on-air sniffer log:
    https://infocenter.nordicsemi.com/topic/ug_sniffer_ble/UG/sniffer_ble/intro.html

    Best regards,
    Kenneth

  • I suggest to check out the throughput example project in the nRF5 SDK. For instance your connection interval is rather slow (30ms), it should be possible to lower this to for instance 7.5ms if you have an nRF device in both ends of the link:

    Another strange thing is that I can see the master is skippin many connection intervals, it should be consistenly 30ms, but instead I can find it's both ~30, ~60, and ~90ms intervals. Likely this indicate that the central is busy scheduling other BLE activities, either other links, scanning etc. So this will have e negative effect on the throughput for the link you are monitoring.

    Not quite sure what you can tell me about the other BLE activities the central is doing here, but that seems to be the main limiting factor.

    Kenneth

  • Hi Kenneth, thank you for your reply. I have tried other examples in the nRF5 SDK and it's lots of migration between the firmware. I will try later. This firmware also based on the example which NORDIC released and it's also released by NORDIC I think. 

    I have checked my code, as you said. The configuration of the peripheral is listed below and I didn't find the definition of connection intervals to be 30ms.

    #define APP_BLE_CONN_CFG_TAG            1                                           /**< A tag identifying the SoftDevice BLE configuration. */
    
    #define DEVICE_NAME                     "Nordic_UART_SAADC_01"                               /**< Name of device. Will be included in the advertising data. */
    #define NUS_SERVICE_UUID_TYPE           BLE_UUID_TYPE_VENDOR_BEGIN                  /**< UUID type for the Nordic UART Service (vendor specific). */
    
    #define APP_BLE_OBSERVER_PRIO           3                                           /**< Application's BLE observer priority. You shouldn't need to modify this value. */
    
    #define APP_ADV_INTERVAL                64                                          /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */
    
    #define APP_ADV_DURATION                18000                                       /**< The advertising duration (180 seconds) in units of 10 milliseconds. */
    
    #define MIN_CONN_INTERVAL               MSEC_TO_UNITS(10, UNIT_1_25_MS)             // 20 /**< Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */
    #define MAX_CONN_INTERVAL               MSEC_TO_UNITS(75, UNIT_1_25_MS)             /**< Maximum acceptable connection interval (75 ms), Connection interval uses 1.25 ms units. */
    #define SLAVE_LATENCY                   0                                           /**< Slave latency. */
    #define CONN_SUP_TIMEOUT                MSEC_TO_UNITS(4000, UNIT_10_MS)             /**< Connection supervisory timeout (4 seconds), Supervision Timeout uses 10 ms units. */
    #define FIRST_CONN_PARAMS_UPDATE_DELAY  APP_TIMER_TICKS(5000)                       /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */
    #define NEXT_CONN_PARAMS_UPDATE_DELAY   APP_TIMER_TICKS(30000)                      /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */
    #define MAX_CONN_PARAMS_UPDATE_COUNT    3                                           /**< Number of attempts before giving up the connection parameter negotiation. */
    
    #define DEAD_BEEF                       0xDEADBEEF                                  /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */
    
    #define UART_TX_BUF_SIZE                256                                         /**< UART TX buffer size. */
    #define UART_RX_BUF_SIZE                256                                         /**< UART RX buffer size. */
    
    #define SAADC_SAMPLES_IN_BUFFER         4
    #define SAADC_SAMPLE_RATE               4                                         /**< SAADC sample rate in ms. */               
    
    #define PACKET_SIZE                     20                                          // MING
    
    BLE_NUS_DEF(m_nus, NRF_SDH_BLE_TOTAL_LINK_COUNT);                                   /**< BLE NUS service instance. */
    NRF_BLE_GATT_DEF(m_gatt);                                                           /**< GATT module instance. */
    NRF_BLE_QWR_DEF(m_qwr);                                                             /**< Context for the Queued Write module.*/
    BLE_ADVERTISING_DEF(m_advertising);                                                 /**< Advertising module instance. */
    
    I have modified the parameter "MIN_CONN_INTERVAL" to 10ms and nothing else. Which code is related to the connection interval? Thanks.

  • On the central side, I used "nrf52-ble-app-uart-c-multilink-master" as example. It's also based on the "ble_app_multilink_central" project in "ble_central " folder. I didn't find any connection parameter in main.c but I get some in the sdk_config.h files which listed below. Does it match the peripheral firmware? Thanks.

    // <o> NRF_BLE_SCAN_SCAN_INTERVAL - Scanning interval. Determines the scan interval in units of 0.625 millisecond. 
    #ifndef NRF_BLE_SCAN_SCAN_INTERVAL
    #define NRF_BLE_SCAN_SCAN_INTERVAL 160               //160
    #endif
    
    // <o> NRF_BLE_SCAN_SCAN_DURATION - Duration of a scanning session in units of 10 ms. Range: 0x0001 - 0xFFFF (10 ms to 10.9225 ms). If set to 0x0000, the scanning continues until it is explicitly disabled. 
    #ifndef NRF_BLE_SCAN_SCAN_DURATION
    #define NRF_BLE_SCAN_SCAN_DURATION 0
    #endif
    
    // <o> NRF_BLE_SCAN_SCAN_WINDOW - Scanning window. Determines the scanning window in units of 0.625 millisecond. 
    #ifndef NRF_BLE_SCAN_SCAN_WINDOW
    #define NRF_BLE_SCAN_SCAN_WINDOW 80                     //80
    #endif
    
    // <o> NRF_BLE_SCAN_MIN_CONNECTION_INTERVAL - Determines minimum connection interval in milliseconds. 
    #ifndef NRF_BLE_SCAN_MIN_CONNECTION_INTERVAL
    #define NRF_BLE_SCAN_MIN_CONNECTION_INTERVAL 7.5       //7.5
    #endif
    
    // <o> NRF_BLE_SCAN_MAX_CONNECTION_INTERVAL - Determines maximum connection interval in milliseconds. 
    #ifndef NRF_BLE_SCAN_MAX_CONNECTION_INTERVAL
    #define NRF_BLE_SCAN_MAX_CONNECTION_INTERVAL 30      //30
    #endif

  • Since the "Windows size" and "interval" is a index number and the real time is about "1.25" proportional to the number, so I guess we should correct the MIN_CONN_INTERVAL and MAX_CONN_INTERVAL in the peripheral. Am I right? But when I decreased the parameters to 5 and 35 respectively, The peripheral will keep in fatal errors. How to correct that? Thanks.

  • If you build with DEBUG then you should get more information about the error from app_error_fault_handler() in app_error_weak.c

    Kenneth

Reply Children
No Data
Related