This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Using NUS service to communicate between 2 devices

Hi, i know maybe this question was asked before, but i have a particulary issue.

I have 2 devices connected through BLE. Just when them get connected i need to send a byte to identify who is the user of my application.The problem is that, i send this byte but the first time that they get connect is ok, the peripheral receive the byte but the second time, i mean, i turn off the central and turn on again it sends the byte but the peropheral doesn't receive it.

I going to show my code in both device central and peripheral.

CENTRAL...

main.c

int main(void)
{
	  
	  logi("Helloooooooooo");
    ret_code_t err_code;
		
    err_code = NRF_LOG_INIT();
    APP_ERROR_CHECK(err_code);
    leds_init();
		nrf_gpio_cfg_output(24);
	  nrf_gpio_pin_write(24,1);
    
		APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, NULL);
		
    ble_stack_init();
   
	  ble_gap_addr_t addr ={BLE_GAP_ADDR_TYPE_RANDOM_STATIC,{0x18,0x64,0xCF,0xB0,0xA4,0xC0}} ;
    err_code = sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &addr);
    APP_ERROR_CHECK(err_code);
		
    db_discovery_init();
    
	  nus_c_init();

    // Start scanning for peripherals and initiate connection to devices which
    // advertise.
    scan_start();

    // Turn on the LED to signal scanning.
    LEDS_ON(CENTRAL_SCANNING_LED);
	

    for (;;)
    {
        // Wait for BLE events.
        power_manage();
		
		 }			 
	
		
    }

when the central gets connected i send the byte (0x02)

static void on_ble_evt(const ble_evt_t * const p_ble_evt)
{
			uint32_t              erro_code;
	
	
    // For readability.
    const ble_gap_evt_t * const p_gap_evt = &p_ble_evt->evt.gap_evt;

    switch (p_ble_evt->header.evt_id)
    {
      case BLE_GAP_EVT_ADV_REPORT:
        {
					uint32_t err_code;
            const ble_gap_evt_adv_report_t * p_adv_report = &p_gap_evt->params.adv_report;

            

						if (is_uuid_present(&m_nus_uuid, p_adv_report))
												{
					logi("encontre servicio nus en periferico");
									err_code = sd_ble_gap_connect(&p_adv_report->peer_addr,
																								&m_scan_param,
																								&m_connection_param);
											
													LEDS_ON(LEDBUTTON_LED);
									if (err_code == NRF_SUCCESS)
									{
											// scan is automatically stopped by the connect
											err_code = bsp_indication_set(BSP_INDICATE_IDLE);
											APP_ERROR_CHECK(err_code);
//											APPL_LOG("Connecting to target %02x%02x%02x%02x%02x%02x\r\n",
//															 p_adv_report->peer_addr.addr[0],
//															 p_adv_report->peer_addr.addr[1],
//															 p_adv_report->peer_addr.addr[2],
//															 p_adv_report->peer_addr.addr[3],
//															 p_adv_report->peer_addr.addr[4],
//															 p_adv_report->peer_addr.addr[5]
//															 );
														}
												}
            break;  
					}
			
					
					
					
			// Upon connection, check which peripheral has connected (HR or RSC), initiate DB
        // discovery, update LEDs status and resume scanning if necessary. */
        case BLE_GAP_EVT_CONNECTED:
        {
		
					  static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
					  data_array[0] = 0x02;
						static uint8_t index = 19;
					
					  erro_code = ble_nus_c_handles_assign(&m_ble_nus_c, p_gap_evt->conn_handle, NULL);
            APP_ERROR_CHECK(erro_code);
										
						erro_code = ble_db_discovery_start(&m_ble_db_discovery, p_gap_evt->conn_handle);
            APP_ERROR_CHECK(erro_code);
					  logi("me conecte a periferico nus ");
					
					
						erro_code = ble_nus_c_string_send(&m_ble_nus_c, data_array, index);
					  if(erro_code == NRF_SUCCESS){
							nrf_gpio_pin_write(24,0);
					    nrf_delay_ms(100);
			        nrf_gpio_pin_write(24,1);
						}
						
					  logi("mande el dato ");
					 // Update LEDs status, and check if we should be looking for more
            // peripherals to connect to.
            LEDS_ON(CENTRAL_CONNECTED_LED);
            LEDS_OFF(CENTRAL_SCANNING_LED);
						
        } break; // BLE_GAP_EVT_CONNECTED
				
				
				

        // Upon disconnection, reset the connection handle of the peer which disconnected, update
        // the LEDs status and start scanning again.
        case BLE_GAP_EVT_DISCONNECTED:
        {
					  logi("me desconecte de nus periferico");
           
        } break; // BLE_GAP_EVT_DISCONNECTED

				
				
        case BLE_GAP_EVT_TIMEOUT:
            if (p_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_SCAN)
            {
//                APPL_LOG("[APPL]: Scan timed out.\r\n");
                scan_start();
            }
            else if (p_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_CONN)
            {
//                APPL_LOG("[APPL]: Connection Request timed out.\r\n");
            }
            break;// BLE_GAP_EVT_TIMEOUT
						
						
						

        case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
        {
            // Accept parameters requested by peer.
            ret_code_t err_code;
            err_code = sd_ble_gap_conn_param_update(p_gap_evt->conn_handle,
                                        &p_gap_evt->params.conn_param_update_request.conn_params);
            APP_ERROR_CHECK(err_code);
        } break; // BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST
				
				case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
            // Pairing not supported
				
            erro_code = sd_ble_gap_sec_params_reply(p_ble_evt->evt.gap_evt.conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
            APP_ERROR_CHECK(erro_code);
            break;

        default:
            // No implementation needed.
            break;
    }
}

PERIPHERAL

main.c

int main(void)
{
	  uint32_t err_code;
	  bool erase_bonds;
		configurar_puerto();
	
//	 leds_init();
    timers_init();
	  create_timers();
	  
    err_code = bsp_init(BSP_INIT_LED, APP_TIMER_TICKS(100, APP_TIMER_PRESCALER), NULL);
    APP_ERROR_CHECK(err_code);
	  err_code = app_timer_start(m_escuchar_nus_id,APP_TIMER_TICKS(200, APP_TIMER_PRESCALER), NULL);
    APP_ERROR_CHECK(err_code);
	
	    LEDS_ON(puerta_led | acceso_denegado );
			nrf_delay_ms(2000);
		  LEDS_OFF(puerta_led | acceso_denegado);

		ble_stack_init();
	
    device_manager_init(erase_bonds);
	  gap_params_init();
    services_init();
    advertising_init();
	  conn_params_init();
	
	// Empiezo el advertising
	  err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
    APP_ERROR_CHECK(err_code);
//    advertising_start();
	
	// Espero un evento
    for (;;)
    {
        power_manage();
    }
}

the service inits...

static void services_init(void)
{
    uint32_t       err_code;

	  ble_nus_init_t nus_init;
    memset(&nus_init, 0, sizeof(nus_init));
    nus_init.data_handler = nus_data_handler;
    
    err_code = ble_nus_init(&m_nus, &nus_init);
    APP_ERROR_CHECK(err_code);
	
}

and the data received is save on an array data_recibido[]

static void nus_data_handler(ble_nus_t * p_nus, uint8_t * p_data, uint16_t length)
{
	LEDS_ON(puerta_led | acceso_denegado );
			  nrf_delay_ms(100);
		    LEDS_OFF(puerta_led | acceso_denegado);
			  nrf_delay_ms(100);
	
    for (uint32_t i = 0; i < length; i++)
    {
        data_recibida[i]= p_data[i];
		    LEDS_ON(puerta_led | acceso_denegado );
			  nrf_delay_ms(100);
		    LEDS_OFF(puerta_led | acceso_denegado);
			  nrf_delay_ms(100);
			
    }
			if(data_recibida[0] == 0x02){
				LEDS_ON(puerta_led | acceso_denegado );
		
//		memset(&data_recibida, 0, sizeof(data_recibida));
			
		}
  • Why are you calling ble_nus_c_handles_assign() with NULL as the last argument? And why are you calling it before ble_db_discovery_start()? Shouldn't you actually discover the services and wait for the BLE_NUS_C_EVT_DISCOVERY_COMPLETE event before you call ble_nus_c_handles_assign() with the actual attribute handles of the relevant characteristics and descriptors? So, ble_nus_c_string_send() return sNRF_SUCCESS but the nus_data_handler() is not called, do you receive a BLE_GATTS_EVT_WRITE event?

  • Thank you very much PETTER MYHRE, you have solved my problem.. the problem was that when that i assign a NULL attribute handle. i going to copy the modified code to show you what i did. THANK YOU.

    Connected event:

        case BLE_GAP_EVT_CONNECTED:
                {
        		
        					  
        					
        //					  erro_code = ble_nus_c_handles_assign(&m_ble_nus_c, p_gap_evt->conn_handle, NULL);
        //            APP_ERROR_CHECK(erro_code);
        										
        						erro_code = ble_db_discovery_start(&m_ble_db_discovery, p_gap_evt->conn_handle);
                    APP_ERROR_CHECK(erro_code);
        					  logi("me conecte a periferico nus ");
        					if(erro_code != NRF_SUCCESS){
        							nrf_gpio_pin_write(24,0);
        					    nrf_delay_ms(1000);
        			        nrf_gpio_pin_write(24,1);
        						}
        					 
        						
        					  logi("mande el dato ");
        					 // Update LEDs status, and check if we should be looking for more
                   // peripherals to connect to.
                    LEDS_ON(CENTRAL_CONNECTED_LED);
                    LEDS_OFF(CENTRAL_SCANNING_LED);
        						
                } break; // BLE_GAP_EVT_CONNECTED
    
    
    /**@snippet [Handling events from the ble_nus_c module] */ 
    static void ble_nus_c_evt_handler(ble_nus_c_t * p_ble_nus_c, const ble_nus_c_evt_t * p_ble_nus_evt)
    {
    		static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
    		data_array[0] = 0x02;
    		static uint8_t index = 19;
        uint32_t err_code;
        switch (p_ble_nus_evt->evt_type)
        {
            case 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->handles);
                APP_ERROR_CHECK(err_code);
    
                err_code = ble_nus_c_rx_notif_enable(p_ble_nus_c);
                APP_ERROR_CHECK(err_code);
    //            APPL_LOG("The device has the Nordic UART Service\r\n");
    				 
    						err_code = ble_nus_c_string_send(&m_ble_nus_c, data_array, index);
    					  if(err_code == NRF_SUCCESS){
    							nrf_gpio_pin_write(24,0);
    					    nrf_delay_ms(100);
    			        nrf_gpio_pin_write(24,1);
    						}
                break;
        
    		
    

    Handling events from the ble_nus_c module:

    static void ble_nus_c_evt_handler(ble_nus_c_t * p_ble_nus_c, const ble_nus_c_evt_t * p_ble_nus_evt)
    {
    		static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
    		data_array[0] = 0x02;
    		static uint8_t index = 19;
        uint32_t err_code;
        switch (p_ble_nus_evt->evt_type)
        {
            case 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->handles);
                APP_ERROR_CHECK(err_code);
    
                err_code = ble_nus_c_rx_notif_enable(p_ble_nus_c);
                APP_ERROR_CHECK(err_code);
    //            APPL_LOG("The device has the Nordic UART Service\r\n");
    				 
    						err_code = ble_nus_c_string_send(&m_ble_nus_c, data_array, index);
    					  if(err_code == NRF_SUCCESS){
    							nrf_gpio_pin_write(24,0);
    					    nrf_delay_ms(100);
    			        nrf_gpio_pin_write(24,1);
    						}
                break;
            
    				
    				
            case BLE_NUS_C_EVT_NUS_RX_EVT:
                for (uint32_t i = 0; i < p_ble_nus_evt->data_len; i++)
                {
                    while(app_uart_put( p_ble_nus_evt->p_data[i]) != NRF_SUCCESS);
                }
                break;
            
            case BLE_NUS_C_EVT_DISCONNECTED:
    //            APPL_LOG("Disconnected\r\n");
                scan_start();
                break;
        }
    }
    
  • Antonio, if you have multiple unrelated questions, please ask them separately. Please consider taking our tour.

Related