How do you set values to 0 on unused adc channels ?

I am trying to setup the following pins A1 (Pin 0.05) , A2 (Pin 0.06) , A3(Pin 0.07) & A4 (Pin 0.25) to read adc values using the nrf5340dk board. I have a joystick module connected to pins A1 & A2 and nothing is connected to pins A3 & A4 but for some reason i am still seeing values on the nrf terminal , i dont know what these values are and how can i setup the channels so that if nothing is connected i read only 0's ?  

My code is shown below: 

/*
 * Copyright (c) 2020 Libre Solar Technologies GmbH
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>

#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/adc.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/util.h>
#include <zephyr/drivers/gpio.h>

#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)
};

void main(void)
{
	int err;
	int16_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 (!device_is_ready(adc_channels[i].dev)) {
			printk("ADC controller device not ready\n");
			return;
		}

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

	while (1) {
		//printk("ADC reading:\n");
			/*---------Channel A1 (Pin 0.04)--------*/
			printk("\n channel %d: ",
			       adc_channels[0].channel_id);
			(void)adc_sequence_init_dt(&adc_channels[0], &sequence);

			err = adc_read(adc_channels[0].dev, &sequence);
			printk("%"PRId16,buf);


			/*---------Channel A2 (Pin 0.06)--------*/
			printk("\n channel %d: ",
			       adc_channels[1].channel_id);
			(void)adc_sequence_init_dt(&adc_channels[1], &sequence);

			err = adc_read(adc_channels[1].dev, &sequence);
			printk("%"PRId16,buf);

			/*---------Channel A3 (Pin 0.07)--------*/
			printk("\n channel %d: ",
			       adc_channels[2].channel_id);
			(void)adc_sequence_init_dt(&adc_channels[2], &sequence);

			err = adc_read(adc_channels[2].dev, &sequence);
			printk("%"PRId16,buf);

			/*---------Channel A4 (Pin 0.25)--------*/
			printk("\n channel %d: ",
			       adc_channels[3].channel_id);
			(void)adc_sequence_init_dt(&adc_channels[3], &sequence);

			err = adc_read(adc_channels[3].dev, &sequence);
			printk("%"PRId16,buf);


		

		k_sleep(K_MSEC(1000));
	}
}

nrf5340dk_nrf5340_cpuapp.overlay

/*
 * SPDX-License-Identifier: Apache-2.0
 *
 * Copyright (c) 2022 Nordic Semiconductor ASA
 */


/ {
	zephyr,user {
		io-channels = <&adc 1>, <&adc 2>, <&adc 3> , <&adc 4> ;
	};
};

&adc {
	#address-cells = <1>;
	#size-cells = <0>;

	channel@0 {
		reg = <1>;
		zephyr,gain = "ADC_GAIN_1_4";
		zephyr,reference = "ADC_REF_INTERNAL";
		zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 20)>;
		zephyr,input-positive = <NRF_SAADC_AIN1>; /* P0.05 */
		zephyr,resolution = <12>;
	};

	channel@2 {
		reg = <2>;
		zephyr,gain = "ADC_GAIN_1_4";
		zephyr,reference = "ADC_REF_INTERNAL";
		zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 20)>;
		zephyr,input-positive = <NRF_SAADC_AIN2>;/* P0.06 */
		zephyr,resolution = <12>;
	};

	channel@3 {
		reg = <3>;
		zephyr,gain = "ADC_GAIN_1_4";
		zephyr,reference = "ADC_REF_INTERNAL";
		zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 20)>;
		zephyr,input-positive = <NRF_SAADC_AIN3>; /* P0.07 */
		zephyr,resolution = <12>;
	};


	channel@4 {
		reg = <4>;
		zephyr,gain = "ADC_GAIN_1_4";
		zephyr,reference = "ADC_REF_INTERNAL";
		zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 20)>;
		zephyr,input-positive = <NRF_SAADC_AIN4>; /* P0.07 */
		zephyr,resolution = <12>;
	};
};

prj.conf

CONFIG_ADC=y

Parents
  • Hello,

    Sorry for the late reply. 

    The ADC, which is used to measure the input voltage has no way of knowing whether something is attached or not. It just measures the voltage on the pin. So if it is disconnected (floating), it just measures noise. As long as the pin is not grounded, it will not show a consistent 0. 

    Is it really an issue? If you plan to connect all 4 channels to two joysticks, they will not be disconnected at any point, right?

    Or if you intend to have only one joystick, perhaps you can remove channel 3 and 4?

    Best regards,

    Edvin

Reply
  • Hello,

    Sorry for the late reply. 

    The ADC, which is used to measure the input voltage has no way of knowing whether something is attached or not. It just measures the voltage on the pin. So if it is disconnected (floating), it just measures noise. As long as the pin is not grounded, it will not show a consistent 0. 

    Is it really an issue? If you plan to connect all 4 channels to two joysticks, they will not be disconnected at any point, right?

    Or if you intend to have only one joystick, perhaps you can remove channel 3 and 4?

    Best regards,

    Edvin

Children
No Data
Related