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

SAADC implementation for three pins to get data at the same time.

Hello,

I am working with nRF52DK, I am trying to implement grouped SAADC for three sensors,

I want to receive all three ADC outputs at the same time on development kit,

I have tried with individual implementation and it's working fine but not getting outputs on ADC channels at the same time.

so I am confused how to implement this to get data on adc channels at the same time.

Thanks and regards,

Jaydip

Parents
  • Hello Jaydip,

    Just to make sure I understand you correctly, you would like to receive SAADC measurements from three pins every time you conduct a sampling - is this correct? 
    In this case, you could need to use the SAADC in scan mode - to do this you would have to configure 3 SAADC channels in your saadc init.
    For example, if you take a look at the SAADC peripheral example you will need to duplicate the channel configuration and initialization, to sample more channels at once.

    Could you tell me how often you intend for them to be sampled - will it be a periodic sampling, or one based on an interrupt, or a manual call to the sampling function somewhere in your code?

    I have tried with individual implementation and it's working fine but not getting outputs on ADC channels at the same time.

    Please elaborate on what you mean when you say that it is working fine, but you are not receiving any ADC samples.

    Best regards,
    Karl

  • Hello Karl,

    Thanks for your reply, you understood correctly, I want to receive SAADC measurements from three pins every time I conduct a sampling.

    I have already implemented three channel configurations and initialization based on peripheral example and some references.

    I am attaching my implementation of SAADC here.

    #define SAMPLES_IN_BUFFER 5
    volatile uint8_t state = 1;
    
    static const nrf_drv_timer_t m_timer = NRF_DRV_TIMER_INSTANCE(0);
    static nrf_saadc_value_t     m_buffer_pool[2][SAMPLES_IN_BUFFER];
    static nrf_ppi_channel_t     m_ppi_channel;
    static uint32_t              m_adc_evt_counter;
    
    static uint8_t                     m_adc_channel_enabled; 
    static nrf_saadc_channel_config_t  channel_0_config;
    static nrf_saadc_channel_config_t  channel_1_config;
    static nrf_saadc_channel_config_t  channel_2_config;
    
    void timer_handler(nrf_timer_event_t event_type, void * p_context)
    {
    
    }
    
    
    void saadc_sampling_event_init(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_drv_ppi_init();
        APP_ERROR_CHECK(err_code);
    
    //    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
    //    timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
        err_code = nrf_drv_timer_init(&m_timer, NULL, timer_handler);
        APP_ERROR_CHECK(err_code);
    
        /* setup m_timer for compare event every 40ms */
        uint32_t ticks = nrf_drv_timer_ms_to_ticks(&m_timer, 40);
        nrf_drv_timer_extended_compare(&m_timer,
                                       NRF_TIMER_CC_CHANNEL0,
                                       ticks,
                                       NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
                                       false);
        nrf_drv_timer_enable(&m_timer);
    
        uint32_t timer_compare_event_addr = nrf_drv_timer_compare_event_address_get(&m_timer,
                                                                                    NRF_TIMER_CC_CHANNEL0);
        uint32_t saadc_sample_task_addr   = nrf_drv_saadc_sample_task_get();
    
        /* setup ppi channel so that timer compare event is triggering sample task in SAADC */
        err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_ppi_channel_assign(m_ppi_channel,
                                              timer_compare_event_addr,
                                              saadc_sample_task_addr);
        APP_ERROR_CHECK(err_code);
    }
    
    
    void saadc_sampling_event_enable(void)
    {
        ret_code_t err_code = nrf_drv_ppi_channel_enable(m_ppi_channel);
    
        APP_ERROR_CHECK(err_code);
    }
    
    
    void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
    {
        if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
        {
            static ret_code_t err_code;
    			
            if(m_adc_channel_enabled == 0)
    	{
              err_code = nrf_drv_saadc_channel_uninit(0);
              APP_ERROR_CHECK(err_code);
              err_code = nrf_drv_saadc_channel_init(1, &channel_1_config);
              APP_ERROR_CHECK(err_code);
              m_adc_channel_enabled = 1;
    	}
    	else if(m_adc_channel_enabled == 1)
    	{
              err_code = nrf_drv_saadc_channel_uninit(1);
              APP_ERROR_CHECK(err_code);
              err_code = nrf_drv_saadc_channel_init(2, &channel_2_config);
              APP_ERROR_CHECK(err_code);
              m_adc_channel_enabled = 2;
    	}
    	else if(m_adc_channel_enabled == 2)
    	{
              err_code = nrf_drv_saadc_channel_uninit(2);
              APP_ERROR_CHECK(err_code);
              err_code = nrf_drv_saadc_channel_init(0, &channel_0_config);
              APP_ERROR_CHECK(err_code);
              m_adc_channel_enabled = 0;
    	}
         
            err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);
            APP_ERROR_CHECK(err_code);
    
            int i;
            NRF_LOG_INFO("ADC event number: %d ",(int)m_adc_evt_counter);
    	NRF_LOG_INFO("Channel %d value: %d\r\n", m_adc_channel_enabled, p_event->data.done.p_buffer[i]);
            m_adc_evt_counter++;
        }
    }
    
    
    void saadc_init(void)
    {
        ret_code_t err_code;
    		//set configuration for saadc channel 0
    		channel_0_config.resistor_p = NRF_SAADC_RESISTOR_DISABLED;
        channel_0_config.resistor_n = NRF_SAADC_RESISTOR_DISABLED;
        channel_0_config.gain       = NRF_SAADC_GAIN1_6;
        channel_0_config.reference  = NRF_SAADC_REFERENCE_INTERNAL;
        channel_0_config.acq_time   = NRF_SAADC_ACQTIME_20US;
        channel_0_config.mode       = NRF_SAADC_MODE_SINGLE_ENDED;
        channel_0_config.pin_p      = (nrf_saadc_input_t)(NRF_SAADC_INPUT_AIN0);
        channel_0_config.pin_n      = NRF_SAADC_INPUT_DISABLED;
    		
    		//set configuration for saadc channel 1
    		channel_1_config.resistor_p = NRF_SAADC_RESISTOR_DISABLED;
        channel_1_config.resistor_n = NRF_SAADC_RESISTOR_DISABLED;
        channel_1_config.gain       = NRF_SAADC_GAIN1_6;
        channel_1_config.reference  = NRF_SAADC_REFERENCE_INTERNAL;
        channel_1_config.acq_time   = NRF_SAADC_ACQTIME_20US;
        channel_1_config.mode       = NRF_SAADC_MODE_SINGLE_ENDED;
        channel_1_config.pin_p      = (nrf_saadc_input_t)(NRF_SAADC_INPUT_AIN1);
        channel_1_config.pin_n      = NRF_SAADC_INPUT_DISABLED;
    
    		//set configuration for saadc channel 2
    		channel_2_config.resistor_p = NRF_SAADC_RESISTOR_DISABLED;
        channel_2_config.resistor_n = NRF_SAADC_RESISTOR_DISABLED;
        channel_2_config.gain       = NRF_SAADC_GAIN1_6;
        channel_2_config.reference  = NRF_SAADC_REFERENCE_INTERNAL;
        channel_2_config.acq_time   = NRF_SAADC_ACQTIME_20US;
        channel_2_config.mode       = NRF_SAADC_MODE_SINGLE_ENDED;
        channel_2_config.pin_p      = (nrf_saadc_input_t)(NRF_SAADC_INPUT_AIN2);
        channel_2_config.pin_n      = NRF_SAADC_INPUT_DISABLED;
    
        err_code = nrf_drv_saadc_init(NULL, saadc_callback);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_channel_init(0, &channel_0_config);
        APP_ERROR_CHECK(err_code);
        m_adc_channel_enabled = 0;
    
        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);
    
    }
    
    
    /**
     * @brief Function for main application entry.
     */
    int main(void)
    {
        uint32_t err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
        ret_code_t ret_code = nrf_pwr_mgmt_init();
        APP_ERROR_CHECK(ret_code);
    
        saadc_init();
        saadc_sampling_event_init();
        saadc_sampling_event_enable();
        NRF_LOG_INFO("SAADC HAL simple example started.");
    
        while (1)
        {
            nrf_pwr_mgmt_run();
            NRF_LOG_FLUSH();
        }
    }
    

    I would like them to be sampled by using manual call, currently it's being sampled periodically with 40ms period.

    so here every time one channel is being sampled other uninitialized.

    please suggest what's wrong with this implementations to receive SAADC measurements from three pins every time I conduct a sampling.

    Thanks and regards,

    Jaydip

  • Hello Jaydip,

    Jaydipsinh440 said:
    Thanks for your reply

     No problem at all, I am happy to help!

    Jaydipsinh440 said:
    so here every time one channel is being sampled other uninitialized.
    Jaydipsinh440 said:
    please suggest what's wrong with this implementations to receive SAADC measurements from three pins every time I conduct a sampling.

    Why do you unit the channels?
    If I understood you correctly in your previous post, then this is not what you would like to do. Instead, you should during your saadc_init do nrf_drv_saadc_channel_init three times - one for each channel.
    Since only one channel is initialized at the time, there will only be samples available for that one channel each time it is sampled. 

    Jaydipsinh440 said:
    I would like them to be sampled by using manual call

    Then you will need to call the nrfx_saadc_sample function somewhere in your code.
    Bear in mind that sampling by function call will require CPU intervention at each sampling.

    Best regards,
    Karl

  • Hello Karl,

    Thanks for your reply,

    I have changed the code that you've suggested, It was my mistake I have used wrong reference, This is working for me.

    Again thanks for your time.

    regards,

    Jaydip

Reply Children
Related