Hi,
I am new to the SAADC concept in nrf52. I have to measure the battery voltage using SAADC over ANI0 pin. I using battery with voltage 4.1 volt.
This voltage is divided using voltage divider with two resistances of 10 kohm and 3.5 kohm . I am applying 1 volt to the ANI0 pin through this network.
SAADC configuration is the default one with single ended. reference = 0.6volt gain = 1/6
So as per the formula given in datasheet,under this condition I should get ADC output as
((1*(1/6))*256)/0.6=71.11
but i am getting 4 or 5 or 6 as output on UART. following is the code,
/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
*/
/** @file
* @defgroup nrf_adc_example main.c
* @{
* @ingroup nrf_adc_example
* @brief ADC Example Application main file.
*
* This file contains the source code for a sample application using ADC.
*
* @image html example_board_setup_a.jpg "Use board setup A for this example."
*/
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "nrf.h"
#include "nrf_drv_saadc.h"
#include "boards.h"
#include "app_uart.h"
#include "app_error.h"
#include "app_util_platform.h"
#include "nrf_drv_clock.h"
#include "nrf_drv_rtc.h"
#include "nrf_delay.h"
#define UART_TX_BUF_SIZE 256 /**< UART TX buffer size. */
#define UART_RX_BUF_SIZE 1 /**< UART RX buffer size. */
#define SAMPLES_IN_BUFFER 1 //Number of SAADC samples in RAM before returning a SAADC event. Do not change this constant for low power SAADC
#define UART_PRINTING_ENABLED //Enable to see SAADC output on UART. Comment out for low power operation.
void saadc_init(void);
volatile uint8_t state = 1;
const nrf_drv_rtc_t rtc = NRF_DRV_RTC_INSTANCE(0); /**< Declaring an instance of nrf_drv_rtc for RTC0. */
static nrf_saadc_value_t m_buffer_pool[2][SAMPLES_IN_BUFFER];
//static uint32_t m_adc_evt_counter;
/**
* @brief UART events handler.
*/
void uart_events_handler(app_uart_evt_t * p_event)
{
}
/**
* @brief UART initialization.
*/
void uart_config(void)
{
uint32_t err_code;
const app_uart_comm_params_t comm_params =
{
RX_PIN_NUMBER,
TX_PIN_NUMBER,
RTS_PIN_NUMBER,
CTS_PIN_NUMBER,
APP_UART_FLOW_CONTROL_DISABLED,
false,
UART_BAUDRATE_BAUDRATE_Baud115200
};
APP_UART_FIFO_INIT(&comm_params,
UART_RX_BUF_SIZE,
UART_TX_BUF_SIZE,
uart_events_handler,
APP_IRQ_PRIORITY_LOW,
err_code);
APP_ERROR_CHECK(err_code);
}
static void rtc_handler(nrf_drv_rtc_int_type_t int_type)
{
uint32_t err_code;
if (int_type == NRF_DRV_RTC_INT_COMPARE0)
{
saadc_init();
nrf_drv_saadc_sample();
LEDS_INVERT(BSP_LED_0_MASK); //Toggle LED1 to indicate SAADC sampling start
err_code = nrf_drv_rtc_cc_set(&rtc,0,2000,true);
APP_ERROR_CHECK(err_code);
nrf_drv_rtc_counter_clear(&rtc);
}
}
static void lfclk_config(void)
{
ret_code_t err_code = nrf_drv_clock_init();
APP_ERROR_CHECK(err_code);
nrf_drv_clock_lfclk_request(NULL);
}
static void rtc_config(void)
{
uint32_t err_code;
//Initialize RTC instance
err_code = nrf_drv_rtc_init(&rtc, NULL, rtc_handler);
APP_ERROR_CHECK(err_code);
//Set compare channel to trigger interrupt after COMPARE_COUNTERTIME seconds
err_code = nrf_drv_rtc_cc_set(&rtc,0,2000,true);
APP_ERROR_CHECK(err_code);
//Power on RTC instance
nrf_drv_rtc_enable(&rtc);
}
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;
LEDS_INVERT(BSP_LED_1_MASK); //Toggle LED2 to indicate SAADC sampling start
err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);
APP_ERROR_CHECK(err_code);
#ifdef UART_PRINTING_ENABLED
//printf("ADC event number: %d\r\n",(int)m_adc_evt_counter);
for (int i = 0; i < SAMPLES_IN_BUFFER; i++)
{
printf("%x\r\n", p_event->data.done.p_buffer[i]);
}
//m_adc_evt_counter++;
#endif //UART_PRINTING_ENABLED
nrf_drv_saadc_uninit();
NRF_SAADC->INTENCLR = (SAADC_INTENCLR_END_Clear << SAADC_INTENCLR_END_Pos);
NVIC_ClearPendingIRQ(SAADC_IRQn);
}
}
void saadc_init(void)
{
ret_code_t err_code;
// nrf_drv_saadc_config_t saadc_config;
nrf_saadc_channel_config_t channel_config =
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN0);
//Configure SAADC
channel_config.reference = NRF_SAADC_REFERENCE_VDD4;
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);
}
/**
* @brief Function for main application entry.
*/
int main(void)
{
LEDS_CONFIGURE(LEDS_MASK); //Configure all leds
LEDS_OFF(LEDS_MASK); //Turn off all leds
//NRF_POWER->DCDCEN = 1; //Enabling the DCDC converter
#ifdef UART_PRINTING_ENABLED
uart_config(); //Configure UART. UART is used to show the SAADC sampled result.
printf("\n\rSAADC HAL simple example.\r\n");
#endif //UART_PRINTING_ENABLED
lfclk_config(); //Configure low frequency 32kHz clock
rtc_config(); //Configure RTC. The RTC will generate periodic interrupts. Requires 32kHz clock to operate.
while(1)
{
nrf_delay_ms(100);
//saadc_init();
//nrf_drv_saadc_sample();
__WFE(); //These three commands disable the CPU. CPU will wake up again on any event or interrupt.
__SEV();
__WFE();
}
}
/** @} */
Does i am making any mistake while doing this?? Please guide me in this regards...