Inquiries regarding adc.

Hello.
"zephyr/samples/drivers/adc/adc_dt" example sample added an additional adcpin.

When reading the sensor value connected to AIN0, the value of AIN1 is also changing.

How can I solve this?

#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE( sta, CONFIG_LOG_DEFAULT_LEVEL );

#include <zephyr/kernel.h>
#include <errno.h>
#include <stdio.h>

#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/adc.h>
#include <zephyr/drivers/gpio.h>

#include "ADC.h"
#include "deviceInformation.h"


//! Variable to identify the TCP Client thread
static struct k_thread ADCThread;
//! Stack size for the TCP_CLIENT thread
#define ADC_STACK_SIZE 2*1024
//! ADC thread priority level
#define ADC_PRIORITY 7

//! ADC stack definition
K_THREAD_STACK_DEFINE(ADC_STACK, ADC_STACK_SIZE);
//! Variable to identify the ADC thread
static struct k_thread ADCThread;

#define LEDS_NODE DT_PATH(leds)
#define GPIO_SPEC_AND_COMMA(button_or_led) GPIO_DT_SPEC_GET(button_or_led, gpios),


#if !DT_NODE_EXISTS(DT_PATH(zephyr_user)) || \
	!DT_NODE_HAS_PROP(DT_PATH(zephyr_user), io_channels)
#error "No suitable devicetree overlay specified"
#endif


#define DT_SPEC_AND_COMMA(node_id, prop, idx) \
	ADC_DT_SPEC_GET_BY_IDX(node_id, idx),


/* Data of ADC io-channels specified in devicetree. */
static const struct adc_dt_spec adc_channels[] = {
	DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), io_channels,
			     DT_SPEC_AND_COMMA)
};

uint16_t cnt = 0;

// static const struct gpio_dt_spec sensor_en = GPIO_DT_SPEC_GET(DT_PATH(zephyr_user), sensor_en_gpios);
static const struct gpio_dt_spec My_gpios[] = {
	GPIO_DT_SPEC_GET(DT_PATH(zephyr_user), bat_en_gpios),
	GPIO_DT_SPEC_GET(DT_PATH(zephyr_user), dt1_gpios),
	GPIO_DT_SPEC_GET(DT_PATH(zephyr_user), dt2_gpios)
};

static const struct gpio_dt_spec leds[] = {
#if DT_NODE_EXISTS(LEDS_NODE)
	DT_FOREACH_CHILD(LEDS_NODE, GPIO_SPEC_AND_COMMA)
#endif
};

void ADC( void )
{
	int err;
	uint32_t count = 0;
	uint16_t buf;
	struct adc_sequence sequence = {
		.buffer = &buf,
		/* buffer size in bytes, not number of samples */
		.buffer_size = sizeof(buf),
	};

	/* Configure channels individually prior to sampling. */
	for (size_t i = 0U; i < ARRAY_SIZE(adc_channels); i++) {
		if (!adc_is_ready_dt(&adc_channels[i])) {
			LOG_INF("ADC controller device %s not ready\n", adc_channels[i].dev->name);
			return 0;
		}

		err = adc_channel_setup_dt(&adc_channels[i]);
		if (err < 0) {
			LOG_INF("Could not setup channel #%d (%d)\n", i, err);
			return 0;
		}
	}

	int ret;

	LOG_INF( "ADC Test");

	for (size_t i = 0; i < ARRAY_SIZE(leds); i++) {
		err = gpio_pin_configure_dt(&leds[i], GPIO_OUTPUT);
		if (err) {
			LOG_ERR("Cannot configure LED gpio");
			return err;
		}
	}

	if (!gpio_is_ready_dt(&My_gpios)) {
		return 0;
	}

	gpio_pin_configure_dt(&My_gpios[0], GPIO_OUTPUT);
	gpio_pin_configure_dt(&My_gpios[1], GPIO_OUTPUT);
	gpio_pin_configure_dt(&My_gpios[2], GPIO_OUTPUT);


	gpio_pin_set_dt(&My_gpios[0], 1);		//BAT_EN
	gpio_pin_set_dt(&My_gpios[1], 0);
	gpio_pin_set_dt(&My_gpios[2], 1);

	while(1) {
		// LOG_INF( "CNT : %d", cnt);
		// cnt++;
		printk("ADC reading[%u]:\n", count++);

		for (size_t i = 0U; i < ARRAY_SIZE(adc_channels); i++) {
			int32_t val_mv;

			printk("- %s, channel %d: ",
			       adc_channels[i].dev->name,
			       adc_channels[i].channel_id);

			(void)adc_sequence_init_dt(&adc_channels[i], &sequence);

			err = adc_read_dt(&adc_channels[i], &sequence);
			if (err < 0) {
				printk("Could not read (%d)\n", err);
				continue;
			}

			/*
			 * If using differential mode, the 16 bit value
			 * in the ADC sample buffer should be a signed 2's
			 * complement value.
			 */
			if (adc_channels[i].channel_cfg.differential) {
				val_mv = (int32_t)((int16_t)buf);
			} else {
				val_mv = (int32_t)buf;
			}
			if(val_mv < (int32_t)0 || val_mv > (int32_t)16384) val_mv = (int32_t)0;
			printk("%"PRId32, val_mv);
			err = adc_raw_to_millivolts_dt(&adc_channels[i],
						       &val_mv);
			/* conversion to mV may not be supported, skip if not */
			if (err < 0) {
				printk(" (value in mV not available)\n");
			} else {
				printk(" = %"PRId32" mV\n", val_mv);
			}
		}
		k_msleep(500);
	}
}


/*! Task_ADC_Init initializes the task ADC
*
* @brief ADC initialization
*/
void Task_ADC_Init( void ){
	
	k_thread_create	(														
					&ADCThread,										
					ADC_STACK,										
					ADC_STACK_SIZE,									
					(k_thread_entry_t)ADC,							
					NULL,													
					NULL,													
					NULL,													
					ADC_PRIORITY,									
					0,														
					K_NO_WAIT);	

	 k_thread_name_set(&ADCThread, "ADC");
	 k_thread_start(&ADCThread);
};

Parents Reply Children
  • Are you able to reproduce the issue on the nRF7002DK or nRF5340DK? If so, please upload the simple project to reproduce the issue on the nRF7002DK or nRF5340DK. That means uploading the source code and configuration. 

    ozoz05 said:
    When sdk was used in SES with the same configuration as the rest of the circuit except mcu (using nRF52833), this problem did not occur.

    Seems the issue might be the hardware. Please make sure to use the correct pins for AIN0 and AIN1 on your custom board.

Related