Hi everybody
I'm trying to implement a reading on a nRF5340 an ADC to sample a sensor every 1ms, pack datas and send them over NUS to a central.
I'm using NCS 2.1.0 and Zephyr ADC API
The problem is how to implement a reading of ADC in a faster way... What I implement until now is this:
An init function, to setup ADC (channels are defined into devTree, this code has been taken from an example)
and set up timers........
struct adc_sequence sequence = {
/* individual channels will be added below */
.channels = 0,
.buffer = &sample_buffer,
/* buffer size in bytes, not number of samples */
.buffer_size = sizeof(sample_buffer),
.resolution = ADC_RESOLUTION,
.calibrate = true,
.options = &adcOptions,
};
/****************************************************************/
static void AppFuncInput_AnalogIn(void)
{
m_pAdcDevice = DEVICE_DT_GET(ADC_NODE);
if (!device_is_ready(m_pAdcDevice))
{
LOG_ERROR("ADC device not found\n");
return ERR_INVALID_PARAM;
}
/*
* Configure channels individually prior to sampling
*/
for (uint8_t i = 0; i < ADC_NUM_CHANNELS; i++)
{
channel_cfg.channel_id = channel_ids[i];
LOG_INFO("Configured ADC%d", channel_ids[i]);
#ifdef CONFIG_ADC_NRFX_SAADC
channel_cfg.input_positive = SAADC_CH_PSELP_PSELP_AnalogInput0 + channel_ids[i];
#endif
adc_channel_setup(m_pAdcDevice, &channel_cfg);
sequence.channels |= BIT(channel_ids[i]);
}
m_adcVref = adc_ref_internal(m_pAdcDevice);
/* Initialize a Timer to run the first time after 10s and then every 1ms */
k_timer_init(&sFunctionTimer, AppFuncInput_AnalogIn, NULL);
k_timer_start(&sFunctionTimer, K_MSEC(10000), K_MSEC(1));
/*
.....
*/
}
Then, the callback function to read the ADC is this:
static void AppFuncInput_AnalogIn(void)
{
int16_t err = NO_ERROR; ///< return code for the function
/* Read sequence of channels (fails if not supported by MCU) */
err = adc_read(m_pAdcDevice, &sequence);
if (err != 0)
{
LOG_ERROR("ADC reading failed with error %d.\n", err);
return err;
}
/* if there's an extra sample number please insert these values into filter calculation */
for (uint8_t jj = 0; jj <= ADC_EXTRASAMPLE_NUMBER; jj += ADC_NUM_CHANNELS)
{
for (uint8_t i = 0; i < ADC_NUM_CHANNELS; i++)
{
calculateMean(&m_analogInputFlt[i], sample_buffer[i + jj]);
/*
....
*/
}
};
AppFuncInput_HandleBleSendingData();
};
Now, if I use the
I put a k_msleep(1) but it depends on execution timing of the function...... That's why I introduced the K_Timer element.
ASSERTION FAIL [((arch_is_in_isr() == 0) || ((timeout).ticks == (((k_timeout_t) {0})).ticks))] @ WEST_TOPDIR/zephyr/kernel/sem.c:121Is there a more simple method to get data every 1ms from an ADC and then send it to BLE Nus central?
Thank you !