About NUS connection

I have implemented NUS on device A and confirmed that it can be connected from a PC by making it the advertising sender.

Device B can scan device A's advertisements and obtain values ​​from the advertisement data.

I would like to add an NUS function to device B so that device B can search for a specific Bluetooth ID from the advertisement and set it on device A via an NUS connection.

I am currently adding NUS_C to device B and trying to run it, but ble_nus_c_init() returns 14.

Please tell me what to do.

Parents
  • Hi,

    I see you are using the nRF5 SDK. That incldues the Nordic UART Service Client example, which is a Central and does what you describe here (this works together with the UART/Serial Port Emulation over BLE peripehral example).

    Regardign the -8 error you get, that is NRF_ERROR_INVALID_STATE. And you typically get this from sd_ble_gap_connect() if a connection is allready in progress. You will also get this error cod eif you call sd_ble_gap_scan_stop when it is not scanning (if you just wanted to terminate scanning if active you can shoose to ignore this error code, for instance by only calling APP_ERROR_CHECK if the error is different from NRF_ERROR_INVALID_STATE).

    But as the description you have match well with the central NUS example linked above, I suggest you test with this first and either base your client on that or copy-past the relevant parts into your application as that i a known working implementation.

  • Thank you for your answer.

    By adding UART initialization, the NRF_ERROR_INVALID_STATE problem is resolved.

    However, when I execute err_code2 = sd_ble_gap_connect(&addr, &scan_params, &conn_params, con_cfg_tag);, 0x05 (NRF_ERROR_NOT_FOUND) is returned and I cannot connect.

    What could be the cause?

    void scan_evt_handler(scan_evt_t const * p_scan_evt)
    {
        switch (p_scan_evt->scan_evt_id)
        {
            case BLE_GAP_EVT_ADV_REPORT:
                break;
            case NRF_BLE_SCAN_EVT_SCAN_TIMEOUT:
                NRF_LOG_INFO("Scan timeout.");
                break;
    
            case NRF_BLE_SCAN_EVT_CONNECTING_ERROR:
                NRF_LOG_ERROR("Connection error.");
                break;
    
            case NRF_BLE_SCAN_EVT_CONNECTED:
                NRF_LOG_INFO("Connected to device.");
                break;
    
            case NRF_BLE_SCAN_EVT_FILTER_MATCH:
            {
                // Get Advertising Report
                ble_gap_evt_adv_report_t const * p_adv_report = p_scan_evt->params.filter_match.p_adv_report;
    
                // Get advertising data
                const uint8_t * p_data = p_adv_report->data.p_data; // Get p_data from ble_data_t
                uint16_t data_len = p_adv_report->data.len; 		// Get the data length from ble_data_t
    
                // Get Device Name
                char device_name[BLE_GAP_DEVNAME_MAX_LEN + 1]; 		// A buffer for the device name
                memset(device_name, 0, sizeof(device_name)); 		// Clear the buffer
    
                // Finding device names from advertising data
                uint8_t * p_name_data = ble_advdata_parse((uint8_t *)p_data, data_len, BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME);
                if (p_name_data != NULL)
                {
                    // Get the length of the device name
                    uint8_t name_len = strlen((const char *)p_name_data);
                    strncpy(device_name, (char *)p_name_data, name_len);
                    device_name[name_len] = '\0'; 					// NULL terminated
                    device_name[6] = '\0';
                    // If the device names match, the connection is initiated.
                    if (strcmp(device_name, TARGET_DEVICE_NAME) == 0)
                    {
                        // Set the address of the destination device
                        Name_acquisition_flag = 1;
                        ble_gap_addr_t addr;
                        addr.addr_id_peer = 0; 												// 0 if not a private address
                        addr.addr_type = p_adv_report->peer_addr.addr_type; 				// Set the address type (0x01)
                        memcpy(addr.addr, p_adv_report->peer_addr.addr, BLE_GAP_ADDR_LEN); 	// Copy address
    
                        // Initialize scan parameters
                        ble_gap_scan_params_t scan_params;
                        memset(&scan_params, 0, sizeof(scan_params)); 						// Zero Initialization
                        scan_params.extended = 0; 											// 0 if you do not want to use extended scanning
                        scan_params.active = 1; 											// Enable Active Scanning
                        scan_params.report_incomplete_evts = 0; 							// Do not report incomplete events
                        scan_params.scan_phys = BLE_GAP_PHY_1MBPS; 							// Back PHY and feeling  (0x01)
                        scan_params.interval = 160; 										// Set the scan interval
                        scan_params.window = 72; 											// Set the scan window
                        scan_params.timeout = 0; 											// No timeout
    
                        // Initializing connection parameters
                        ble_gap_conn_params_t conn_params;
                        memset(&conn_params, 0, sizeof(conn_params)); 						// Zero Initialization
                        conn_params.min_conn_interval = MIN_CONN_INTERVAL; 					// Minimum Connection Interval (160)
                        conn_params.max_conn_interval = MAX_CONN_INTERVAL; 					// Maximum Connection Interval (320)
                        conn_params.slave_latency = SLAVE_LATENCY; 							// Slave Latency  (0)
                        conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; 					// Connection Supervision Timeout (MSEC_TO_UNITS(4000, UNIT_10_MS)
                        int attempts = 0;
    //                    if (is_scanning)
    //                    {
    //                        err_code2 = sd_ble_gap_scan_stop();
    //                        if (err_code2 != NRF_SUCCESS) 
    //                        {
    //                            is_scanning = true;
    //                        }
    //                        else
    //                        {
    //                            is_scanning = false; 
    //                        }
    //                    }
                        // Start a connection
                        if (!is_connected)
                        {
                            nrf_delay_ms(200);
                            err_code2 = sd_ble_gap_connect(&addr, &scan_params, &conn_params, con_cfg_tag);
                            if(err_code2 == NRF_ERROR_NOT_FOUND)
                            {
                                for(int i = 0 ; i < 5 ; i++)
                                {
                                    nrf_delay_ms(1000);
                                    err_code2 = sd_ble_gap_connect(&addr, &scan_params, &conn_params, con_cfg_tag);
                                    if(err_code2 == 0)
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                        device_name[6] = '\0';
                        if (err_code2 != NRF_SUCCESS) 
                        {
                            is_connected = true;
                        }
                    }
                }
                break;
            }
            default:
                break;
        }
    }

Reply
  • Thank you for your answer.

    By adding UART initialization, the NRF_ERROR_INVALID_STATE problem is resolved.

    However, when I execute err_code2 = sd_ble_gap_connect(&addr, &scan_params, &conn_params, con_cfg_tag);, 0x05 (NRF_ERROR_NOT_FOUND) is returned and I cannot connect.

    What could be the cause?

    void scan_evt_handler(scan_evt_t const * p_scan_evt)
    {
        switch (p_scan_evt->scan_evt_id)
        {
            case BLE_GAP_EVT_ADV_REPORT:
                break;
            case NRF_BLE_SCAN_EVT_SCAN_TIMEOUT:
                NRF_LOG_INFO("Scan timeout.");
                break;
    
            case NRF_BLE_SCAN_EVT_CONNECTING_ERROR:
                NRF_LOG_ERROR("Connection error.");
                break;
    
            case NRF_BLE_SCAN_EVT_CONNECTED:
                NRF_LOG_INFO("Connected to device.");
                break;
    
            case NRF_BLE_SCAN_EVT_FILTER_MATCH:
            {
                // Get Advertising Report
                ble_gap_evt_adv_report_t const * p_adv_report = p_scan_evt->params.filter_match.p_adv_report;
    
                // Get advertising data
                const uint8_t * p_data = p_adv_report->data.p_data; // Get p_data from ble_data_t
                uint16_t data_len = p_adv_report->data.len; 		// Get the data length from ble_data_t
    
                // Get Device Name
                char device_name[BLE_GAP_DEVNAME_MAX_LEN + 1]; 		// A buffer for the device name
                memset(device_name, 0, sizeof(device_name)); 		// Clear the buffer
    
                // Finding device names from advertising data
                uint8_t * p_name_data = ble_advdata_parse((uint8_t *)p_data, data_len, BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME);
                if (p_name_data != NULL)
                {
                    // Get the length of the device name
                    uint8_t name_len = strlen((const char *)p_name_data);
                    strncpy(device_name, (char *)p_name_data, name_len);
                    device_name[name_len] = '\0'; 					// NULL terminated
                    device_name[6] = '\0';
                    // If the device names match, the connection is initiated.
                    if (strcmp(device_name, TARGET_DEVICE_NAME) == 0)
                    {
                        // Set the address of the destination device
                        Name_acquisition_flag = 1;
                        ble_gap_addr_t addr;
                        addr.addr_id_peer = 0; 												// 0 if not a private address
                        addr.addr_type = p_adv_report->peer_addr.addr_type; 				// Set the address type (0x01)
                        memcpy(addr.addr, p_adv_report->peer_addr.addr, BLE_GAP_ADDR_LEN); 	// Copy address
    
                        // Initialize scan parameters
                        ble_gap_scan_params_t scan_params;
                        memset(&scan_params, 0, sizeof(scan_params)); 						// Zero Initialization
                        scan_params.extended = 0; 											// 0 if you do not want to use extended scanning
                        scan_params.active = 1; 											// Enable Active Scanning
                        scan_params.report_incomplete_evts = 0; 							// Do not report incomplete events
                        scan_params.scan_phys = BLE_GAP_PHY_1MBPS; 							// Back PHY and feeling  (0x01)
                        scan_params.interval = 160; 										// Set the scan interval
                        scan_params.window = 72; 											// Set the scan window
                        scan_params.timeout = 0; 											// No timeout
    
                        // Initializing connection parameters
                        ble_gap_conn_params_t conn_params;
                        memset(&conn_params, 0, sizeof(conn_params)); 						// Zero Initialization
                        conn_params.min_conn_interval = MIN_CONN_INTERVAL; 					// Minimum Connection Interval (160)
                        conn_params.max_conn_interval = MAX_CONN_INTERVAL; 					// Maximum Connection Interval (320)
                        conn_params.slave_latency = SLAVE_LATENCY; 							// Slave Latency  (0)
                        conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; 					// Connection Supervision Timeout (MSEC_TO_UNITS(4000, UNIT_10_MS)
                        int attempts = 0;
    //                    if (is_scanning)
    //                    {
    //                        err_code2 = sd_ble_gap_scan_stop();
    //                        if (err_code2 != NRF_SUCCESS) 
    //                        {
    //                            is_scanning = true;
    //                        }
    //                        else
    //                        {
    //                            is_scanning = false; 
    //                        }
    //                    }
                        // Start a connection
                        if (!is_connected)
                        {
                            nrf_delay_ms(200);
                            err_code2 = sd_ble_gap_connect(&addr, &scan_params, &conn_params, con_cfg_tag);
                            if(err_code2 == NRF_ERROR_NOT_FOUND)
                            {
                                for(int i = 0 ; i < 5 ; i++)
                                {
                                    nrf_delay_ms(1000);
                                    err_code2 = sd_ble_gap_connect(&addr, &scan_params, &conn_params, con_cfg_tag);
                                    if(err_code2 == 0)
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                        device_name[6] = '\0';
                        if (err_code2 != NRF_SUCCESS) 
                        {
                            is_connected = true;
                        }
                    }
                }
                break;
            }
            default:
                break;
        }
    }

Children
Related