This blog is to show the method how to configure the number of packets per each connection interval. Basically, it is very similar to the blog (https://jimmywongiot.com/2019/12/15/how-to-set-the-bandwidth-on-ble-link-connection/).
I would give more details how to achieve for example 3 packet per connection interval.

Suppose on the Nordic nRF5 SDK, it has the MACRO NRF_SDH_BLE_GAP_EVENT_LENGTH.
It was introduced since Softdevice S132v4.0 or later. It can assign the timing for each connection.
// <i> The time set aside for this connection on every connection interval in 1.25 ms units.
#ifndef NRF_SDH_BLE_GAP_EVENT_LENGTH
#define NRF_SDH_BLE_GAP_EVENT_LENGTH 6
#endif
Example
Here is the example how to send 3 packets per each connection interval (7.5ms)
Connection interval = 7.5ms

Duration of each packet DLE = 251, MTU = 247 at 2Mbps ~= 1.4ms


Radio Notification
What is Radio Notification? – Nordic DevZone
- Radio notification allows the application to receive an interrupt (SWI1) before, after or both before and after a scheduled radio event is happening. This event can be a connection event, advertising event, timeslot event or flash operation. This way the application can synchronize application logic with the radio operations.
The application layer can get the RADIO activity through its notification. By setting difference distance between the RADIO is active, the application would be early alert.


In order to set the number of packets per connection interval,
Step 1:
#define MAXIMUM_NUMBER_PACKET_PER_INTERVAL 3
Step 2: Initialize the Radio notification
static void radio_notification_init(void)
{
ble_radio_notification_init(APP_IRQ_PRIORITY_LOW_MID, NRF_RADIO_NOTIFICATION_DISTANCE_800US, radio_notification_handler);
}
static ble_radio_notification_evt_handler_t radio_notification_handler(bool radio_active)
{
if (!radio_active)
{
m_number_of_packets_per_interval = MAXIMUM_NUMBER_PACKET_PER_INTERVAL;
}
else
{
}
}
Step 3:
static uint32_t data_transmit_single_packet(uint8_t *send_data, uint16_t len)
{
uint32_t err_code = NRF_SUCCESS;
uint16_t length = len;
if (m_number_of_packets_per_interval <= 0)
return NRF_EXCEED_NUMBER_PACKETS;
// Send data back to the peripheral.
err_code = ble_nus_c_data_send(&m_ble_nus_c, m_test_buffer, length);
if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY) && (err_code != NRF_ERROR_RESOURCES))
{
NRF_LOG_ERROR("Failed sending NUS message. Error 0x%x. ", err_code);
APP_ERROR_CHECK(err_code);
}
m_number_of_packets_per_interval--;
if (err_code != NRF_ERROR_RESOURCES)
throughput_measure_send_update(length);
return NRF_ERROR_RESOURCES;
}
Step 4: Loop to send the data at the main thread

Welcome to give me some comments and feedback.
As I understand if I call data_transmit_single_packet() for fourth packet in one connection interval this function will check m_number_of_packets_per_interval and return success, but data won’t send. Is it correct behavior?
LikeLike
Yes, it should return the NRF_EXCEED_NUMBER_PACKETS instead of NRF_SUCCESS.
Because it has exceed the number of packets per interval.
static uint32_t data_transmit_single_packet(uint8_t *send_data, uint16_t len)
{
uint32_t err_code = NRF_SUCCESS;
uint16_t length = len;
if (m_number_of_packets_per_interval <= 0)
return NRF_EXCEED_NUMBER_PACKETS;
LikeLike
about ble_radio_notification_evt_handler_t .(for the old nordic sdk)
could be use BLE_EVT_TX_COMPLETE event ?
and when Between connect interval , ble stack should be queue?
LikeLike
the key point is that you don’t know the timing on each connection interval.
You don’t have the reference point and then use the TX Complete to tune the number of packets per connection interval.
LikeLike
Hello, I have some questions.
What program did you use for measured connection Interval?
LikeLike
You can use the radio notification with rtc tick to measure.
LikeLike
Very interesting project! I am trying to implement it in my nRF52840DK boards, but apparently, I am facing some errors from just copying your code.
Could you pls give some suggestions, like if I should include some other files, or make some changes to the code? Or it would be best if you can share the document.
LikeLike
Please go through Nordic Devzone to get the support.
LikeLike
Hello Jimmy.
I’m always impressed by your blog.
I have a question.
Can radio notification distinguish between “active” and “inactive” signals from SWI1_IRQHandler functions?
LikeLike
You can use the variable (radio_active) as the indicator.
static ble_radio_notification_evt_handler_t radio_notification_handler(bool radio_active)
{
if (!radio_active)
{
m_number_of_packets_per_interval = MAXIMUM_NUMBER_PACKET_PER_INTERVAL;
}
else
{
}
}
LikeLike
Hi Jimmy, my congratulations for your amazing work. It is brilliant. I have a puzzle that is baffling me. I’m using Nordic SoftDevice S140 – 7.2.0, I’m able to put in the connection interval the number of notifications I want (after reading your suggestions here), everything is fine. The problem is that after a certain number of executions that are quite okay, once in a while, from the very beginning of the BLE connection, communication is struggling. Number of notifications inside the connection is highly decreased, apparently (looking at the sniffer output) lots of packets are dropped for errors. But it suffice a reset to have a clean communication once again (that’s why I don’t think any noise/interference to be the problem here). It seems like something from the very beginning of the connection, is spoiling once in a while SoftDevice performances. But really I cannot figure out precisely, what would be (maybe something in timing, but how to check). Have you ever encountered any issue like this? Do you feel like telling your opinion about such an issue? Thank you for your kind and precious attention.
Best regards
LikeLike
Hi Alessandro,
Step 1:
You can use the TX_COMPLETE_EVENT (by using the GPIO toggle) to check the communication status. If the data is transmitted correctly, the number of packets per interval would be synced with TX Complete.
Step 2:
You may change the radio notification distance from 800us to longer. (just for debugging purposes to figure out the racing condition).
Jimmy
LikeLike