Multiperipheral UART Example

villaran gravatar image

asked 2017-07-14 19:27:37 +0200

I am using 3 nrf52 DKs with S132 and SDK13 to try and implement a combination of the multilink and UART examples. I started with the ble_app_uart_c example and added the relevant code from the ble_app_multilink_central example to connect to multiple (in my case 2) peripherals via the NUS instead of the device name as it does in the multilink example. I programmed the two peripherals with the standard ble_app_uart example code, and it works -- the peripherals connect and I can see that the central has assigned connection handles to each of the devices.

However, when I try to send data from the peripherals to the central via a terminal I only get the output from one peripheral, and it's always the one that connected first. BUT if I connect both peripherals, and then unpower the one that connected first, the second one starts to work.

Has anyone seen this problem? One possible clue is the handles for the two devices. Namely, the nus_* handles are all zero for the second device. Could this be the problem?

The first peripheral: {uuid_type = 2 '\002', conn_handle = 0, handles = {nus_tx_handle = 18, nus_tx_cccd_handle = 19, nus_rx_handle = 16}, evt_handler = 0x22121 <ble_nus_c_evt_handler>}

And the second: {uuid_type = 2 '\002', conn_handle = 1, handles = {nus_tx_handle = 0, nus_tx_cccd_handle = 0, nus_rx_handle = 0}, evt_handler = 0x22121 <ble_nus_c_evt_handler>}

edit retag flag offensive close delete report spam

2 answers

Sort by » oldest newest most voted
villaran gravatar image

answered 2017-07-18 18:15:58 +0200

updated 2017-07-18 18:16:46 +0200

I found the problem with my code:

The two lines in ble_nus_c_evt_handler should actually have been:

ble_nus_c_handles_assign(p_ble_nus_c, p_ble_nus_evt->conn_handle, &p_ble_nus_evt->handles);

I was treating the pointer passed to ble_nus_c_evt_handler like the global variable m_ble_nus_c and trying to index into it, when in fact I already had the client handle.

edit flag offensive delete publish link more
hungbui gravatar image

answered 2017-07-17 14:36:02 +0200

Hi Villaran,

Seems that on the second device you haven't done service discovery. This explain why the nus_tx_handle was 0 . This is done by calling ble_db_discovery_start() when BLE_GAP_EVT_CONNECTED event occurred. Please have a look at on_ble_evt() event in main.c

Note that you would need an array to store the attribute table (the handles), if you have 2 devices, you need space for two tables. In the ble_app_uart example it's a single m_ble_db_discovery but in the multilink, it's an array m_ble_db_discovery[]

edit flag offensive delete publish link more


I am actually doing exactly that:

static ble_db_discovery_t       m_ble_db_discovery[TOTAL_LINK_COUNT];


err_code = ble_db_discovery_start(&m_ble_db_discovery[p_gap_evt->conn_handle],

The peripherals are connected to the central, but the BLE_NUS_C_EVT_NUS_TX_EVT only gets generated for the first device.

villaran ( 2017-07-17 17:12:48 +0200 )editconvert to answer

You need to check if the handle (for example nus_tx_handle ) return the correct handle. If not then it's impossible to receive the write command from the central. Were CCCDs enabled on both peripheral (writing 0x01 to CCCD characteristic).
You can try to capture a sniffer trace, it's easier to understand what exactly happens.

Hung Bui ( 2017-07-17 17:18:02 +0200 )editconvert to answer

I have loaded the same code on to both peripherals -- it's just the standard ble_app_uart example code. But I really only need one-way communication from each peripheral to the central. I believe I'm assigning handles and setting the CCCDs for both peripherals with these lines when I get the BLE_NUS_C_EVT_DISCOVERY_COMPLETE:

err_code = ble_nus_c_handles_assign(&p_ble_nus_c[p_ble_nus_evt->conn_handle], p_ble_nus_evt->conn_handle, &p_ble_nus_evt->handles);
err_code = ble_nus_c_tx_notif_enable(&p_ble_nus_c[p_ble_nus_evt->conn_handle]);
villaran ( 2017-07-17 17:21:00 +0200 )editconvert to answer

The reason I asked to check the CCCD is to check if the the central manage to send write command correctly or not. If the central can manage to enable CCCD on both peripheral, there is no reason you couldn't do write command on the TX handle.

Hung Bui ( 2017-07-18 13:04:01 +0200 )editconvert to answer

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer. Do not ask a new question or reply to an answer here.

[hide preview]

Question Tools

1 follower


Asked: 2017-07-14 19:27:37 +0200

Seen: 171 times

Last updated: Jul 18