Hello,
I'm developing a BLE Central application using the nRF52 SDK.
The central connects to multiple peripheral devices (nRF52832), each sending 6-byte ADXL345 accelerometer data at 20 Hz via Nordic UART Service (NUS).
I'm using the BLE_NUS_C_ARRAY_DEF(m_ble_nus_c, NRF_SDH_BLE_CENTRAL_LINK_COUNT)
macro to support multiple clients, based on project: https://github.com/NordicPlayground/nrf52-ble-app-uart-c-multilink
And I want to classify data that where it is from
Everything works fine for:
-
Scanning and connecting to peripherals
-
MTU exchange
-
Service discovery
-
Assigning
conn_handle
to the correct NUS client index -
Enabling notifications
-
Disconnection and MAC cleanup
What doesn't work: Only the first connected peripheral (typically assigned conn_handle = 0x0000
) successfully sends data via BLE_NUS_C_EVT_NUS_TX_EVT
.
Even though the others connect and complete discovery, they never trigger NUS data events, and I receive no data from them.
I've verified that:
-
Each peripheral works correctly (tested with Android, receiving data from 5 devices in parallel)
- GAP success of each peripheral device, and NUS discovery success of each peripheral device.
Attached is the debug terminal image, which verifies the function works well, but the data comes from the first connected peripheral device.
--------------------------------------------------------------------------------------------
Any idea why only one peripheral sends data, even though others connect successfully and notifications are enabled?
How can I reliably receive data from all connected peripherals and distinguish where each packet comes from?
Below are the parts of the code I've made.
typedef struct { uint16_t conn_handle; // Assigned connection handle for the peripheral ble_gap_addr_t mac_addr; // MAC address of the connected peripheral bool in_use; // Slot usage flag } device_info_t; static device_info_t m_connected_devices[MAX_CONNECTED_DEVICES]; // Array to track connected peripherals ~~~~ static void scan_evt_handler(scan_evt_t const * p_scan_evt) { ret_code_t err_code; switch (p_scan_evt->scan_evt_id) { case NRF_BLE_SCAN_EVT_CONNECTING_ERROR: // Connection failed, report error err_code = p_scan_evt->params.connecting_err.err_code; APP_ERROR_CHECK(err_code); break; case NRF_BLE_SCAN_EVT_CONNECTED: { // Successfully initiated connection to peripheral ble_gap_evt_connected_t const * p_connected = p_scan_evt->params.connected.p_connected; NRF_LOG_INFO("Connecting to target %02x%02x%02x%02x%02x%02x", p_connected->peer_addr.addr[0], p_connected->peer_addr.addr[1], p_connected->peer_addr.addr[2], p_connected->peer_addr.addr[3], p_connected->peer_addr.addr[4], p_connected->peer_addr.addr[5]); // Store MAC address in the first available slot for (int i = 0; i < MAX_CONNECTED_DEVICES; i++) { if (!m_connected_devices[i].in_use) { m_connected_devices[i].mac_addr = p_connected->peer_addr; m_connected_devices[i].in_use = true; break; } } break; } case NRF_BLE_SCAN_EVT_SCAN_TIMEOUT: // Restart scanning on timeout NRF_LOG_INFO("Scan timed out."); scan_start(); break; default: break; } } ~~~~ static void ble_nus_c_evt_handler(ble_nus_c_t * p_ble_nus_c, ble_nus_c_evt_t const * p_ble_nus_evt) { ret_code_t err_code; switch (p_ble_nus_evt->evt_type) { case BLE_NUS_C_EVT_DISCOVERY_COMPLETE: { // Find the device slot matching the connection handle int matched_index = -1; for (int i = 0; i < MAX_CONNECTED_DEVICES; i++) { if (m_connected_devices[i].in_use && m_connected_devices[i].conn_handle == p_ble_nus_evt->conn_handle) { matched_index = i; break; } } if (matched_index != -1) { // Assign handles to the correct NUS client and enable notifications err_code = ble_nus_c_handles_assign(&m_ble_nus_c[matched_index], p_ble_nus_evt->conn_handle, &p_ble_nus_evt->handles); APP_ERROR_CHECK(err_code); err_code = ble_nus_c_tx_notif_enable(&m_ble_nus_c[matched_index]); APP_ERROR_CHECK(err_code); NRF_LOG_INFO("Discovery complete.:conn_handle = 0x%04X assigned to NUS[%d]", p_ble_nus_evt->conn_handle, matched_index); } else { NRF_LOG_WARNING("No matching MAC slot for conn_handle 0x%04X", p_ble_nus_evt->conn_handle); } break; } case BLE_NUS_C_EVT_NUS_TX_EVT: { // Incoming data from a peripheral — identify and log it uint16_t conn_handle = p_ble_nus_evt->conn_handle; uint8_t *data = p_ble_nus_evt->p_data; uint16_t len = p_ble_nus_evt->data_len; for (int i = 0; i < MAX_CONNECTED_DEVICES; i++) { if (m_connected_devices[i].in_use && m_connected_devices[i].conn_handle == conn_handle) { ble_gap_addr_t *addr = &m_connected_devices[i].mac_addr; NRF_LOG_INFO("[%02X:%02X:%02X] data received %d", addr->addr[5], addr->addr[4], addr->addr[3], m_connected_devices[i].conn_handle); NRF_LOG_HEXDUMP_INFO(data, len); } } break; } case BLE_NUS_C_EVT_DISCONNECTED: // Re-start scanning when a device disconnects NRF_LOG_INFO("Disconnected.NUS_C"); scan_start(); break; } }
I guess there might be problems in the "BLE_NUS_C_EVT_NUS_TX_EVT:" I cannot find out how to solve this problem.
Please help me and thanks in advance.