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

Transmit number via ble

Hello! I have uint32_t adc_value (from external ADC converter) And try to send it value through ble. My code:

main.c: ....

 for (;;)
    {
	Weighing();
        power_manage();    			 
			if(adc_value)    				
			{
				SEGGER_RTT_printf(0, "%d\n", adc_value);
				ble_adc_send(&m_nus, &adc_value);
			}
			nrf_delay_ms(100);
    }

here's send value function from ble_nus.c:

uint32_t ble_adc_send(ble_nus_t * p_nus, uint32_t *adc_value)
{
    ble_gatts_hvx_params_t hvx_params;

    VERIFY_PARAM_NOT_NULL(p_nus);

    if ((p_nus->conn_handle == BLE_CONN_HANDLE_INVALID) || (!p_nus->is_notification_enabled))
    {
        return NRF_ERROR_INVALID_STATE;
    }
		uint16_t length = 10;
    if (length > BLE_NUS_MAX_DATA_LEN)
    {
        return NRF_ERROR_INVALID_PARAM;
    }
		
    memset(&hvx_params, 0, sizeof(hvx_params));

    hvx_params.handle = p_nus->rx_handles.value_handle;
    hvx_params.p_data = (uint8_t*) adc_value;
    hvx_params.p_len  = &length;
    hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;

    return sd_ble_gatts_hvx(p_nus->conn_handle, &hvx_params);
}
  1. Segger RTT terminal shows correct values but in mobile phone I getting garbage data. Notification works properly by the way.

  2. What is the easiest way to convert int to string. Before working with 8-bit MC I used ultoa/utoa function from the lib with avg gcc compiler, here it's not working. But vice versa converting string to int (itoa) works good

Thanks

  • uint32_t ble_adc_send(ble_nus_t * p_nus, uint32_t *adc_value) { ble_gatts_hvx_params_t hvx_params;

        VERIFY_PARAM_NOT_NULL(p_nus);
    
        if ((p_nus->conn_handle == BLE_CONN_HANDLE_INVALID) || (!p_nus->is_notification_enabled))
        {
            return NRF_ERROR_INVALID_STATE;
        }
    		uint8_t buffer[4];
    		uint16_t length = uint32_encode(*adc_value, buffer);
        if (length > BLE_NUS_MAX_DATA_LEN)
        {
            return NRF_ERROR_INVALID_PARAM;
        }
    		
        memset(&hvx_params, 0, sizeof(hvx_params));
    
        hvx_params.handle = p_nus->rx_handles.value_handle;
        hvx_params.p_data = buffer;
        hvx_params.p_len  = &length;
        hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
    
        return sd_ble_gatts_hvx(p_nus->conn_handle, &hvx_params);
    }
    

    just the same result.

  • My receiver site is just read string characteristic from nus service. (Actually I think it's the same as NRF connect app, Because in both of them the result is the same)

  • Ok, for example, i use the following code for received characteristiic data in an android app (written in c++ using Qt):

    typedef union ui32u_i {
        uint32_t Value;     
        uint8_t  Byte[4];	
    } UI32U;
    
    //
    // in the slot for "characteristic data chaged" 
    //
    
    void MainWindow::on_characteristicChanged(QLowEnergyCharacteristic ch, QByteArray data) // data is the array with the charaterisic data
    {
    UI32U u32;
    
      if(ch.uuid().toUInt32() == ADC_CHRACTERISTIC){
          u32.Value = 0;
          for(int i = 0; i < sizeof(uint32_t); i++) // or use memcpy()
              u32.Byte[i] = data[i];
    
            ADC_Value = u32.Value; // assign the ADC value here, the "ADC_Value" is global or part of "MainWindow" in this case 
                                                // the ADC value is now correct assigned and you can call utoa(), sprintf() or any other conversion fuction
                                                // or send the new value using a Qt event (next line)
            emit new_adc_value(u32.Value);
        }
    }
    
    
       ...
    
    //
    // print the value on an GUI element (QLabel in this case)
    //
    void MainWindow::On_new_adc_value(uint32_t value)
    {
      ui->label->setText(QString().sprintf("%d", value));
    }
    
  • Thanks for your example. Indeed I've only started to learn android programming (on Java by the way). Now I just make a simple app in probable the highest level way of android programming - ble-test.appinventor.mit.edu . In that app I can get string value via ble and it work good with get/send string value (the same like in nrf connect app) Here's my code :) ybex.com/.../w1vcqz9gpumalqb10hqxroupa32vuhtmtew89hfv.html

  • Ok, than you can try to send the value as ASCII string.

    char buffer[10];
    
    sprintf(buffer, "%d", *adc_value);
    
    uint16_t length = strlen(buffer);
    
     hvx_params.p_data = (uint8_t *) buffer;
     hvx_params.p_len  = &length;
      
    ...
    

    Now your app can receive the value as ASCII string.

Related