Dear All, I would like a simple way to read the voltage on one ADC pin without using any "adc_event_handler"-like solution. I tried
reading=nrf_adc_convert_single(NRF_ADC_CONFIG_INPUT_2);
but without success.
Thanks
Francesco
Dear All, I would like a simple way to read the voltage on one ADC pin without using any "adc_event_handler"-like solution. I tried
reading=nrf_adc_convert_single(NRF_ADC_CONFIG_INPUT_2);
but without success.
Thanks
Francesco
The function does not check if the ADC is initialized and powered
See: developer.nordicsemi.com/.../a00754.html
So are you sure that you have correctly initialized and powered the ADC?
Let me explain better. This is my main. It is basically the adc example where I tried not to use the interrupts or the handler to have a reading.
#include "nrf.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "nrf_drv_adc.h"
#include "nordic_common.h"
#include "boards.h"
#include "nrf_log.h"
#include "app_error.h"
#include "nrf_delay.h"
#include "app_util_platform.h"
#define ADC_BUFFER_SIZE 1 /**< Size of buffer for ADC samples. */
static nrf_adc_value_t adc_buffer[ADC_BUFFER_SIZE]; /* ADC buffer. */
static nrf_drv_adc_channel_t m_channel_config = NRF_DRV_ADC_DEFAULT_CHANNEL(NRF_ADC_CONFIG_INPUT_2); /* Channel instance. Default configuration used. */
static void adc_event_handler(nrf_drv_adc_evt_t const * p_event)
{
// if (p_event->type == NRF_DRV_ADC_EVT_DONE)
// { // uint32_t i;
// for (i = 0; i < p_event->data.done.size; i++)
// {
// NRF_LOG_PRINTF("Current sample value: %d\r\n", p_event->data.done.p_buffer[i]); //
// }
// }
}
static void adc_config(void)
{
ret_code_t ret_code;
nrf_drv_adc_config_t config = NRF_DRV_ADC_DEFAULT_CONFIG;
ret_code = nrf_drv_adc_init(&config, adc_event_handler);
APP_ERROR_CHECK(ret_code);
nrf_drv_adc_channel_enable(&m_channel_config);
}
int main(void)
{
nrf_adc_value_t myvalue;
LEDS_CONFIGURE(BSP_LED_0_MASK);
LEDS_OFF(BSP_LED_0_MASK);
adc_config();
UNUSED_RETURN_VALUE(NRF_LOG_INIT());
NRF_LOG_PRINTF("ADC example\r\n");
while(1)
{
APP_ERROR_CHECK(nrf_drv_adc_buffer_convert(adc_buffer,ADC_BUFFER_SIZE));
nrf_drv_adc_sample();
nrf_delay_ms(100);
LEDS_INVERT(BSP_LED_0_MASK);\
myvalue=nrf_adc_convert_single(NRF_ADC_CONFIG_INPUT_2);
NRF_LOG_PRINTF("Currently my value: %d\r\n",myvalue);
}
}
I would like to know more details about:
2: if I understand properly first a measurement is triggered with nrf_drv_adc_sample() while nrf_adc_convert_single makes accessible the first of the measurements. Am I correct?
Thanks
First of all, event-driven ADC is recommended, so that the CPU can be turned off during inactive periods. But if you don’t want that, here is a very simple way to read the ADC without using any events, using the nrf_drv_adc_sample_convert
function:
#include "nrf.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "nrf_drv_adc.h"
#include "nordic_common.h"
#include "boards.h"
#include "nrf_log.h"
#include "app_error.h"
#include "nrf_delay.h"
#include "app_util_platform.h"
static nrf_adc_value_t adc_value; /**< ADC buffer. */
static nrf_drv_adc_channel_t m_channel_config = NRF_DRV_ADC_DEFAULT_CHANNEL(NRF_ADC_CONFIG_INPUT_2);
/**
* @brief Function for main application entry.
*/
int main(void)
{
UNUSED_RETURN_VALUE(NRF_LOG_INIT());
NRF_LOG_PRINTF("ADC example\r\n");
while (true)
{
nrf_drv_adc_sample_convert(&m_channel_config,&adc_value);
NRF_LOG_PRINTF("ADC buffer: %d\r\n",adc_value);
nrf_delay_ms(100);
}
}
/** @} */
Thanks Sigurd, how long does it take to have a measurement ready? Can I shorten the nrf_delay_ms() to 10ms (of course after removing the UART)?
How long time before the measurement is ready depend on what bit mode you use on the ADC. The default configuration uses 10-bit, and takes 68 μs to sample. If you use 8-bit mode it takes 20 μs (50K samples per second). The nrf_delay_ms() is just there to not overflow the uart.