Some time I'll got wrong value from read ADC.
I am using ncs2.0.2.
Here is my debug message you can see huge value at adc port 2.
======================= ADC raw value[2]: 65535 rc[2] : 230396 mV
Here is how I define ADC node in DTS.
/{
zephyr,user {
io-channels = <&adc 0>, <&adc 1>, <&adc 2>, <&adc 3>, <&adc 4>;
};
}
&adc {
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0>;
zephyr,gain = "ADC_GAIN_1_6";
zephyr,reference = "ADC_REF_INTERNAL";
zephyr,resolution = <12>;
};
channel@1 {
reg = <1>;
zephyr,gain = "ADC_GAIN_1_6";
zephyr,reference = "ADC_REF_INTERNAL";
zephyr,resolution = <12>;
};
channel@2 {
reg = <2>;
zephyr,gain = "ADC_GAIN_1_6";
zephyr,reference = "ADC_REF_INTERNAL";
zephyr,resolution = <12>;
};
channel@3 {
reg = <3>;
zephyr,gain = "ADC_GAIN_1_6";
zephyr,reference = "ADC_REF_INTERNAL";
zephyr,resolution = <12>;
};
channel@4 {
reg = <4>;
zephyr,gain = "ADC_GAIN_1_6";
zephyr,reference = "ADC_REF_INTERNAL";
zephyr,resolution = <12>;
};
};
Here is my full code
#ifndef _NRFADC_C
#define _NRFADC_C
#include <zephyr.h>
#include <sys/printk.h>
/*ADC definitions and includes*/
#include <hal/nrf_saadc.h>
#include <device.h>
#include <drivers/gpio.h>
#include <drivers/adc.h>
#include <string.h>
#define DEBUG 1
#if DEBUG == 1
#define debug(x, ...) {printk(x, ##__VA_ARGS__);}
#else
#define debug(x, ...)
#endif
#define ADC_DEVICE_NAME DT_LABEL(DT_INST(0, nordic_nrf_saadc))
#define ADC_RESOLUTION 10
#define ADC_GAIN ADC_GAIN_1_6
#define ADC_REFERENCE ADC_REF_INTERNAL
#define ADC_ACQUISITION_TIME ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 10)
#define ADC_1ST_CHANNEL_ID 0
#define ADC_2ST_CHANNEL_ID 1
#define ADC_3ST_CHANNEL_ID 2
#define ADC_4ST_CHANNEL_ID 3
#define ADC_5ST_CHANNEL_ID 4
#define BUFFER_SIZE 5
#define ADC_MAX_VOLT 3300
#define ADC_ERROR_VELUE 100000 // Should not that big.
const struct device *adc_dev;
int adcDataArray[5] = {0, 0, 0, 0, 0}; //A0, A1, A2, A3 , A7
/* ========================================== */
static const struct adc_channel_cfg AIN0 = {
.gain = ADC_GAIN,
.reference = ADC_REFERENCE,
.acquisition_time = ADC_ACQUISITION_TIME,
.channel_id = ADC_1ST_CHANNEL_ID,
#if defined(CONFIG_ADC_CONFIGURABLE_INPUTS)
.input_positive = NRF_SAADC_INPUT_AIN0,
#endif
};
static const struct adc_channel_cfg AIN1 = {
.gain = ADC_GAIN,
.reference = ADC_REFERENCE,
.acquisition_time = ADC_ACQUISITION_TIME,
.channel_id = ADC_2ST_CHANNEL_ID,
#if defined(CONFIG_ADC_CONFIGURABLE_INPUTS)
.input_positive = NRF_SAADC_INPUT_AIN1,
#endif
};
static const struct adc_channel_cfg AIN2 = {
.gain = ADC_GAIN,
.reference = ADC_REFERENCE,
.acquisition_time = ADC_ACQUISITION_TIME,
.channel_id = ADC_3ST_CHANNEL_ID,
#if defined(CONFIG_ADC_CONFIGURABLE_INPUTS)
.input_positive = NRF_SAADC_INPUT_AIN2,
#endif
};
static const struct adc_channel_cfg AIN3 = {
.gain = ADC_GAIN,
.reference = ADC_REFERENCE,
.acquisition_time = ADC_ACQUISITION_TIME,
.channel_id = ADC_4ST_CHANNEL_ID,
#if defined(CONFIG_ADC_CONFIGURABLE_INPUTS)
.input_positive = NRF_SAADC_INPUT_AIN3,
#endif
};
static const struct adc_channel_cfg AIN7 = {
.gain = ADC_GAIN,
.reference = ADC_REFERENCE,
.acquisition_time = ADC_ACQUISITION_TIME,
.channel_id = ADC_5ST_CHANNEL_ID,
#if defined(CONFIG_ADC_CONFIGURABLE_INPUTS)
.input_positive = NRF_SAADC_INPUT_AIN7,
#endif
};
const struct adc_channel_cfg* adcArray[BUFFER_SIZE] = {
&AIN0, // A0
&AIN1, // A1
&AIN2, // A2
&AIN3, // A3
&AIN7, // A7
};
static uint16_t m_sample_buffer[BUFFER_SIZE];
const struct adc_sequence sequence = {
.channels = 0b00011111,// BIT(ADC_1ST_CHANNEL_ID|ADC_2ST_CHANNEL_ID|ADC_3ST_CHANNEL_ID|ADC_4ST_CHANNEL_ID|ADC_5ST_CHANNEL_ID),
.buffer = m_sample_buffer,
.buffer_size = sizeof(m_sample_buffer),
.resolution = ADC_RESOLUTION,
};
/* ========================================== */
void adcInit(void){
int err;
adc_dev = device_get_binding(ADC_DEVICE_NAME);
if (!adc_dev) {
printk("device_get_binding ADC_0 (=%s) failed\n", ADC_DEVICE_NAME);
}
for(int i=0; i < ARRAY_SIZE(adcArray); i++){
err = adc_channel_setup(adc_dev, adcArray[i]);
if (err) {
printk("Error in adc setup[%d]: %d\n", i, err);
}
}
NRF_SAADC->TASKS_CALIBRATEOFFSET = 1;
}
int ADCreading(void){
int ret;
if (!adc_dev) {
return -1;
}
/* Wait for voltage to stabilize */
// k_busy_wait(5);/*VOLTAGE_STABILIZE_TIME_US*/
ret = adc_read(adc_dev, &sequence);
if (ret) {
printk("adc_read() failed with code %d\n", ret);
}else{
for (int i = 0; i < BUFFER_SIZE; i++) {
printk("=======================\n");
printk("ADC raw value[%d]: %d\n", i, m_sample_buffer[i]);
int32_t val = m_sample_buffer[i];
adc_raw_to_millivolts(adc_ref_internal(adc_dev),
adcArray[i]->gain,
sequence.resolution,
&val);
printk("rc[%d] : %d mV \n", i, val);
if (val < 0){
val = 0;
}else if (val >ADC_ERROR_VELUE){
// Should not that big. skip this val
// return;
}else if (val > ADC_MAX_VOLT){
val = ADC_MAX_VOLT;
}
adcDataArray[i] = (val*0xFF)/ADC_MAX_VOLT;
debug("adcDataArray[%d] : %d \n", i, adcDataArray[i]);
}
}
return ret;
}
#endif /*_NRFADC_C*/