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

nrf52 SAADC, ADV

Hi,

I am trying to use the SAADC via ble when noridc is connecting with other device and adding value to advartasing. This is my code but i've got some problems.

1) SAADC

AFTER EDIT

void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
{
    if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
    {
        ret_code_t err_code;
        uint16_t adc_value;
        uint8_t value[SAADC_SAMPLES_IN_BUFFER*2];
        uint8_t bytes_to_send;
        char data_arr[20];

     
        // set buffers
        err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAADC_SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);

	//VVV i'm not sure what this loop do i use it from example where was enable in saadc_init function analog from A0-A5 i want to use just one 	

        // print samples on hardware UART and parse data for BLE transmission
        printf("ADC event number: %d\r\n",(int)m_adc_evt_counter);
        for (int i = 0; i < SAADC_SAMPLES_IN_BUFFER; i++)
        {
        	printf("%d \r\n", p_event->data.done.p_buffer[i]);
            adc_value = p_event->data.done.p_buffer[i];
            value[i*2] = adc_value;
            value[(i*2)+1] = adc_value >> 8;
        }
				
        // Send data over BLE via NUS service. Makes sure not to send more than 20 bytes.
        if((SAADC_SAMPLES_IN_BUFFER*2) <= 20)
        {
            bytes_to_send = (SAADC_SAMPLES_IN_BUFFER*2);
        }
        else
        {
            bytes_to_send = 20;
        }

        //data_arr=value;

//VVV I don't know how to get hole value not just one "sample" .Saadc is 12bit how to achive it? on phone i get value just to 255 no more i need whole size 2^12 adc VVV

      bytes_to_send = snprintf(data_arr,bytes_to_send ,"%d",(int)value[0]);  

        err_code = ble_nus_string_send(&m_nus, (uint8_t *)data_arr, bytes_to_send);

        if (err_code != NRF_ERROR_INVALID_STATE) 
        {
            APP_ERROR_CHECK(err_code);
        }
						
        m_adc_evt_counter++;
    }
}

void saadc_init(void)
{
    ret_code_t err_code;
	
    nrf_drv_saadc_config_t saadc_config = NRF_DRV_SAADC_DEFAULT_CONFIG;
    saadc_config.resolution = NRF_SAADC_RESOLUTION_12BIT;
	
    nrf_saadc_channel_config_t channel_0_config =
        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN4);
    channel_0_config.gain = NRF_SAADC_GAIN1_4;
    channel_0_config.reference = NRF_SAADC_REFERENCE_VDD4;
	
    err_code = nrf_drv_saadc_init(&saadc_config, saadc_callback);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_channel_init(0, &channel_0_config);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[0],SAADC_SAMPLES_IN_BUFFER);
    APP_ERROR_CHECK(err_code);   
    err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1],SAADC_SAMPLES_IN_BUFFER);
    APP_ERROR_CHECK(err_code);
}

2) Data dynamically changing in adv Later i want to send upper data to function below and changing it every e.g. second how to do it? Any ideas?

static void advertising_init(void)
{
    uint32_t               err_code;
    ble_advdata_t          advdata;
    ble_advdata_t          scanrsp;
    ble_adv_modes_config_t options;

//    int balance[1] = {255};

    // Build advertising data struct to pass into @ref ble_advertising_init.
    memset(&advdata, 0, sizeof(advdata));
    advdata.name_type          = BLE_ADVDATA_FULL_NAME;
    advdata.include_appearance = false;
    advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;

    memset(&scanrsp, 0, sizeof(scanrsp));
    scanrsp.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
    scanrsp.uuids_complete.p_uuids  = m_adv_uuids;

    memset(&options, 0, sizeof(options));
    options.ble_adv_fast_enabled  = true;
    options.ble_adv_fast_interval = APP_ADV_INTERVAL;
    options.ble_adv_fast_timeout  = APP_ADV_TIMEOUT_IN_SECONDS;

//New part

    ble_advdata_manuf_data_t          adv_manuf_data;
    uint8_t                           adv_manuf_data_data[2] = {225,3}; //<---- HERE ADD DATA FROM ADC 

    adv_manuf_data.data.p_data        = adv_manuf_data_data;
    adv_manuf_data.data.size          = sizeof(adv_manuf_data_data);
    adv_manuf_data.company_identifier = 0x0059; //Nordic's company ID
    advdata.p_manuf_specific_data     = &adv_manuf_data;

    //

    err_code = ble_advertising_init(&advdata, &scanrsp, &options, on_adv_evt, NULL);
    APP_ERROR_CHECK(err_code);

    ble_advertising_conn_cfg_tag_set(CONN_CFG_TAG);
}

3) At this moment i can read value only to 255 (and when i connected potentiometer. The value was changing. I can say that adc works but not properly. And the value 225 and 3 show in advertising on phone.

  • The advertising data is just an array of bytes that is passed to the SD. All you need to do write your data into whichever advertising elements you wish to change and re-init advertising. You don't even need to stop advertising, just re-init. So looks something like:

    m_beacon_info [element of your choosing]= SAADC_Sample; 
    advertising_init(advtime);
    

    This is based on SDK11, but I don't think it has changed much. Since the advert elements are 8 bits you will need to play with the bits and use two elements to send a 10 or 12 bit SAADC sample.

  • If you use one of the standard advert formats like iBeacon, alt beacon or eddystone you can put a full 16 bits into the slot for major or minor and the data will show up in most ble scanners by default. Again though on the firmware side the 16 bits is two elements so you have to play with the bits.

Related