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

NRF UART SERVICE long data to send

Hi,

Today, i try to use the UART SERVICE from nordic on both smartphone and NRF51. I succeed to send data between the two. But now, i want to send data longer than 20 bytes.

My idea is to cut the long data in lot of 20 bytes data. I need a response for each packet of 20 bytes to known if the data is good or if i need to ask to send a second time.

I use on my NRF51 dev board : nrf uart ota sample I use on my Smartphone android : nrf uart app android

on my Android app, to receive my data, i use this code :

  //*********************//
    if (action.equals(UartService.ACTION_DATA_AVAILABLE)) {
      
         final byte[] txValue = intent.getByteArrayExtra(UartService.EXTRA_DATA);
         //AJOUTER CODE DE DESENCAPSULATION C1111 ------------------------------------------
         final byte[] tx_unencaps = new byte[500];
         //---------------------------------------------------------------------------------
         runOnUiThread(new Runnable() {
            public void run() {
                try {
                    //AJOUTER CODE DE DESENCAPSULATION C1111 ------------------------------------------
                    ProtocolUartOTA.PP_UART_OTA_unencapsulate(txValue, tx_unencaps);
                    //---------------------------------------------------------------------------------
                    String text = new String(tx_unencaps, "UTF-8");
                    String currentDateTimeString = DateFormat.getTimeInstance().format(new Date());
                    listAdapter.add("["+currentDateTimeString+"] RX: "+text);
                    messageListView.smoothScrollToPosition(listAdapter.getCount() - 1);

                } catch (Exception e) {
                    Log.e(TAG, e.toString());
                }
            }
        });
     }
   //*********************//

i use this code to send :

btnSend.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    	EditText editText = (EditText) findViewById(R.id.sendText);
    	String message = editText.getText().toString();
    	byte[] value;
        byte[] mess_encaps = new byte[500];
        byte[] envoie = new byte[20];
        int i = 0;
        //BleUartHandle BleUartHandleSession = new BleUartHandle();
			try {
				//send data to service
				value = message.getBytes("UTF-8");
            // AJOUTER CODE D'ENCAPSULATION C2222 -----------------------------------------
            ProtocolUartOTA.PP_UART_OTA_encapsulate(value, value.length, mess_encaps);
            while(i < mess_encaps.length) {
                for(int j = 0; j < 20; j++)
                {
                    envoie[j] = mess_encaps[i];
                    i++;
                }
                mService.writeRXCharacteristic(envoie);
            }
            //BleUartHandleSession.SendDataOverUartOta(value, mService);
            //-----------------------------------------------------------------------------
				//mService.writeRXCharacteristic(value);
				//Update the log with time stamp
				String currentDateTimeString = DateFormat.getTimeInstance().format(new Date());
				listAdapter.add("["+currentDateTimeString+"] TX: "+ message);
       	 	messageListView.smoothScrollToPosition(listAdapter.getCount() - 1);
       	 	edtMessage.setText("");
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        
    }
});

on my dev board, to receive and send i use :

static void nus_data_handler(ble_nus_t * p_nus, uint8_t * p_data, uint16_t length)
{
	uint32_t err_code = 0;
	uint8_t length_encaps = 0;

	uint8_t p_data_encaps[500] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
	uint8_t data_unen[500] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
	INFOTRAME InfoTrame;
		    
	InitInfoTrame(&InfoTrame);
	

	while (InfoTrame.NbTrameRecu < InfoTrame.NbTrameTotal)
		PP_UART_OTA_unencapsulate(p_data, data_unen, &InfoTrame);
	for (uint8_t i = 0; i < 1; i++) {}

	length_encaps = PP_UART_OTA_encapsulate(data_unen, 15, p_data_encaps);

	for (uint8_t i = 0; i < 1; i++) {}
    /* for (uint32_t i = 0; i < length; i++)
    {
        while (app_uart_put(p_data[i]) != NRF_SUCCESS);
    }
    while (app_uart_put('\r') != NRF_SUCCESS);
    while (app_uart_put('\n') != NRF_SUCCESS);*/

	err_code = ble_nus_string_send(p_nus, p_data_encaps, length_encaps);
	if (err_code != NRF_ERROR_INVALID_STATE)
	{
		APP_ERROR_CHECK(err_code);
	}

}

Regards,

PS : My question is How to send 2 packets of 20 bytes in android java application with UART service.

  • FormerMember
    0 FormerMember

    It is (currently) not possible to transmit more than 20 bytes of data per package between a nRF51/52 and Android.

    When transferring data using notifications, it is not necessary to get a confirmation in the application layer that the notification was received. BLE is a reliable protocol that doesn't accept packet loss, and all packets are ACK'ed in the link layer. If a packet is not ACK'ed, it is re-transmitted until success or until timeout.

  • I know its impossible to send more than 20 bytes per package. I want to say, my data is longer than 20 bytes. i want to send it to my smartphone but i need more than 1 package.

    Its that i dont succeed to do.

    if i send 5 package for my data : 1 2 3 4 5

    with the BLE protocol, i dont lose package but is the package come in the same order ? 1 2 3 4 5 ?

    or is it possible that a package come before an other ?

  • packets have a guarantee of arrival and a guarantee of arrival in the order they were sent. So if you send 1 2 3 4 5 you will receive 1 2 3 4 5 and if anything goes wrong, the connection will be terminated.

  • If i want to send 40bytes over uart service with my nrf51, i use this function :

    uint32_t ble_nus_string_send ( ble_nus_t * p_nus, uint8_t * p_string, uint16_t length )

    link of function in infocenter : infocenter.nordicsemi.com/index.jsp

    no detail for the length of data ? i can send 500 bytes and this function cut in 20bytes packages my data ?

    I enter in this function and look at hvx_params.p_len : infocenter.nordicsemi.com/index.jsp

    And nothing about max length.

    And about java function to send data. any doc ? infocenter dont anwser me about java doc for ble and nordic uart service.

    I think about this function mService.writeRXCharacteristic(data_in_byte_not_more_than_20_bytes) to send data over ble. if i want to send more than 20 bytes, i thougth it can be that :

                while(i < mess_encaps.length) {
                    for (int j = 0; j < 20; j++) {
                        envoie[j] = mess_encaps[i];
                        i++;
                    }
                    mService.writeRXCharacteristic(envoie);
                }
    

    but didnt work.

  • it's in the header file

    #define BLE_NUS_MAX_DATA_LEN (GATT_MTU_SIZE_DEFAULT - 3) /**< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module
    

    and with this definition

    #define GATT_MTU_SIZE_DEFAULT 23
    

    you can see that 20 bytes is the max you can send with ble_nus_string_send(). If you want to send more you have to send multiple notifications one after another as the previous one finishes.

    There is no max length in the hvx function because it's already in the BTLE spec that notifications and indications have max length MTU-3

    don't know anything about java.

Related