BLE Connection Issue with Multiple Simultaneous Peripherals

I have a BLE system where multiple sensors operate as peripherals and send data to a BLE central. These sensors enter sleep mode after transmitting data and later wake up to send new information.

I have observed an issue when increasing the number of sensors connected to the same central. Specifically, when two sensors become available for connection simultaneously, communication starts to fail. This affects the system's stability and impacts the reliability of data transmission.

Currently, I establish connections using the UUID of the NUS service, while other BLE parameters, such as the device name, remain identical among the sensors.

Communication Flow:

  1. The central identifies a peripheral through advertising.

  2. The central establishes a connection with the peripheral.

  3. The central stops the scanning process.

  4. The peripheral and central exchange information.

  5. The central disconnects from the peripheral.

  6. The central restarts scanning while two peripherals are advertising simultaneously.

Observed Behavior:

  • If only one sensor is available for connection, the process works correctly.

  • If two sensors are available simultaneously, communication fails, and the central cannot manage connections properly.

  • When this issue occurs, communication starts timing out, there are unexpected disconnections, and intermittent failures appear, such as the following:

00> [01:58:53.731,842] <inf> BLE: scan_filter_match: Filters matched. Address: DE:62:6A:79:C5:A5 (random) connectable: 1
00> [01:58:54.357,177] <inf> BLE: connected: Connected: DE:62:6A:79:C5:A5 (random)
00> [01:58:54.461,456] <inf> BLE: exchange_func: MTU exchange done
00> [01:58:58.293,762] <inf> MAIN: ble_connected_state: Connection state timeout
00> [01:58:58.293,792] <inf> PROTO: log_protocol_infos: Num: 0 - Extra: 0 - Off: 0
00> [01:58:58.293,792] <inf> PROTO: log_protocol_infos: data: 00 00 00 00
00> [01:58:58.293,823] <inf> MAIN: set_state: [STATE_BLE_CONNECTED] -> [STATE_BLE_DISCONNECTION]
00> [01:58:58.393,920] <inf> MAIN: ble_disconnection_state: BLE Disconnection State
00> [01:58:58.393,951] <inf> MAIN: set_state: [STATE_BLE_DISCONNECTION] -> [STATE_BLE_DISCOVERY]
00> [01:58:58.494,049] <inf> MAIN: ble_discovery_state: BLE Discovery State
00> [01:58:58.610,198] <err> nus_c: bt_nus_handles_assign: Missing NUS TX characteristic.
00> [01:58:58.610,198] <err> nus_c: bt_nus_subscribe_receive: Subscribe failed (err -128)
00> [01:58:58.610,351] <inf> BLE: disconnected: Disconnected: DE:62:6A:79:C5:A5 (random) (reason 8)
00> [01:58:58.611,053] <inf> MAIN: ble_discovery_state: BLE Connected
00> [01:58:58.626,312] <inf> MAIN: set_state: [STATE_BLE_DISCOVERY] -> [STATE_BLE_CONNECTED]
00> [01:58:58.726,379] <inf> MAIN: ble_connected_state: START FLAG sent
00> [01:58:58.726,409] <err> BLE: bluetooth_central_send_data: Cannot send data, no BLE connection

Questions:

  1. Are there any known limitations in managing multiple sequential connections with peripherals that have similar parameters?

  2. Are there any recommendations to handle this scenario better? Any specific configurations in Zephyr or SoftDevice that could help?

  3. Any best practices to differentiate peripherals and avoid connection conflicts?

I appreciate any guidance that can help resolve this issue.

Best regards,

Parents
  • Hi Arthur, 

    We will need to take a look at how you handle multiple connections in your central code. 
    Please show your code and your project configuration. 

    Have you looked at this issue: 
    00> [01:58:58.610,198] <err> nus_c: bt_nus_handles_assign: Missing NUS TX characteristic.
    00> [01:58:58.610,198] <err> nus_c: bt_nus_subscribe_receive: Subscribe failed (err -128)


    Have you made sure you do service discovery correctly when connect to a new peripheral ? 

    I would suggest to get familiar with the nRF Sniffer. It's very useful for debugging.  

  • Thanks for your response.

    Currently, our central does not support multiple connections. It simply connects to the first peripheral that appears during the scanning process and performs the entire data exchange procedure with that device.

    We’ve only observed the issue when we have too many sensors operating at the same time — specifically when two or more peripherals are advertising simultaneously at the exact moment the central starts scanning. I’ve attached the central_ble file so you can take a look.

    /* main.c - Application main entry point */
    #include <errno.h>
    #include <zephyr/kernel.h>
    #include <zephyr/device.h>
    #include <zephyr/devicetree.h>
    #include <zephyr/sys/byteorder.h>
    #include <zephyr/bluetooth/bluetooth.h>
    #include <zephyr/bluetooth/hci.h>
    #include <zephyr/bluetooth/conn.h>
    #include <zephyr/bluetooth/uuid.h>
    #include <zephyr/bluetooth/gatt.h>
    #include <bluetooth/services/nus.h>
    #include <bluetooth/services/nus_client.h>
    #include <bluetooth/gatt_dm.h>
    #include <bluetooth/scan.h>
    #include <zephyr/settings/settings.h>
    #include <zephyr/logging/log.h>
    #include <zephyr/random/rand32.h>
    #include "bluetooth_central_app.h"
    #include "data_structures.h"
    #include "protocol.h"
    #include <zephyr/drivers/gpio.h>
    
    LOG_MODULE_REGISTER(BLE, CONFIG_LOG_DEFAULT_LEVEL);
    
    #ifdef CONFIG_USE_CODED_PHY
    #pragma message "Build with LongRange"
    #else
    #pragma message "Build WITHOUT LongRange"
    #endif //CONFIG_USE_CODED_PHY
    
    /* Connection handle */
    static struct bt_conn *default_conn;
    
    /* NUS client handle */
    static struct bt_nus_client nus_client;
    
    /* Buffer to receive data - 492 bytes */
    static uint8_t packet_buffer[BLUETOOTH_PACKET_SIZE] = {0};
    
    /* Buffer size */
    static uint16_t packet_buffer_len = 0;
    
    /* Services discovery flag*/
    static bool services_discovery_completed = false;
    
    K_SEM_DEFINE(ble_connection_discovery_sem, 0, 1);
    
    static void ble_data_sent(struct bt_nus_client *nus, uint8_t err,
    						  const uint8_t *const data, uint16_t len)
    {
    	ARG_UNUSED(nus);
    	//LOG_INF("NUS sent data callback");
    }
    
    void bluetooth_start_scan (void)
    {
    	int ret = bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE);
    	if (ret != SUCCESS) {
    		LOG_ERR("Scanning failed to start (ret %d)", ret);
    	}
    
    	LOG_INF("Start bt_scan");
    }
    
    static uint8_t ble_data_received(struct bt_nus_client *nus, const uint8_t *data, uint16_t len)
    {
    	ARG_UNUSED(nus);
    
    	// LOG_INF("Received data len: %d", len);
    
    	memset((void *)&packet_buffer, (int)0x00, (size_t)BLUETOOTH_PACKET_SIZE);
    	memcpy((void *)&packet_buffer, (const void *)data, (size_t)len);
    	packet_buffer_len = len;
    	if (protocol_parse_packet((const uint8_t *)&packet_buffer, packet_buffer_len) == SUCCESS) {
    		return BT_GATT_ITER_CONTINUE;
    	}
    	return BT_GATT_ITER_STOP;
    }
    
    static void discovery_complete(struct bt_gatt_dm *dm,
    							   void *context)
    {
    	struct bt_nus_client *nus = context;
    	//LOG_INF("Service discovery completed");
    	bt_gatt_dm_data_print(dm);
    	bt_nus_handles_assign(dm, nus);
    	bt_nus_subscribe_receive(nus);
    	bt_gatt_dm_data_release(dm);
    	k_sem_give(&ble_connection_discovery_sem);
    	services_discovery_completed = true;
    }
    
    static void discovery_service_not_found(struct bt_conn *conn, void *context)
    {
    	LOG_INF("Service not found");
    }
    
    static void discovery_error(struct bt_conn *conn, int err, void *context)
    {
    	LOG_ERR("Error while discovering GATT database: (%d)", err);
    }
    
    struct bt_gatt_dm_cb discovery_cb = {
    	.completed = discovery_complete,
    	.service_not_found = discovery_service_not_found,
    	.error_found = discovery_error,
    };
    
    static void gatt_discover(struct bt_conn *conn)
    {
    	int ret = SUCCESS;
    
    	if (conn != default_conn) {
    		return;
    	}
    
    	ret = bt_gatt_dm_start(conn, BT_UUID_NUS_SERVICE, &discovery_cb, &nus_client);
    	if (ret != SUCCESS) {
    		LOG_ERR("could not start the discovery procedure, error code: %d", ret);
    	}
    }
    
    static void exchange_func(struct bt_conn *conn, uint8_t err, struct bt_gatt_exchange_params *params)
    {
    	if (!err) {
    		LOG_INF("MTU exchange done");
    	} else {
    		LOG_ERR("MTU exchange failed (err %" PRIu8 ")", err);
    	}
    }
    
    static void connected(struct bt_conn *conn, uint8_t conn_err)
    {
    	char addr[BT_ADDR_LE_STR_LEN] = {0};
    	int ret = SUCCESS;
    
    	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    
    	if (conn_err) {
    		LOG_ERR("Failed to connect to %s (%d)", addr, conn_err);
    
    		if (default_conn == conn) {
    			bt_conn_unref(default_conn);
    			default_conn = NULL;
    
    			bluetooth_start_scan();
    		}
    
    		return;
    	}
    
    	LOG_INF("Connected: %s", addr);
    
    	// Verificar MTU atual
    	uint16_t mtu = bt_gatt_get_mtu(conn);
    	//LOG_INF("Current MTU size: %u", mtu);
    
    	// Negociar MTU apenas se necessário
    	if (mtu == 23) { // Tamanho padrão significa que ainda não foi negociado
    		static struct bt_gatt_exchange_params exchange_params;
    		exchange_params.func = exchange_func;
    
    		ret = bt_gatt_exchange_mtu(conn, &exchange_params);
    		if (ret == 0) {
    			//LOG_INF("MTU exchange initiated");
    		} else if (ret == -EALREADY) {
    			LOG_WRN("MTU already exchanged");
    		} else {
    			LOG_ERR("MTU exchange failed (ret %d)", ret);
    		}
    	} else {
    		LOG_INF("MTU already negotiated, no need to exchange");
    	}
    
    	gatt_discover(conn);
    	// ret = bt_conn_set_security(conn, BT_SECURITY_L2);
    	// if (ret)
    	// {
    	// 	LOG_WRN("Failed to set security: %d", ret);
    	// 	gatt_discover(conn);
    	// }
    
    	ret = bt_scan_stop();
    	if ((!ret) && (ret != -EALREADY)) {
    		LOG_INF("Stop LE scan failed (ret %d)", ret);
    	}
    }
    
    static void disconnected(struct bt_conn *conn, uint8_t reason)
    {
    	char addr[BT_ADDR_LE_STR_LEN] = {0};
    
    	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    
    	LOG_INF("Disconnected: %s (reason %u)", addr, reason);
    
    	if (default_conn != conn) {
    		return;
    	}
    
    	bt_conn_unref(default_conn);
    	default_conn = NULL;
    }
    
    int bluetooth_is_connected(void)
    {
    	if (default_conn == NULL){
    		return ERROR;
    	}
    
    	return SUCCESS;
    }
    
    void bluetooth_disconnect_ble_nus(void)
    {
    	if (default_conn) {
    		int ret = bt_conn_disconnect(default_conn, BT_HCI_ERR_LOCALHOST_TERM_CONN);
    		if (ret) {
    			LOG_ERR("Disconnection failed (err %d)", ret);
    		} else {
    			LOG_INF("Disconnection initiated");
    		}
    	} else {
    		LOG_INF("No active connection to disconnect");
    	}
    }
    
    static void security_changed(struct bt_conn *conn, bt_security_t level,
    							 enum bt_security_err err)
    {
    	char addr[BT_ADDR_LE_STR_LEN] = {0};
    
    	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    
    	if (!err) {
    		LOG_INF("Security changed: %s level %u", addr, level);
    	}
    	else {
    		LOG_ERR("Security failed: %s level %u err %d", addr, level, err);
    	}
    
    	gatt_discover(conn);
    }
    
    BT_CONN_CB_DEFINE(conn_callbacks) = {
    	.connected = connected,
    	.disconnected = disconnected,
    	.security_changed = security_changed
    };
    
    static void scan_filter_match(struct bt_scan_device_info *device_info,
    							  struct bt_scan_filter_match *filter_match,
    							  bool connectable)
    {
    	char addr[BT_ADDR_LE_STR_LEN] = {0};
    	bt_addr_le_to_str(device_info->recv_info->addr, addr, sizeof(addr));
    	LOG_INF("Filters matched. Address: %s connectable: %d", addr, connectable);
    
    	// Se já houver uma conexão ativa, ignora novos anúncios
    	if (default_conn) {
    		LOG_INF("Já existe conexão ativa. Ignorando novo anúncio.");
    		return;
    	}
    
        #ifdef CONFIG_USE_CODED_PHY
    	int ret;
    	struct bt_conn_le_create_param *conn_params;
    
    	ret = bt_scan_stop();
    	if (ret) {
    		LOG_ERR("Stop LE scan failed (ret %d)", ret);
    	}
    	conn_params = BT_CONN_LE_CREATE_PARAM(
    		BT_CONN_LE_OPT_CODED | BT_CONN_LE_OPT_NO_1M,
    		BT_GAP_SCAN_FAST_INTERVAL,
    		BT_GAP_SCAN_FAST_INTERVAL);
    	ret = bt_conn_le_create(device_info->recv_info->addr, conn_params,
    							BT_LE_CONN_PARAM_DEFAULT,
    							&default_conn);
    	if (ret) {
    		LOG_ERR("Create conn failed (ret %d)", ret);
    
    		bluetooth_start_scan();
    	}
    	//LOG_INF("Connection pending");
    
        #endif //CONFIG_USE_CODED_PHY
    }
    
    static void scan_connecting_error(struct bt_scan_device_info *device_info)
    {
    	LOG_ERR("Connecting failed");
    }
    
    static void scan_connecting(struct bt_scan_device_info *device_info,
    							struct bt_conn *conn)
    {
    	default_conn = bt_conn_ref(conn);
    }
    
    static int nus_client_init(void)
    {
    	int ret = SUCCESS;
    	struct bt_nus_client_init_param init = {
    		.cb = {
    			.received = ble_data_received,
    			.sent = ble_data_sent,
    		}
    	};
    
    	ret = bt_nus_client_init(&nus_client, &init);
    	if (ret != SUCCESS) {
    		LOG_ERR("NUS Client initialization failed (ret %d)", ret);
    		return ret;
    	}
    
    	LOG_INF("NUS Client module initialized");
    	return ret;
    }
    
    BT_SCAN_CB_INIT(scan_cb, scan_filter_match, NULL,
    				scan_connecting_error, scan_connecting);
    
    static int scan_init(void)
    {
    	int ret = SUCCESS;
    
        #ifdef CONFIG_USE_CODED_PHY
    	/* Use active scanning and disable duplicate filtering to handle any
    	 * devices that might update their advertising data at runtime. */
    	struct bt_le_scan_param scan_param = {
    		.type     = BT_LE_SCAN_TYPE_ACTIVE,
    		.interval = BT_GAP_SCAN_FAST_INTERVAL,
    		.window   = BT_GAP_SCAN_FAST_WINDOW,
    		.options  = BT_LE_SCAN_OPT_CODED | BT_LE_SCAN_OPT_NO_1M
    	};
    
    	struct bt_scan_init_param scan_init = {
    		.connect_if_match = 0,
    		.scan_param = &scan_param,
    		.conn_param = NULL
    	};
    	#else
    	struct bt_scan_init_param scan_init = {
    		.connect_if_match = 1,
    	};
        #endif //CONFIG_USE_CODED_PHY
    
    	bt_scan_init(&scan_init);
    	bt_scan_cb_register(&scan_cb);
    
    	ret = bt_scan_filter_add(BT_SCAN_FILTER_TYPE_UUID, BT_UUID_NUS_SERVICE);
    	if (ret != SUCCESS) {
    		LOG_ERR("Scanning filters cannot be set (ret %d)", ret);
    		return ret;
    	}
    
    	ret = bt_scan_filter_enable(BT_SCAN_UUID_FILTER, false);
    	if (ret != SUCCESS) {
    		LOG_ERR("Filters cannot be turned on (ret %d)", ret);
    		return ret;
    	}
    
    	LOG_INF("Scan module initialized");
    	return ret;
    }
    
    static void auth_cancel(struct bt_conn *conn)
    {
    	char addr[BT_ADDR_LE_STR_LEN] = {0};
    	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    	LOG_INF("Pairing cancelled: %s", addr);
    }
    
    static void pairing_complete(struct bt_conn *conn, bool bonded)
    {
    	char addr[BT_ADDR_LE_STR_LEN] = {0};
    	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    	LOG_INF("Pairing completed: %s, bonded: %d", addr, bonded);
    }
    
    static void pairing_failed(struct bt_conn *conn, enum bt_security_err reason)
    {
    	char addr[BT_ADDR_LE_STR_LEN] = {0};
    	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
    	LOG_WRN("Pairing failed conn: %s, reason %d", addr, reason);
    }
    
    static struct bt_conn_auth_cb conn_auth_callbacks = {
    	.cancel = auth_cancel,
    };
    
    static struct bt_conn_auth_info_cb conn_auth_info_callbacks = {
    	.pairing_complete = pairing_complete,
    	.pairing_failed = pairing_failed
    };
    
    int bluetooth_central_init(void)
    {
    	int ret = SUCCESS;
    
    	// Enable pins of SKY66112-11
    	const struct device* gpio0_dev = device_get_binding("gpio@50000000"); // gpio 0
    
    	//	Table 6. SKY66112-11 Mode Control Logic1
    	//	Mode	Description 		CPS	CHL
    	//	1 	Receive LNA 		0 	X
    	//	2 	Transmit high-power 	0 	1
    
    	gpio_pin_configure(gpio0_dev, 6, GPIO_OUTPUT); // gpio 0.06 - CPS
    	gpio_pin_set(gpio0_dev, 6, 0);
    	gpio_pin_configure(gpio0_dev, 8, GPIO_OUTPUT); // gpio 0.08 - CHL
    	gpio_pin_set(gpio0_dev, 8, 1);
    
    	ret = bt_conn_auth_cb_register(&conn_auth_callbacks);
    	if (ret != SUCCESS) {
    		LOG_ERR("Failed to register authorization callbacks.");
    		return ERROR;
    	}
    
    	ret = bt_conn_auth_info_cb_register(&conn_auth_info_callbacks);
    	if (ret != SUCCESS) {
    		LOG_ERR("Failed to register authorization info callbacks.");
    		return ERROR;
    	}
    
    	ret = bt_enable(NULL);
    	if (ret != SUCCESS) {
    		LOG_ERR("Bluetooth init failed (ret %d)", ret);
    		return ERROR;
    	}
    	LOG_INF("Bluetooth initialized");
    
    	if (IS_ENABLED(CONFIG_SETTINGS)) {
    		settings_load();
    	}
    
    	ret = scan_init();
    	if (ret != SUCCESS) {
    		LOG_ERR("scan_init failed (ret %d)", ret);
    		return ERROR;
    	}
    
    	ret = nus_client_init();
    	if (ret != SUCCESS) {
    		LOG_ERR("nus_client_init failed (ret %d)", ret);
    		return ERROR;
    	}
    
    	ret = bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE);
    	if (ret != SUCCESS) {
    		LOG_ERR("Scanning failed to start (ret %d)", ret);
    		return ERROR;
    	}
    
    	LOG_INF("Scanning successfully started");
    
    	return SUCCESS;
    }
    
    int bluetooth_central_send_data(const uint8_t *data, uint16_t len)
    {
    	int ret = SUCCESS;
    	if (!default_conn) {
    		LOG_ERR("Cannot send data, no BLE connection");
    		return -ENOTCONN;
    	}
    
    	ret = bt_nus_client_send(&nus_client, data, len);
    	if (ret != SUCCESS) {
    		LOG_ERR("BT NUS send ERROR: %d", ret);
    		return ERROR;
    	}
    	return ret;
    }
    
    bool bluetooth_service_discovery_completed(void)
    {
    	return services_discovery_completed;
    }
    

    In this case, is implementing multiple simultaneous connections strictly necessary to avoid this failure? If so, would you happen to have an example suited to this use case?

    Our idea is to keep the current approach: connect to the first sensor that appears, perform the data exchange, and disconnect. The other peripherals would only send a command or flag indicating they should wait or disconnect if not selected.

    Let me know your thoughts. Thanks again for the support!

    Best regards,

    Arthur

  • Hi Arthur, 

    What you describe is a very common use case for a central device that it need to scan for a peripheral and connect to it. I am not aware of any issue related to the central has problem when multiple peripherals advertise. I don't think implementing multi connection handling is the way to go here. 

    From what I can see in your log is that right after connection the link is terminated: 

    00> [01:58:53.731,842] <inf> BLE: scan_filter_match: Filters matched. Address: DE:62:6A:79:C5:A5 (random) connectable: 1
    00> [01:58:54.357,177] <inf> BLE: connected: Connected: DE:62:6A:79:C5:A5 (random)
    00> [01:58:54.461,456] <inf> BLE: exchange_func: MTU exchange done
    00> [01:58:58.293,762] <inf> MAIN: ble_connected_state: Connection state timeout
    00> [01:58:58.293,792] <inf> PROTO: log_protocol_infos: Num: 0 - Extra: 0 - Off: 0
    00> [01:58:58.293,792] <inf> PROTO: log_protocol_infos: data: 00 00 00 00
    00> [01:58:58.293,823] <inf> MAIN: set_state: [STATE_BLE_CONNECTED] -> [STATE_BLE_DISCONNECTION]
    00> [01:58:58.393,920] <inf> MAIN: ble_disconnection_state: BLE Disconnection State

    But I don't fully understand this: 
    00> [01:58:58.393,951] <inf> MAIN: set_state: [STATE_BLE_DISCONNECTION] -> [STATE_BLE_DISCOVERY]
    00> [01:58:58.494,049] <inf> MAIN: ble_discovery_state: BLE Discovery State

    What is this discovery state ? Can you show the code ? 

    After the device get disconnected the process of discovery, subscribe to the characteristic or sending data should be stopped. But from the log it was not. The state machine continued after the disconnection. So you need to check your state machine and should not continue to call bluetooth_central_send_data() if the link is disconnected or if bt_nus_subscribe_receive() return failed. 

    Do you see the same problem when you test with our central_uart sample ?

Reply
  • Hi Arthur, 

    What you describe is a very common use case for a central device that it need to scan for a peripheral and connect to it. I am not aware of any issue related to the central has problem when multiple peripherals advertise. I don't think implementing multi connection handling is the way to go here. 

    From what I can see in your log is that right after connection the link is terminated: 

    00> [01:58:53.731,842] <inf> BLE: scan_filter_match: Filters matched. Address: DE:62:6A:79:C5:A5 (random) connectable: 1
    00> [01:58:54.357,177] <inf> BLE: connected: Connected: DE:62:6A:79:C5:A5 (random)
    00> [01:58:54.461,456] <inf> BLE: exchange_func: MTU exchange done
    00> [01:58:58.293,762] <inf> MAIN: ble_connected_state: Connection state timeout
    00> [01:58:58.293,792] <inf> PROTO: log_protocol_infos: Num: 0 - Extra: 0 - Off: 0
    00> [01:58:58.293,792] <inf> PROTO: log_protocol_infos: data: 00 00 00 00
    00> [01:58:58.293,823] <inf> MAIN: set_state: [STATE_BLE_CONNECTED] -> [STATE_BLE_DISCONNECTION]
    00> [01:58:58.393,920] <inf> MAIN: ble_disconnection_state: BLE Disconnection State

    But I don't fully understand this: 
    00> [01:58:58.393,951] <inf> MAIN: set_state: [STATE_BLE_DISCONNECTION] -> [STATE_BLE_DISCOVERY]
    00> [01:58:58.494,049] <inf> MAIN: ble_discovery_state: BLE Discovery State

    What is this discovery state ? Can you show the code ? 

    After the device get disconnected the process of discovery, subscribe to the characteristic or sending data should be stopped. But from the log it was not. The state machine continued after the disconnection. So you need to check your state machine and should not continue to call bluetooth_central_send_data() if the link is disconnected or if bt_nus_subscribe_receive() return failed. 

    Do you see the same problem when you test with our central_uart sample ?

Children
No Data
Related