Hello, I'm using nRF51822-mKIT for a research.
I recently posted a question related to "reading ADC value from analog input", having issues with reading proper ADC value from input pin. However, after narrowing down, I have found out that the root cause was that I tried to read ADC values simultaneously from multiple pins.
The following is the code that I have right now:
static void rr_interval_timeout_handler(void * p_context) {
UNUSED_PARAMETER(p_context);
if (m_rr_interval_enabled) {
/*!<AIn2 corrosponds to Vgas>*/
/*!<AIn4 corrosponds to Vref>*/
data[2] = (uint16_t) adc_read(ADC_CONFIG_PSEL_AnalogInput6); /*!<AIn6 corrosponds to Vtemp>*/
}
}
unsigned short adc_read(unsigned int adc_in_mask)
{
uint16_t adc_result;
// interrupt ADC
NRF_ADC->INTENSET = (ADC_INTENSET_END_Disabled << ADC_INTENSET_END_Pos); /*!< Interrupt enabled. */
// config ADC
NRF_ADC->CONFIG = (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos) /* Bits 17..16 : ADC external reference pin selection. */
| (adc_in_mask << ADC_CONFIG_PSEL_Pos) /*!< Use analog input 0 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_10bit << ADC_CONFIG_RES_Pos); /*!< 10bit ADC resolution. */
// enable ADC
NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled; /* Bit 0 : ADC enable. */
// start ADC conversion
NRF_ADC->TASKS_START = 1;
// wait for conversion to end
while (!NRF_ADC->EVENTS_END)
{}
NRF_ADC->EVENTS_END = 0;
adc_result = ADC_RESULT_IN_MILLI_VOLTS(NRF_ADC->RESULT);
//Use the STOP task to save current. Workaround for PAN_028 rev1.1 anomaly 1.
NRF_ADC->TASKS_STOP = 1;
return adc_result;
}
You can see that I am currently collecting an ADC value from AnalogInput6 only. What I want to have is a code that collects ADC values from AnalogInput2 and AnalogInput4 as well in a very short interval (simultaneously if possible).
The bottom code is the one that I tried and failed to get correct ADC values:
static void rr_interval_timeout_handler(void * p_context) {
UNUSED_PARAMETER(p_context);
if (m_rr_interval_enabled) {
data[0] = (uint16_t) adc_read(ADC_CONFIG_PSEL_AnalogInput2); /*!<AIn2 corrosponds to Vgas>*/
data[1] = (uint16_t) adc_read(ADC_CONFIG_PSEL_AnalogInput4); /*!<AIn4 corrosponds to Vref>*/
data[2] = (uint16_t) adc_read(ADC_CONFIG_PSEL_AnalogInput6); /*!<AIn6 corrosponds to Vtemp>*/
}
}
Is there any way that I could read ADC values from multiple pins? Thank you in advance.
=====SOLUTION=====
Thanks to Stefan, I got a working code! Hope this helps to people who were having similar problem. I have modified my code to collect ADC values from each pin sequentially, using a counter.
uint8_t count = 0;
static void rr_interval_timeout_handler(void * p_context)
{
UNUSED_PARAMETER(p_context);
if (m_rr_interval_enabled)
{
if(count == 0) {
data[0] = (uint16_t) adc_read(ADC_CONFIG_PSEL_AnalogInput2); /*!<AIn2 corrosponds to Vgas>*/
} else if(count == 1) {
data[1] = (uint16_t) adc_read(ADC_CONFIG_PSEL_AnalogInput4); /*!<AIn4 corrosponds to Vref>*/
} else if(count == 2) {
data[2] = (uint16_t) adc_read(ADC_CONFIG_PSEL_AnalogInput6); /*!<AIn6 corrosponds to Vtemp>*/
}
}
}
static void heart_rate_meas_timeout_handler(void * p_context)
{
uint32_t err_code;
UNUSED_PARAMETER(p_context);
ble_hrs_rr_interval_add(&m_hrs, data[count]);
err_code = ble_hrs_heart_rate_measurement_send(&m_hrs, count);
count++;
if(count > 2) {
count = 0;
}
if ((err_code != NRF_SUCCESS) &&
(err_code != NRF_ERROR_INVALID_STATE) &&
(err_code != BLE_ERROR_NO_TX_BUFFERS) &&
(err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)
)
{
APP_ERROR_HANDLER(err_code);
}
}