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

nRF52832 SAADC sampling

Hi,

I have been able to use SAADC to measure temperature, but my code does not behave in the way I expect it to! In the config file I have the following settings set:

#define SAADC_CONFIG_RESOLUTION      NRF_SAADC_RESOLUTION_10BIT
#define SAADC_CONFIG_OVERSAMPLE      NRF_SAADC_OVERSAMPLE_DISABLED
#define SAADC_CONFIG_IRQ_PRIORITY    APP_IRQ_PRIORITY_LOW

here is my code:

#define SAMPLES_IN_BUFFER 5

static nrf_saadc_value_t       m_buffer_pool[2][SAMPLES_IN_BUFFER];
static int temp_rotor;

void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
{
    if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
    {
        int avg_sample = 0;
        float steinhart;
        float sampleAVG;
        int i;
        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);

        for (i = 0; i < SAMPLES_IN_BUFFER; i++)	
        {
              avg_sample += p_event->data.done.p_buffer[i]; // take N samples in a row
        }
        avg_sample /= i; // average all the samples out
        printf("Avg_sample: %d\r\n", avg_sample);
			
        sampleAVG = 810 / avg_sample - 1;		//VDD = 2.85V
        sampleAVG = SERIESRESISTOR / sampleAVG;
        
        steinhart = 0;
        steinhart = sampleAVG / THERMISTORNOMINAL;   // (R/Ro)
        steinhart = log(steinhart);                  // ln(R/Ro)
        steinhart /= BCOEFFICIENT;                   // 1/B * ln(R/Ro)
        steinhart += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To)
        steinhart = 1.0 / steinhart;                 // Invert
        steinhart -= 273.15;                         // convert to C
        temp_rotor = (int)steinhart;             //convert float to int
    }
}

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.gain = NRF_SAADC_GAIN1_6;

    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;
	//Event handler is called immediately after conversion is finished.
	err_code = nrf_drv_saadc_sample(); // Check error
	APP_ERROR_CHECK(err_code);
}

int main(void)
{
	uart_config();
	printf("SAADC Started...\r\n");
	saadc_init();
	while (true)
    {
		saadc_sampling_trigger();
		printf("Room Temperature: %d\r\n", temp_rotor);
		nrf_delay_ms(1000);       //waiting a second
	}

}

When I run the code, I get the following text on Termite terminal(each line is printed every 1 second): Termite

I expected to see something like this instead:

Avg_sample: 409

Room Temperature: 24

Avg_sample: 400

Room Temperature: 25

Avg_sample: 393

Room Temperature: 26

Avg_sample: 377

Room Temperature: 28

What am I doing wrong? why is the Avg_sample(ADC value) updated so slowly?

How can I implement a code in a way that every time I make a call to nrf_drv_saadc_sample() I get 5 samples of ADC value so I could average them and convert the averaged value to temperature?

If I want to use just one buffer for this code, how should I change it?

Related