HI,
I'm developing it using NRF52832.
I'm updating the remaining battery capacity using saadc. However, the battery value is not stable because the value obtained from saadc is not constant.
Can I stabilize the saadc value using oversampling?
Is there anything I missed when setting up the code for oversampling?
I'll attach the code.
<nrfx_saadc.h>
#define NRFX_SAADC_DEFAULT_CHANNEL_CONFIG_SE(PIN_P) \ { \ .resistor_p = NRF_SAADC_RESISTOR_DISABLED, \ .resistor_n = NRF_SAADC_RESISTOR_DISABLED, \ .gain = NRF_SAADC_GAIN1_6, \ .reference = NRF_SAADC_REFERENCE_INTERNAL, \ .acq_time = NRF_SAADC_ACQTIME_10US, \ .mode = NRF_SAADC_MODE_SINGLE_ENDED, \ .burst = NRF_SAADC_BURST_ENABLED, \ .pin_p = NRF_SAADC_INPUT_AIN0, \ .pin_n = NRF_SAADC_INPUT_DISABLED \ }
<sdk_config.h>
// <o> NRFX_SAADC_CONFIG_OVERSAMPLE - Sample period // <0=> Disabled // <1=> 2x // <2=> 4x // <3=> 8x // <4=> 16x // <5=> 32x // <6=> 64x // <7=> 128x // <8=> 256x #ifndef NRFX_SAADC_CONFIG_OVERSAMPLE #define NRFX_SAADC_CONFIG_OVERSAMPLE 8 #endif
<main.c>
void saadc_init(void) { ret_code_t err_code; nrf_saadc_channel_config_t channel_config = //NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_DIFFERENTIAL(NRF_SAADC_INPUT_VDD, NRF_SAADC_INPUT_AIN0); NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN0); 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_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, &timer_cfg, 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, 500); 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); } static void battery_level_percent(void) { if (mvolts >= 3000) { battery_level = 100; } else if (mvolts > 2900) { battery_level = 100 - ((3000 - mvolts) * 58) / 100; } else if (mvolts > 2740) { battery_level = 42 - ((2900 - mvolts) * 24) / 160; } else if (mvolts > 2440) { battery_level = 18 - ((2740 - mvolts) * 12) / 300; } else if (mvolts > 2100) { battery_level = 6 - ((2440 - mvolts) * 6) / 340; } else { battery_level = 0; } } 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; NRF_LOG_INFO("ADC event number: %d", (int)m_adc_evt_counter); avg_mvolts=0; for (i = 0; i < SAMPLES_IN_BUFFER; i++) { /* get adc value */ NRF_LOG_INFO("%d", p_event->data.done.p_buffer[i]); adc_value= p_event->data.done.p_buffer[i]; mmvolts=adc_value*(3.6)/1024; mvolts=mmvolts*1000; m_adc_evt_counter++; } avg_mvolts+=mvolts; /* Update the battery every minute. */ if (m_adc_evt_counter>240) { battery_level=avg_mvolts/m_adc_evt_counter; /* battery level in percent to coin cell */ battery_level_percent(); NRF_LOG_INFO("battery_level: %d", battery_level); /* update battery percent */ battery_level_update(); m_adc_evt_counter=0; } m_adc_evt_counter++; /*Initialize variables.*/ mvolts=0; avg_mvolts=0; } }