Hi,
I have been playing around with the nRF9160 DK trying to get it reading a range of sensors, so far with success, however I have found an issue which has stumped me. I am using ADC0 to read a voltage. Although this is intended for a pressure transducer, for debugging I have just put the 5V out through a resistive divider (10K / 10K) and the ADC successfully reads 2.5V.
However, when the program is first run, the very first ADC reading is around 50. The next one, and all instances after, it reads correctly (around 3500 - using 3V VDD as reference and gain of 1/4, 12-bit resolution).
I assumed this may be due to acquisition time, but I tried a few different values and nothing helped.
I wont post the full code, but here is the config and read code
#define ADC_RESOLUTION 12 #define ADC_GAIN ADC_GAIN_1_4 #define ADC_REFERENCE ADC_REF_VDD_1_4 #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_AIN0 #define BUFFER_SIZE 1 static uint16_t m_sample_buffer[BUFFER_SIZE]; static struct adc_channel_cfg channel_cfg = { .gain = ADC_GAIN, .reference = ADC_REFERENCE, .acquisition_time = ADC_ACQUISITION_TIME, .differential = 0, .channel_id = ADC_1ST_CHANNEL_INPUT , .input_positive = SAADC_CH_PSELP_PSELP_AnalogInput0, }; static int adc_sample(void) { int ret; struct adc_sequence sequence = { .channels = BIT(channel_cfg.channel_id), .buffer = &m_sample_buffer, .buffer_size = sizeof(m_sample_buffer), .resolution = ADC_RESOLUTION, }; if (!adc_dev) { return -1; } ret = adc_read(adc_dev, &sequence); if (ret) { printk("adc_read() failed with code %d\n", ret); } for (int i = 0; i < BUFFER_SIZE; i++) { printk("ADC raw value: %d\n", m_sample_buffer[i]); uint32_t mV = (m_sample_buffer[i] *1000)*3/4096; //n*1000*Reference (3V) / 12bit adc printk("ADC mV after Divider: %u\n", mV); mV = mV *2; printk("Voltage Sensed: %u\n", mV); } return ret; } //WITHIN MAIN adc_dev = device_get_binding("ADC_0"); if (!adc_dev) { printk("device_get_binding ADC_0 failed\n"); } NRF_SAADC_NS->TASKS_CALIBRATEOFFSET=1; err = adc_channel_setup(adc_dev, &channel_cfg); if (err) { printk("Error in adc setup: %d\n", err); } //END
The adc_sample() function is called when button 1 is pressed, but I'm sure that shouldnt make a difference.
Thanks,
Damien