This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Simulataneous ADC sampling

Hello, I am trying to make adc sampling on two adc inputs at the same time. The adc example (simulataneous-adc-sampling-from-two-inputs) is not using IRQ handler and applying some delay, but I really want to sample them at the same time. Here is my code and I am checking with nRF-UART app, it seems like the code doesn't work properly. I am very bad at programming. Please help me figure out the problem.

static void adc_init(void)
{	
	/* Enable interrupt on ADC sample ready event*/		
	NRF_ADC->INTENSET = ADC_INTENSET_END_Msk;   
	sd_nvic_SetPriority(ADC_IRQn, NRF_APP_PRIORITY_LOW);  
	sd_nvic_EnableIRQ(ADC_IRQn);
	
	NRF_ADC->CONFIG	= (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos) /* Bits 17..16 : ADC external reference pin selection. */
									| (ADC_CONFIG_PSEL_AnalogInput2 << ADC_CONFIG_PSEL_Pos)					/*!< Use analog input 2 as analog input. */
									| (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos)							/*!< Use internal 1.2V bandgap voltage as reference for conversion. */
									| (ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) /*!< Analog input specified by PSEL with no prescaling used as input for the conversion. */
									| (ADC_CONFIG_RES_8bit << ADC_CONFIG_RES_Pos);									/*!< 8bit ADC resolution. */ 
	
	/* Enable ADC*/
	NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled;
	adc_result1 = NRF_ADC->RESULT;
	
}

static void adc_init2(void)
{	
	/* Enable interrupt on ADC sample ready event*/		
	NRF_ADC->INTENSET = ADC_INTENSET_END_Msk;   
	sd_nvic_SetPriority(ADC_IRQn, NRF_APP_PRIORITY_LOW);  
	sd_nvic_EnableIRQ(ADC_IRQn);
	
	NRF_ADC->CONFIG	= (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos) /* Bits 17..16 : ADC external reference pin selection. */
									| (ADC_CONFIG_PSEL_AnalogInput6 << ADC_CONFIG_PSEL_Pos)					/*!< Use analog input 2 as analog input. */
									| (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos)							/*!< Use internal 1.2V bandgap voltage as reference for conversion. */
									| (ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) /*!< Analog input specified by PSEL with no prescaling used as input for the conversion. */
									| (ADC_CONFIG_RES_8bit << ADC_CONFIG_RES_Pos);									/*!< 8bit ADC resolution. */ 
	
	/* Enable ADC*/
	NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled;
	adc_result2 = NRF_ADC->RESULT;
}

/* Interrupt handler for ADC data ready event */
void ADC_IRQHandler(void)
{
	uint8_t adc_result1;
	uint8_t adc_result2;
	
	/* Clear dataready event */
  NRF_ADC->EVENTS_END = 0;	

  /* Write ADC result both to the UART and over BLE */
//	adc_result = NRF_ADC->RESULT;
	app_uart_put(adc_result1);
	app_uart_put(adc_result2);
	ble_nus_send_string(&m_nus, &adc_result1, 1);
	ble_nus_send_string(&m_nus, &adc_result2, 1);
	nrf_gpio_pin_toggle(LED_3);        //indicate on LED that the ADC interrupt handler is executing
	
	//Use the STOP task to save current. Workaround for PAN_028 rev1.5 anomaly 1.
  NRF_ADC->TASKS_STOP = 1;
	
	//Release the external crystal
	sd_clock_hfclk_release();
}	
Parents Reply
  • Actual simultaneous ADC sampling is not possible. You will always have to sample one pin and then the other pin. In order to make it simultaneous, you would need two ADC peripherals, but the nRF51 only has one.

    The time difference between the two samples is approximately the duration of the sampling plus ~10us. It takes ~10us to enter the ADC interrupt handler, reconfigure the ADC and start the sampling on the second pin. For 8-bit sampling, the time difference would be 20+10=30us. For 10-bit sampling the time difference would be 68+10=78us

Children
No Data
Related