I need to measure with SAADC two channels in the same time (NRF_SAADC_INPUT_AIN6 and NRF_SAADC_INPUT_AIN4).
Is possible ?
Have you an code example?
Thanks
Marco
I need to measure with SAADC two channels in the same time (NRF_SAADC_INPUT_AIN6 and NRF_SAADC_INPUT_AIN4).
Is possible ?
Have you an code example?
Thanks
Marco
Dear, all.
I have activated the second channel:
#define NRFX_SAADC_PULSE_CHANNEL_CONFIG_SE(PIN_P) \ { \ .resistor_p = NRF_SAADC_RESISTOR_DISABLED, \ .resistor_n = NRF_SAADC_RESISTOR_DISABLED, \ .gain = NRF_SAADC_GAIN1_6, \ .reference = NRF_SAADC_REFERENCE_INTERNAL, \ .acq_time = NRF_SAADC_ACQTIME_3US, \ .mode = NRF_SAADC_MODE_SINGLE_ENDED, \ .burst = NRF_SAADC_BURST_DISABLED, \ .pin_p = (nrf_saadc_input_t)(PIN_P), \ .pin_n = NRF_SAADC_INPUT_DISABLED \ } #define NRFX_SAADC_INEX_CHANNEL_CONFIG_SE(PIN_P) \ { \ .resistor_p = NRF_SAADC_RESISTOR_DISABLED, \ .resistor_n = NRF_SAADC_RESISTOR_DISABLED, \ .gain = NRF_SAADC_GAIN1_6, \ .reference = NRF_SAADC_REFERENCE_INTERNAL, \ .acq_time = NRF_SAADC_ACQTIME_3US, \ .mode = NRF_SAADC_MODE_SINGLE_ENDED, \ .burst = NRF_SAADC_BURST_DISABLED, \ .pin_p = (nrf_saadc_input_t)(PIN_P), \ .pin_n = NRF_SAADC_INPUT_DISABLED \ } nrf_saadc_channel_config_t channel_config_INEX = NRFX_SAADC_INEX_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN6); nrf_saadc_channel_config_t channel_config_PULSE = NRFX_SAADC_PULSE_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN4); void saadc_init(unsigned char type) { ret_code_t err_code; err_code = nrf_drv_saadc_init(NULL, saadc_PULSE_INEX_callback); APP_ERROR_CHECK(err_code); err_code = nrf_drv_saadc_channel_init(0, &channel_config_INEX); APP_ERROR_CHECK(err_code); err_code = nrf_drv_saadc_channel_init(1, &channel_config_PULSE); APP_ERROR_CHECK(err_code); err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool_scann[0], SAMPLES_IN_BUFFER_SCANN); APP_ERROR_CHECK(err_code); err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool_scann[1], SAMPLES_IN_BUFFER_SCANN); APP_ERROR_CHECK(err_code); }
seem work but sametime in the buffer I find the values exchanged between channels. WHY ?
this is my callback function:
void saadc_PULSE_INEX_callback(nrf_drv_saadc_evt_t const * p_event) { nrf_saadc_value_t adc_result; uint16_t value_mV_local; uint16_t value_mV_acc; int i; if (p_event->type == NRF_DRV_SAADC_EVT_DONE) { ret_code_t err_code; err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER_SCANN); APP_ERROR_CHECK(err_code); adc_result = p_event->data.done.p_buffer[0]; adc_value_inex = ADC_RESULT_IN_MILLI_VOLTS(adc_result);//+ DIODE_FWD_VOLT_DROP_MILLIVOLTS; adc_result = p_event->data.done.p_buffer[1]; adc_value_pulse = ADC_RESULT_IN_MILLI_VOLTS(adc_result);//+ DIODE_FWD_VOLT_DROP_MILLIVOLTS; } }
with this code I ask a start of new conversion
nrf_drv_saadc_sample();
while(!u_STATO10.STATO10_bit.mm_EOC);
the bit mm_EOC is for waiting the end of conversion. This is set in the callback with the event DONE.
Marco
I had forgotten to say:
#define SAMPLES_IN_BUFFER_SCANN 2
static nrf_saadc_value_t m_buffer_pool_scann[2][SAMPLES_IN_BUFFER_SCANN];
Marco
I had forgotten to say that the correct value (thai is 0 in this buffer) is located with same offset in the other buffer (of the other signal)
I have discovered now that when the data from ADC is swapped, this situation continues until I reset the system.
In previus immage I stopped the debug at the first 0. The other values after the 0 are old values on the buffer
ok. so the issue is that the adc is not triggered on every fall on the input pulse, is that maybe the case?
The issue may be that you don't have time for all interrupts. Either, they are too fast on it's own, or there is a possibility that you don't get the lpcomp interrupts (lpcomp_event_handler) in time, because the CPU is busy doing something else, such as handling one of the ADC events.
I suggest that you try to use PPI, like it is done in the example. It sets up a timer, and then uses the ppi to trigger the sampling on this event, rather than handling the timer interrupt using the CPU.
Dear Edvin,
the interrup is triggered on all fall edge. The LPCOM work perfectly and follow all edge.
The ADC in scann mod, on 2 channels, work but some times the data are swapped into the doubble buffer.
I have found other with my problem, see: https://devzone.nordicsemi.com/f/nordic-q-a/16885/saadc-scan-mode-sample-order-is-not-always-consistent
For now I have resolved using two call, each with only one channel ON.
err_code = nrf_drv_saadc_channel_init(0, &channel_config_PULSE); APP_ERROR_CHECK(err_code); nrfx_saadc_sample_convert(0, &value_1); adc_value_pulse = ADC_RESULT_IN_MILLI_VOLTS(value_1); // if (adc_value_pulse>35000) adc_value_pulse=0; err_code = nrf_drv_saadc_channel_uninit(0); APP_ERROR_CHECK(err_code); err_code = nrf_drv_saadc_channel_init(0, &channel_config_INEX); APP_ERROR_CHECK(err_code); nrfx_saadc_sample_convert(0, &value_2); adc_value_inex = ADC_RESULT_IN_MILLI_VOLTS(value_2); // if (adc_value_inex>35000) adc_value_inex=0; err_code = nrf_drv_saadc_channel_uninit(0); APP_ERROR_CHECK(err_code);
In this configuration all work good, also using 1 mS between two fall edge.
the above code use 55uS for both channels.
But this is not the correct solution. I hope to found the error in the scann mode configurations
Thanks
Marco
Hello,
Sorry. I forgot to mention that if you have two channels that are enabled, the scan function will scan both channels. I wasn't aware that you wanted to scan on different times based on two different input pulses.
The ticket that you link to is not entirely the same. We have seen similar cases when they use the internal SAADC timer to trigger samples, when they are sampling very fast, and have several channels.
If you want to measure on different times, you need to disable one channel at the time, like you do here.
How does that behave? I am still a bit confused about your description.
Marco Pennacchietti said:I had forgotten to say that the correct value (thai is 0 in this buffer) is located with same offset in the other buffer (of the other signal)
So how is your channels mixed up? Could you clarify?
Best regards,
Edvin
Hello,
Sorry. I forgot to mention that if you have two channels that are enabled, the scan function will scan both channels. I wasn't aware that you wanted to scan on different times based on two different input pulses.
The ticket that you link to is not entirely the same. We have seen similar cases when they use the internal SAADC timer to trigger samples, when they are sampling very fast, and have several channels.
If you want to measure on different times, you need to disable one channel at the time, like you do here.
How does that behave? I am still a bit confused about your description.
Marco Pennacchietti said:I had forgotten to say that the correct value (thai is 0 in this buffer) is located with same offset in the other buffer (of the other signal)
So how is your channels mixed up? Could you clarify?
Best regards,
Edvin
maybe I can't explain myself well.
The event of LPCOM is only on 1 signal.
When this event start I need to scan both signals in the same time.
In the buffer: static nrf_saadc_value_t m_buffer_pool_scann[2][2];
Normally I found in position 0 the first signal and in position 1 the second signal. And this is OK, all seem to work good.
Sometimes during the acquisition of the signals I find the values exchanged, so in position 0 the second signal and in position 1 the first signal. This situation continues and then every once in a while it is reversed.
I don't understand. Other people on the web complain about this problem
Marco
Hello Marco,
Ok. I think I understand. Does this happen when you disable and enable the different channels? I am sorry to ask the same questions over and over, but I try to think of why this may happen. I still don't think it is exactly the same as in the ticket that you link to, and I hope that it isn't, because there is really no good solution to that issue.
So the reason why you disable and enable the channels is that you want to measure on different times, is that correct? Or do you intend to measure them at the same time?
Because when you have two ADC channels, and you trigger the scan, it will scan both channels one after the other (because there is only one physical ADC on the chip).
What I suspect is happening is that you are triggering the scan via CPU interrupts, the interrupts are too fast for the CPU to handle all, so some of them are skipped. What I suggest is that you try to use the PPI to trigger the interrupts, which is more efficient, and you may not miss any of the events.
Now, the reason that the positions swap is that the buffer isn't aware of how many channels, or which channel the interrupts are coming from. This is not a problem if you only use one channel, but it is if you have more. If one sample is interrupted, it may happen that it scans twice on one channel, and then they will be swapped.
So: Do you disable/enable the channels? And have you tried triggering them via PPI? And do you need to measure at different points in time, or can you measure both channels at the same time?
Thank Edvin ! Difficult to find help in mid-August
Yes I need to measure both channels at the same time (AIN4 and AIN6)
If I enable only one channel all is perfect, if I anable 2 channel sometimes I have the swap.