NRF52840 Zephyr ADC read issue

Hello,

I am using nrf52840 on usb dongle  and i would like to measure voltage on a specific ADC input pin.

According to the datasheet, i use P0.02/AIN0.

My problem is that adc_read() function returns -22 error.

I am posting the code and the overlay file. Could you please help me what i am doing wrong here?

Thanks a lot guys!

Thanos

&adc
{   
    status = "okay";
    io-channels = <&adc 0>;
};
#define ADC_RESOLUTION		    12
#define ADC_GAIN			    ADC_GAIN_1
#define ADC_REFERENCE		    ADC_REF_INTERNAL
#define ADC_ACQUISITION_TIME	ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 40)
#define ADC_CHANNEL_AIN0       0

#define ADC_IO_LABEL            DT_GPIO_LABEL(DT_ALIAS(gpiocus1), gpios)
#define ADC_IO_PIN	            DT_GPIO_PIN(DT_ALIAS(gpiocus1), gpios)

const struct device *adc_dev;
const struct device *adc_en_dev;


uint32_t sample_buffer[10] = {0};


static struct adc_channel_cfg adcConfig = 
{
	.gain             = ADC_GAIN,
	.reference        = ADC_REFERENCE,
	.acquisition_time = ADC_ACQUISITION_TIME,
	.channel_id       = 1, // gets set during init
	.differential	  = 0,
// #if CONFIG_ADC_CONFIGURABLE_INPUTS
	// .input_positive   = 0, // gets set during init
// #endif
};

const struct adc_sequence sequence = 
{
	    .options     = NULL,				// extra samples and callback
		.channels    = BIT(ADC_CHANNEL_AIN0),		// bit mask of channels to read
		.buffer      = sample_buffer,		// where to put samples read
		.buffer_size = sizeof(sample_buffer),
		.resolution  = ADC_RESOLUTION,		// desired resolution
		.oversampling = 0,					// don't oversample
		.calibrate = 0						// don't calibrate
};
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
bool adc_init(uint8_t channel)
{
    int adcInitError;
    
    adc_dev = DEVICE_DT_GET(DT_NODELABEL(adc));
    if(adc_dev == NULL)
    {
        return false;
    }

    adc_dev = device_get_binding(DEVICE_DT_NAME(DT_NODELABEL(adc)));
    if(adc_dev == NULL)
    {
        return false;
    }

    adcConfig.channel_id = channel;
    adcInitError = adc_channel_setup(adc_dev, &adcConfig);
    if(adcInitError)
    {
        return false;
    }

    return true;
}
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
uint32_t readBatteryVoltage(void)
{
    int readBatteryVoltageError = 0;

    readBatteryVoltageError = adc_read(adc_dev, &sequence);
    if(readBatteryVoltageError == 0)
    {
        return sample_buffer[0];
    }

    return 0;
}
CONFIG_ADC=y
CONFIG_ADC_ASYNC=y

Parents
  • Hi

    I finally got some time to run some power consumption tests using the ADC driver, and using the adc_sample() function I don't seem to need to do anything in order to get low power consumption (other than disable logging in the application). When I sample the ADC at a slow rate it has very little impact on overall system power, and the sleep currents seem to be unchanged:

    adc_low_power.zip

    Could you try it out and see if it works for you as well?

    Regarding Zephyr threads it is important not to get them mixed up with the Thread wireless protocol ;)

    The easiest way to create a thread is to use the K_THREAD_DEFINE macro, then you can create and start a thread with a single line of code:

    // Define the thread function
    void my_thread_func(void)
    {
    
    }
    
    // Initialize and start the thread
    K_THREAD_DEFINE(my_thread, 1024, my_thread_func, NULL, NULL, NULL, 5, 0, 0);

    Best regards
    Torbjørn

Reply
  • Hi

    I finally got some time to run some power consumption tests using the ADC driver, and using the adc_sample() function I don't seem to need to do anything in order to get low power consumption (other than disable logging in the application). When I sample the ADC at a slow rate it has very little impact on overall system power, and the sleep currents seem to be unchanged:

    adc_low_power.zip

    Could you try it out and see if it works for you as well?

    Regarding Zephyr threads it is important not to get them mixed up with the Thread wireless protocol ;)

    The easiest way to create a thread is to use the K_THREAD_DEFINE macro, then you can create and start a thread with a single line of code:

    // Define the thread function
    void my_thread_func(void)
    {
    
    }
    
    // Initialize and start the thread
    K_THREAD_DEFINE(my_thread, 1024, my_thread_func, NULL, NULL, NULL, 5, 0, 0);

    Best regards
    Torbjørn

Children
No Data
Related