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

SAADC - NRF_DRV_SAADC_EVT_DONE

Hello,

I'm currently working with sdk 11 on nRF52832.

I'm trying to acquire 20 value from SAADC every 10ms during 300uS.

I think that the rate is too high because p_event->type == NRF_DRV_SAADC_EVT_DONE occur only once per 20 value.

Is it normal ? Is it too fast ?

Thank you, Nabil

  • Hi Nabil,

    Whether or not this is normal depends on how you have configured your buffer(s). You will only get a NRF_DRV_SAADC_EVT_DONE event when a buffer is filled, so if your buffer size is 20 samples, this behavior is normal.

    To say something about what sample rate you can achieve, you will have to provide some more details about your application and SAADC setting. The SAADC peripheral can support up to 200 ksps, so your 20 values every 10 ms should be achievable (I'm not sure I understand what you mean by "during 300uS"). What aquisition time do you use? Do you use BLE in your application? Do you do any processing on the samples? The SAADC support EasyDMA and double buffering, meaning it can sample directly to RAM and you can process one buffer while sampling to a separate buffer.

    Best regards,

    Jørgen

  • Hello,

    Thank you. I'm working like that :

    #define SAMPLES_IN_BUFFER 1
    #define SAMPLE 20
    
    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;
         
            err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);
            APP_ERROR_CHECK(err_code);
            int i;
            for (i = 0; i < SAMPLES_IN_BUFFER; i++)
                {
                  adc_measure = adc_measure + p_event->data.done.p_buffer[i];
                  nrf_drv_gpiote_out_toggle(27);
    
                }
    
        }
    }
    
    void saadc_init(void)
    {
        ret_code_t err_code;
        nrf_saadc_channel_config_t channel_config =
        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN0);
        channel_config.reference = NRF_SAADC_REFERENCE_VDD4;
        channel_config.gain = NRF_SAADC_GAIN1_6;                          
        channel_config.reference = NRF_SAADC_REFERENCE_INTERNAL;     
    
        err_code = nrf_drv_saadc_init(NULL, saadc_callback);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_channel_init(0, &channel_config);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[0],SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);
        
        err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1],SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);
    
    }
    
    void saadc_sampling_trigger(void)
    {
        ret_code_t err_code;
        err_code = nrf_drv_saadc_sample();
        APP_ERROR_CHECK(err_code);
    }
    
    void FONCTION_FOR_ACQ(void)
       {
    
        for (cpt = 0; cpt < SAMPLE; cpt++)
            {
              saadc_sampling_trigger();
              nrf_delay_us(5);
            }
      cpt = 0;
    
       }
    

    This part work on a BLE environnement. Every 10ms I want to start 20 acquisition. One every 17us.

    The fonction FONCTION_FOR_ACQ is called by an interrupt from LCOMP (each cross event from 50hz sinus)

  • Is the call to nrf_drv_saadc_sample returning NRF_SUCCESS? Do you need to use a 1-sample buffer, or could you try to increase SAMPLES_IN_BUFFER to 20? This will reduce overhead related to generating 20 events, processing 20 single samples, and calling buffer_convert 20 times. You should also move the call to nrf_drv_saadc_buffer_convertuntil after you have processed the buffer, to avoid the samples to be overwritten by new samples.

  • Like that ?

     if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
        {
            ret_code_t err_code;
         
         
    
            int i;
    
            //printf("ADC event number: %d\r\n",(int)m_adc_evt_counter);
            for (i = 0; i < SAMPLES_IN_BUFFER; i++)
                {
                   // printf("%d\r\n", p_event->data.done.p_buffer[i]);
                  adc_measure = adc_measure + p_event->data.done.p_buffer[i];
                  nrf_drv_gpiote_out_toggle(27);
    
                }
            m_adc_evt_counter++;
       err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);
            APP_ERROR_CHECK(err_code);
            if(m_adc_evt_counter==3)
                {
                    nrf_gpio_pin_toggle(LED_3);
                }
        }
    
  • ADC only work with Sample_In_BUFFER = 1 in my case. I don't know why

Related