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

SAADC Scan Mode

I want to use three ADC-inputs on my nRF51832 Engineering Sample B. I read that it is possible to define several ADC-Channels and if a ADC Sample is triggered all Channels are sampeld. That would be great, but how it is possible to find out which measured value is from which channel or input? Here is my code:

    void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
{
	if (p_event->type ==   NRF_DRV_SAADC_EVT_DONE)//NRF_DRV_SAADC_EVT_LIMIT )
	    {


			ret_code_t err_code;

	        err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);//2 Sample pro Messung
	        APP_ERROR_CHECK(err_code);
	        //error_to_uart("call",err_code);
	        uint16_t voltage;

	       // if(p_event->data.limit.channel ==0)//if (m_adc_evt_counter == 0)
	        {
				voltage = 3.6 * p_event->data.done.p_buffer[0] / 0xFFF *1000;		//Value1
				*(uint16_t*) &status_send[1] =  voltage;
				if(m_conn_handle != BLE_CONN_HANDLE_INVALID)
	    		while(rx_set (&m_nus, status_send, 5)!= NRF_SUCCESS);
	        }
	       // if(p_event->data.limit.channel ==1)//else if (m_adc_evt_counter == 1)
	        {
	        	voltage = 2.5* p_event->data.done.p_buffer[1] / 0xFFF *1000;		//Value 2
	        	LOAD = voltage;
	        }
	        //if(p_event->data.limit.channel ==2)//else if (m_adc_evt_counter == 2)
	        {
	        	voltage = 3.6* p_event->data.done.p_buffer[2] / 0xFFF *1000;		//Value 3
	        	//do something with Value 3
	        }

	        m_adc_evt_counter++;	//Anzahl der adc-events
	        if (m_adc_evt_counter == 3)
	        	m_adc_evt_counter = 0;
	    }
}
void saadc_init(void)
{
    ret_code_t err_code;
    //###########################################VDD
    nrf_saadc_channel_config_t channel_0_config;
    	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_10US;
		channel_0_config.mode       = NRF_SAADC_MODE_SINGLE_ENDED;
		channel_0_config.pin_p      = NRF_SAADC_INPUT_VDD;
		channel_0_config.pin_n      = NRF_SAADC_INPUT_DISABLED;

	//#############################################AIN1 -> DruckSensor
	nrf_saadc_channel_config_t channel_1_config;
	    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_10US;
		channel_1_config.mode       = NRF_SAADC_MODE_SINGLE_ENDED;
		channel_1_config.pin_p      = NRF_SAADC_INPUT_AIN1;
		channel_1_config.pin_n      = NRF_SAADC_INPUT_DISABLED;

	//#############################################AIN2 -> Rolle
	nrf_saadc_channel_config_t channel_2_config;
		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_10US;
		channel_2_config.mode       = NRF_SAADC_MODE_SINGLE_ENDED;
		channel_2_config.pin_p      = 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);
    //error_to_uart("init",err_code);

    err_code = nrf_drv_saadc_channel_init(0, &channel_0_config);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_saadc_channel_init(1, &channel_1_config);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_saadc_channel_init(2, &channel_2_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);
    //error_to_uart("buff",err_code);
    err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1],SAMPLES_IN_BUFFER);
    APP_ERROR_CHECK(err_code);
    //error_to_uart("buff2",err_code);

    //nrf_saadc_channel_limits_set(0,0,0);
    //nrf_saadc_channel_limits_set(1,0,0);
    //nrf_saadc_channel_limits_set(2,0,0);
}
void timer_handler(nrf_timer_event_t event_type, void* p_context)
{
	//Timer Event des ADC Timers
}
void saadc_sampling_event_init(void)
{
    ret_code_t err_code;
    err_code = nrf_drv_ppi_init();
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_timer_init(&m_timer, NULL, timer_handler);
    APP_ERROR_CHECK(err_code);

    /* setup m_timer for compare event every 400ms */
    uint32_t ticks = nrf_drv_timer_ms_to_ticks(&m_timer, 400);
    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_event_addr = nrf_drv_saadc_task_address_get(NRF_SAADC_TASK_SAMPLE);

    /* 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_event_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);
}
Parents
  • The values should come in the channel order (initiated with nrf_drv_saadc_channel_init(uint8_t channel, ...)). If SAMPLES_IN_BUFFER is 6 you will get: ch0, ch1, ch2, ch0, ch1, ch2.

    SDK 11.0.0-2.alpha has a bug that seems to be present if the array size is equal to the number of channels or a multiple of the size. The reason for this bug is that the engineering A chip (PCA10036) did not have the scan mode in hardware, so the scanning was done manually.

    The bug is fixed (I just tested it) in the next version of the SDK which should be out very soon. For now you can set SAMPLES_IN_BUFFER to be larger than the number of channels.

  • I just tested with 4 channels and it works like it should. Can you send me the code you are using (in a c file, not in the comment)?

Reply Children
No Data
Related