nrf9160 DK Analog Input Pin Configuration

Hi, I am currently developing on nrf9160 DK, and would like to set pins 0.14 and 0.15 as analog inputs to read data from sensors, similar to arduino uno, but not sure how to read the pins, or if I need to use ADC driver for this, or if i need to modify the devicetree file. Please help

  • Hello,

    You can find an example below showing how to read the ADC, should work for most nordic DK's.

    #include <zephyr.h>
    #include <device.h>
    #include <sys/printk.h>
    #include <drivers/gpio.h>
    #include <drivers/adc.h>
    #include <string.h>
    
    /*ADC definitions and includes*/
    #include <hal/nrf_saadc.h>
    #define ADC_DEVICE_NODE		DT_INST(0, nordic_nrf_saadc)
    #define ADC_RESOLUTION		10
    #define ADC_GAIN		ADC_GAIN_1_6
    #define ADC_REFERENCE		ADC_REF_INTERNAL
    #define ADC_ACQUISITION_TIME	ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 10)
    #define ADC_1ST_CHANNEL_ID	0
    #define ADC_1ST_CHANNEL_INPUT	NRF_SAADC_INPUT_AIN1 // Check the "pin assignment" table in the product spec to find which pin is AIN1
    #define ADC_2ND_CHANNEL_ID	1
    #define ADC_2ND_CHANNEL_INPUT	NRF_SAADC_INPUT_AIN2 // Check the "pin assignment" table in the product spec to find which pin is AIN2
    
    #define TIMER_INTERVAL_MSEC 200
    
    #if defined(ADC_2ND_CHANNEL_ID)
    #define BUFFER_SIZE 2
    #else
    #define BUFFER_SIZE 1
    #endif
    
    struct k_timer my_timer;
    const struct device *adc_dev;
    
    static const struct adc_channel_cfg m_1st_channel_cfg = {
    	.gain = ADC_GAIN,
    	.reference = ADC_REFERENCE,
    	.acquisition_time = ADC_ACQUISITION_TIME,
    	.channel_id = ADC_1ST_CHANNEL_ID,
    #if defined(CONFIG_ADC_CONFIGURABLE_INPUTS)
    	.input_positive = ADC_1ST_CHANNEL_INPUT,
    #endif
    };
    
    #if defined(ADC_2ND_CHANNEL_ID)
    static const struct adc_channel_cfg m_2nd_channel_cfg = {
    	.gain             = ADC_GAIN,
    	.reference        = ADC_REFERENCE,
    	.acquisition_time = ADC_ACQUISITION_TIME,
    	.channel_id       = ADC_2ND_CHANNEL_ID,
    #if defined(CONFIG_ADC_CONFIGURABLE_INPUTS)
    	.input_positive   = ADC_2ND_CHANNEL_INPUT,
    #endif
    };
    #endif /* defined(ADC_2ND_CHANNEL_ID) */
    
    static int16_t m_sample_buffer[BUFFER_SIZE];
    
    void adc_sample_event(struct k_timer *timer_id){
        int err;	
    
    		const struct adc_sequence sequence = {
    #if defined(ADC_2ND_CHANNEL_ID)
    		.channels    = BIT(ADC_1ST_CHANNEL_ID) |
    			       BIT(ADC_2ND_CHANNEL_ID),
    #else
    		.channels    = BIT(ADC_1ST_CHANNEL_ID),
    #endif /* defined(ADC_2ND_CHANNEL_ID) */
    		.buffer      = m_sample_buffer,
    		.buffer_size = sizeof(m_sample_buffer),
    		.resolution  = ADC_RESOLUTION,
    	};
    
    	err = adc_read(adc_dev, &sequence);
    	if (err) {
            printk("adc_read() failed with code %d\n", err);
    	}
    
    	printk("ADC raw value(s):");                
    	for (int i = 0; i < BUFFER_SIZE; i++) {
            printk(" %d", m_sample_buffer[i]);                
    	}
    	printk("\n");
    }
    
    void main(void)
    {
        int err;	
    
        //ADC setup
        adc_dev = DEVICE_DT_GET(ADC_DEVICE_NODE);
    	if (!adc_dev) {
            printk("device_get_binding ADC failed\n");
        } 
        
        err = adc_channel_setup(adc_dev, &m_1st_channel_cfg);
        if (err) {
    	    printk("Error in adc channel1 setup: %d\n", err);
    	}
    
    #if defined(ADC_2ND_CHANNEL_ID)
    	err = adc_channel_setup(adc_dev, &m_2nd_channel_cfg);
        if (err) {
    	    printk("Error in adc channel2 setup: %d\n", err);
    	}
    #endif /* defined(ADC_2ND_CHANNEL_ID) */
    
    	//Timer setup
        k_timer_init(&my_timer, adc_sample_event, NULL);
        k_timer_start(&my_timer, K_MSEC(TIMER_INTERVAL_MSEC), K_MSEC(TIMER_INTERVAL_MSEC));    
    }

    8117.prj.conf

    6064.adc.zip

    Best regards,
    Kenneth

Related