adc_read() returns 234

Dear support,

I am using this board: https://www.nologo.tech/en/product/otherboard/NRF52840.html#%E5%BC%95%E8%84%9A%E5%9B%BE. I am trying to use any analog input to eventually read the voltage of my 72V battery pack. Just to get started i want to send some values via BLE. I have tried different configurations in the dts, still getting err = 234. adc_init() seems to work as expected. This is not a nordic devboard so debugging is mainly done using custom values sent to nrf connect app. I did try internal reference and also vdd as refence. I use FOTA at all times for convenience. I use nrf connec sdk in visual studio code. 

I have this device tree and overlay:

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

/dts-v1/;
#include <nordic/nrf52840_qiaa.dtsi>

/ {
	model = "ProMicro nRF";
	compatible = "promicro,promicro-nrf";

	chosen {
		zephyr,sram = &sram0;
		zephyr,flash = &flash0;
		zephyr,code-partition = &slot0_partition;
	};

	zephyr,user {
		io-channels = <&adc 0>;
		io-channel-names = "MAIN_VOLTAGE";
	};

	aliases {
		redled = &red;
	};

	gate_1: gate-1 {
        compatible = "nordic,gpio-pins";
        gpios = <&gpio0 20 (1 << 9)>;
        status = "okay";
    };

    gate_2: gate-2 {
        compatible = "nordic,gpio-pins";
        gpios = <&gpio0 22 (1 << 9)>;
        status = "okay";
    };

    sw_1: sw-1 {
        compatible = "nordic,gpio-pins";
        gpios = <&gpio1 4 0>;
        status = "okay";
    };

    sw_2: sw-2 {
        compatible = "nordic,gpio-pins";
        gpios = <&gpio1 6 0>;
        status = "okay";
    };

    pir_1: pir-1 {
        compatible = "nordic,gpio-pins";
        gpios = <&gpio0 9 GPIO_PULL_DOWN>;
        status = "okay";
    };

    sw_pwr_1: sw-pwr-1 {
        compatible = "nordic,gpio-pins";
        gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>;
        status = "okay";
    };

	button_1: button-1 {
        compatible = "nordic,gpio-pins";
        gpios = <&gpio0 17 GPIO_PULL_UP>;
        status = "okay";
    };

	sw_mp3: sw-mp3 {
        compatible = "nordic,gpio-pins";
        gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
        status = "okay";
    };

	sw_light: sw-light {
        compatible = "nordic,gpio-pins";
        gpios = <&gpio0 29 (1 << 9)>;
        status = "okay";
    };

	leds {
		compatible = "gpio-leds";
		red: led_0 {
			gpios = <&gpio0 15 (GPIO_ACTIVE_LOW)>;
			label = "Red LED";
		};
	};
};

&flash0 {
	partitions {
		compatible = "fixed-partitions";
		#address-cells = <1>;
		#size-cells = <1>;

		boot_partition: partition@0 {
			label = "mcuboot";
			reg = <0x0 0xc000>;
		};
		slot0_partition: partition@c000 {
			label = "image-0";
			reg = <0xc000 0x72000>;
		};
		slot1_partition: partition@7e000 {
			label = "image-1";
			reg = <0x7e000 0x72000>;
		};
		scratch_partition: partition@f0000 {
			label = "image-scratch";
			reg = <0xf0000 0xa000>;
		};
		storage_partition: partition@fa000 {
			label = "storage";
			reg = <0xfa000 0x6000>;
		};
	};
};

&gpio0 {
	status = "okay";
};

&gpio1 {
	status = "okay";
};

&gpiote {
	status = "okay";
};

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

    channel@0 {
        reg = <0>;
        zephyr,gain = "ADC_GAIN_1_6";
        zephyr,reference = "ADC_REF_INTERNAL";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 20)>;
        zephyr,input-positive = <NRF_SAADC_AIN0>; /* P0.24 */
        zephyr,resolution = <10>;
    };
};

/ {
    gate_1: gate-1 {
        status = "disabled";
    };

    gate_2: gate-2 {
        status = "disabled";
    };

    sw_1: sw-1 {
        status = "disabled";
    };

    sw_2: sw-2 {
        status = "disabled";
    };

    pir_1: pir-1 {
        status = "disabled";
    };

    sw_pwr_1: sw-pwr-1 {
        status = "disabled";
    };

	button_1: button-1 {
        status = "disabled";
    };

	sw_mp3: sw-mp3 {
        status = "disabled";
    };

	sw_light: sw-light {
        status = "disabled";
    };

	leds {
		compatible = "gpio-leds";
		red: led_0 {
			gpios = <&gpio0 15 (GPIO_ACTIVE_LOW)>;
			label = "Red LED";
		};
	};
};

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

    channel@0 {
        reg = <0>;
        zephyr,gain = "ADC_GAIN_1";
        zephyr,reference = "ADC_REF_VDD_1";
        zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 50)>;
        zephyr,input-positive = <NRF_SAADC_AIN2>;
        zephyr,resolution = <10>;
    };
};

This is my application: 

#include "application.h"
#include "../bluetooth/bluetooth.h"
#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/settings/settings.h>
#include <bluetooth/services/lbs.h>
#include <hal/nrf_power.h>
#include <zephyr/drivers/adc.h>

static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_ALIAS(redled), gpios);

#define ADC_DEVICE_NAME DT_NODE_FULL_NAME(DT_NODELABEL(adc))
#define ADC_SAMPLE_INTERVAL	20  //unit:ms
#define BATTERY_VOLTAGE(sample) (sample * 6	* 600 / 1024)

static const struct adc_channel_cfg ch0_cfg_dt =
    ADC_CHANNEL_CFG_DT(DT_CHILD(DT_NODELABEL(adc), channel_0));

const struct device *adc_dev;
static int16_t adc_buffer[1];
static uint8_t error_debug = 100;

static struct adc_sequence sequence = {
	.options	= NULL,
	.buffer		= adc_buffer,
	.buffer_size	= sizeof(adc_buffer),
	.resolution	= 10,
	.oversampling	= 0,
	.calibrate	= false,
};

static int init_adc(void)
{
	int err;

	adc_dev = device_get_binding(ADC_DEVICE_NAME);
	error_debug = 101;
	if (!adc_dev) {
		error_debug = 110;
        bt_lbs_send_voltage(11);
		return -EIO;
	}

	err = adc_channel_setup(adc_dev, &ch0_cfg_dt);
	error_debug = 102;
	if (err) {
		error_debug = err;
        bt_lbs_send_voltage(13);
		return err;
	}

	error_debug = 103;
	return 0;
}

int adc_sample(void)
{
	int err;

	err = adc_read(adc_dev, &sequence);
	if (err) {
		bt_lbs_send_voltage(3);
		k_sleep(K_MSEC(1000));
        bt_lbs_send_voltage(err);
		return err;
	}
	bt_lbs_send_voltage(10);
	k_sleep(K_MSEC(1000));
	bt_lbs_send_voltage(adc_buffer[0]);

	return 0;
		
}

void init_pins()
{
    gpio_pin_configure_dt(&led, GPIO_OUTPUT_INACTIVE);
}

void run_application()
{
    static int32_t number = 0;
    init_pins();

    bluetooth_init();

    bluetooth_start_advertising();

    gpio_pin_set_dt(&led, 0);

    k_sleep(K_MSEC(1000));

    init_adc();

    k_sleep(K_MSEC(5000));

    gpio_pin_set_dt(&led, 1);

    for (;;) 
	{
		number++;
		k_sleep(K_MSEC(2000)); // 1000ms
        adc_sample();
		k_sleep(K_MSEC(2000)); // 1000ms
        gpio_pin_set_dt(&led, 0);
		k_sleep(K_MSEC(1000)); // 1000ms
        gpio_pin_set_dt(&led, 1);
        bt_lbs_send_voltage(error_debug);
        k_sleep(K_MSEC(1000)); // 1000ms
	}
}

Parents Reply Children
  • Hello Sigurd,

    I tried your suggestion but i still get the same error. I see now that 234 is true for unsigned int. When instead reading it as signed int i get -22 which corresponds to -EINVAL (invalid argument). I have made some adjustments for debugging but still the same problem. See updated code.

    overlay:

    &adc {
        #address-cells = <1>;
        #size-cells = <0>;
        status = "okay";
    
        channel@0 {
            reg = <0>;
            zephyr,gain = "ADC_GAIN_1_6";
            zephyr,reference = "ADC_REF_INTERNAL";
            zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 20)>;
            zephyr,input-positive = <NRF_SAADC_AIN0>;
            zephyr,resolution = <10>;
        };
    };

    application:

    #include "application.h"
    #include "../bluetooth/bluetooth.h"
    #include <zephyr/kernel.h>
    #include <zephyr/sys/printk.h>
    #include <zephyr/drivers/gpio.h>
    #include <zephyr/settings/settings.h>
    #include <bluetooth/services/lbs.h>
    #include <hal/nrf_power.h>
    #include <zephyr/drivers/adc.h>
    #include <hal/nrf_saadc.h>
    
    static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_ALIAS(redled), gpios);
    
    #define ADC_DEVICE_NAME DT_NODE_FULL_NAME(DT_NODELABEL(adc))
    #define ADC_SAMPLE_INTERVAL	20  //unit:ms
    #define BATTERY_VOLTAGE(sample) (sample * 6	* 600 / 1024)
    
    static const struct adc_channel_cfg ch0_cfg_dt =
        ADC_CHANNEL_CFG_DT(DT_CHILD(DT_NODELABEL(adc), channel_0));
    
    const struct device *adc_dev;
    static int16_t adc_buffer[3];
    static uint8_t error_debug = 100;
    
    static struct adc_sequence sequence = {
    	.options	= NULL,
    	.buffer		= adc_buffer,
    	.buffer_size	= sizeof(adc_buffer),
    };
    
    static int init_adc(void)
    {
    	int err;
    
    	adc_dev = device_get_binding(ADC_DEVICE_NAME);
    	error_debug = 101;
    	if (!adc_dev) {
    		//error_debug = 110;
            bt_lbs_send_voltage(11);
    		return -EIO;
    	}
    
    	err = adc_channel_setup(adc_dev, &ch0_cfg_dt);
    	error_debug = 102;
    	if (err) {
    		//error_debug = err;
            bt_lbs_send_voltage(13);
    		return err;
    	}
    
    	error_debug = 103;
    	return 0;
    }
    
    int adc_sample(void)
    {
    	int err;
    
    	sequence.channels = BIT(ch0_cfg_dt.channel_id);
    	err = adc_read(adc_dev, &sequence);
    	if (err) {
    		bt_lbs_send_voltage(3);
    		k_sleep(K_MSEC(1000));
            bt_lbs_send_voltage(err);
    		return err;
    	}
    	bt_lbs_send_voltage(10);
    	k_sleep(K_MSEC(1000));
    	bt_lbs_send_voltage(adc_buffer[0]);
    
    	return 0;
    		
    }
    
    void init_pins()
    {
        gpio_pin_configure_dt(&led, GPIO_OUTPUT_INACTIVE);
    }
    
    void run_application()
    {
        static int32_t number = 0;
        init_pins();
    
        bluetooth_init();
    
        bluetooth_start_advertising();
    
        init_adc();
    
    	k_sleep(K_MSEC(3000));
    
        for (;;) 
    	{
    		k_sleep(K_MSEC(1000));
            error_debug = adc_sample();
            gpio_pin_set_dt(&led, 0);
    		k_sleep(K_MSEC(1000));
            gpio_pin_set_dt(&led, 1);
            k_sleep(K_MSEC(1000));
    		bt_lbs_send_voltage(0);
    	}
    }

    Oh i think i found the issue... when adding adding all the parameters to the sequence struct it finally works! Thank you for your support Slight smile

    static struct adc_sequence sequence = {
    	.options	= NULL,
    	.channels = BIT(0),
    	.buffer		= adc_buffer,
    	.buffer_size	= sizeof(adc_buffer),
    	.resolution = 10,
    	.oversampling = 0,
    	.calibrate = 	false,
    };

Related