RAK4631 ADC : AIN2 Not Configured

I am programming a RAK4631 Board, which is of course based on the nrf52840 SoC. The BaseLine Device tree has no detail in the ADC Node so I have created an overlay. The RAK4631 documentation indicates that AIN2 (P0.04) is directly connected to the battery for voltage measurement. There are many Arduino examples out there but not many C code examples. Here is my overlay file contents:
/ {

zephyr,user {

io-channels = <&adc 2>, <&adc 7>;

};

};

&adc {

status = “okay”;

#address-cells = <1>;

#size-cells = <0>;

channel@2 {

reg = <2>;
zephyr,gain = “ADC_GAIN_1_6”;
zephyr,reference = “ADC_REF_INTERNAL”;
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
zephyr,input-positive = <NRF_SAADC_AIN2>; /* Corresponds to P0.04 */
zephyr,resolution = <12>;
};

channel@7 {
reg = <7>;
zephyr,gain = “ADC_GAIN_1_6”;
zephyr,reference = “ADC_REF_INTERNAL”;
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
zephyr,input-positive = <NRF_SAADC_AIN7>; /* Corresponds to P0.31 */
zephyr,resolution = <12>;
};

};

Here is my setup code:
//
// ADC Defines
//
#define BATT_ADC_NODE DT_NODELABEL(adc) // ADC peripheral node
#define ADC_RESOLUTION 12 // 12-bit ADC resolution
#define ADC_GAIN ADC_GAIN_1_6 // Gain setting for ADC
#define ADC_REFERENCE ADC_REF_INTERNAL // Internal reference voltage
#define ADC_ACQUISITION_TIME ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 10) // Acquisition time
#define BATTERY_CHANNEL_ID 2 // ADC channel ID for the battery AIN2
#define ADC_MAX_VOLTAGE 3.6 // Maximum ADC input voltage (V)
#define ADC_FULL_SCALE (1 << ADC_RESOLUTION) // Full-scale value for 12-bit ADC

#define VOLTAGE_DIVIDER_RATIO 2.0f
const struct device *batt_adc_dev = DEVICE_DT_GET(BATT_ADC_NODE);

// Define ADC channel configuration
static const struct adc_channel_cfg battery_channel_cfg = {

.gain = ADC_GAIN_1_6,
.reference = ADC_REF_INTERNAL,
.acquisition_time = ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 10),
.channel_id = BATTERY_CHANNEL_ID, // Specify the channel ID for AIN2
.differential = 0 // Single-ended input
};

// Define ADC sequence
static struct adc_sequence battery_adc_seq = {
.channels = BIT(BATTERY_CHANNEL_ID),
.buffer = NULL, // Buffer will be set dynamically
.buffer_size = 0,
.resolution = ADC_RESOLUTION,
};

I am calling this for setup:
//
// Check AIN Ready for Battery Voltage Read
//

if (!device_is_ready(batt_adc_dev))
{
LOG_ERR(“AIN2 Device not ready”);

return;
}
else
{
LOG_ERR(“AIN2 Device Ready!!”);
}

ret = adc_channel_setup(batt_adc_dev, &battery_channel_cfg);

if (ret != 0) {

LOG_ERR(“Failed to configure ADC channel: %d”, ret);
}else

{
LOG_INF(“ADC channel configured for battery voltage measurement”);
}

These calls are all successful.

However, when I call this:

int ret = adc_read(batt_adc_dev, &battery_adc_seq);

if (ret < 0) {
LOG_ERR(“Failed to read ADC: %d”, ret);
return -1.0f;
}

I always get this log message:

00> [00:30:35.901,824] adc_nrfx_saadc: Channel 2 not configured
00> [00:30:36.002,075] ublox_gps: Failed to read ADC: -22

The project builds successfully without warnings or errors. I am on a Windows 11 machine, using VSCODE and the nrfConnect Framework with Zephyr. Any help letting me know where I am going wrong would be appreciated. I am using Zephyr v2.9.0 which I believe is the latest and the RAK4631 dev board with the ublox GPS Chip and the SHTC3 Sensor connected as well.

Thank you.

Welcome to RAK forum @equarles2 .

We want to help you here but most of info you can get in our forum is based on Arduino. I haven’t used Zephyr personally so I cannot make any comment on the overlay file.

However, we’ll see if there’s anyone in RAK community that can provide answer. Else, it is best to checkout with Zephyr community (Discord, Github, NXP forum, etc.)

Hi @equarles2,

I will look into your case.

When I checked your shared code, firstly, you are trying to setup adc channels inside your rak4631 overlay file but you are not using these parameters while setting up adc inside main. Please be aware about this.

The reason of the problem is that you are not assigning .input_positive for configurartion and there is no buffer for measurements. Please try with following settings.

...
#include <hal/nrf_saadc.h>
...

// Define ADC channel configuration
static const struct adc_channel_cfg battery_channel_cfg = {
	.gain = ADC_GAIN_1_6,
	.reference = ADC_REF_INTERNAL,
	.acquisition_time = ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 10),
	.channel_id = BATTERY_CHANNEL_ID, // Specify the channel ID for AIN2
	.differential = 0, // Single-ended input
	.input_positive = NRF_SAADC_INPUT_AIN2,
};

// Define ADC sequence
#define BUFFER_LEN 1
static uint16_t m_sample_buffer[BUFFER_LEN];
static struct adc_sequence battery_adc_seq = {
	.buffer = m_sample_buffer,
	.buffer_size = sizeof(m_sample_buffer),
	.resolution = ADC_RESOLUTION,
	.options = NULL,
	.oversampling = 0,
	.channels = BIT(BATTERY_CHANNEL_ID),
};

Please check zephyr example applications for easier usage if you want.

Best regards,
Sercan.

1 Like

This ticket can be closed…Thank you!!

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.