Get weird value back when read ADC

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*/

Related