Hi,
I'm trying to read the battery voltage of a custom board from the VDDHDIV5 channel. I'm using FreeRTOS in my project. I would like to read trigger the ADC to read 5 samples(non-blocking) once every hour. I tried the below pseudo code to trigger the read but I noticed that only one reading is present in the buffer.
nrf_saadc_value_t raw_value[5] = {0}; void saadc_handler(nrf_drv_saadc_evt_t const * p_event) { if(p_event->type == NRF_DRV_SAADC_EVT_DONE) { raw_val = *(p_event->data.done.p_buffer); test = (raw_val*10/1024); //Notify saadc_thread } } void saadc_init() { uint32_t err_code; //SAADC peripheral configuration nrf_drv_saadc_config_t m_saadc_config = { .interrupt_priority = APP_IRQ_PRIORITY_LOW, .low_power_mode = false, .oversample = NRF_SAADC_OVERSAMPLE_DISABLED, .resolution = NRF_SAADC_RESOLUTION_10BIT }; // Channel configuration //Internal reference is 0.6V nrf_saadc_channel_config_t m_channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_VDDHDIV5); m_channel_config.acq_time = NRF_SAADC_ACQTIME_10US; m_channel_config.gain = NRF_SAADC_GAIN1_6; err_code = nrf_drv_saadc_init(&m_saadc_config, saadc_handler); APP_ERROR_CHECK(err_code); err_code = nrf_drv_saadc_channel_init(0, &m_channel_config); APP_ERROR_CHECK(err_code); } void saadc_sample() { nrf_drv_saadc_buffer_convert(raw_value, 5); for(uint8_t i=0; i<5; ++i) nrf_drv_saadc_sample(); } static void saadc_thread(void * arg) { // Call saadc_sample and wait for a notification. And then delay for 1 hour }
I tried two more things and noticed different output
- The SAADC example in the SDK. The code was running fine and the ADC values were correct.
- Call saadc_sample in the SAADC handler on NRF_DRV_SAADC_EVT_DONE. The ADC values were correct but this is not a desirable situation as I don't need the SAADC to constantly sample
- Change the size of raw_value to 1. The ADC value was wrong. I tried this with and without oversampling.
MCU - nRF52833-QDAAA0
SDK - nRF5 SDK 17.1.0
With FreeRTOS