-
Notifications
You must be signed in to change notification settings - Fork 4
Description
AdvancedADC
gives you two options for capturing two analog signals simultaneously. The first is to bind both analog input pins to the same AdvancedADC
instance. This works great, but sadly, means your sample rate is cut in half. The sample_rate
provided applies to the sampling of both inputs. So a 1M Samp./sec rate really means each is sampled at 500K Samp./sec. If you trying to push the limits of sample rate, this is not a great solution.
The second way is to bind each analog input to a different AdvancedADC
. The library will automatically assign the two pins to two different ADC blocks. The sample rate of each will be maximum. Very nice. However, this creates another problem. The begin()
routine takes approximately 100 us on GIGA R1 to initialize and start the ADC capture. So if I say something like:
adc_input[0].load(res, sample_rate, num_samples, QUEUE_DEPTH,1,&(probes[0]));
adc_input[1].load(res, sample_rate, num_samples, QUEUE_DEPTH,1,&(probes[1])));
What happens is that the second ADC input capture is delayed by about 100us. So the two signals are not synchronized. If you're trying to capture two signals with reasonable synchronization, that is not going to work. I analyzed the timing of each line of code in the begin()
routine and found that two lines are causing almost all the delay:
Arduino_AdvancedAnalog/src/AdvancedADC.cpp
Line 187 in f7d081c
descr->pool = new DMABufferPool<Sample>(n_samples, n_channels, n_buffers); |
and
Arduino_AdvancedAnalog/src/AdvancedADC.cpp
Lines 200 to 202 in f7d081c
if (hal_adc_config(&descr->adc, ADC_RES_LUT[resolution], descr->tim_trig, adc_pins, n_channels) < 0) { | |
return 0; | |
} |
I have a solution. I created two new routines in AdvancedADC.cpp
I call load()
and fire()
.
load()
is identical to the begin()
routine up to a point, including the long-delay lines above. It then returns. Essentially load()
allocates the DMA and ADC etc, but does not start the capture. The fire()
routine (which only takes about 4 us) does the rest of
what was in begin()
and starts the capture. This is working and providing a synchronization error of about 4-6 us. Not bad.
This is probably NOT the solution that someone else would prefer, but it works for me. Now I have full sample-rate and okay synchronization between two or three analog inputs.
I guess I would say the issue I have is that begin()
takes too long (106 us!). Either this needs to be shortened significantly or the idea of the load()
and fire()
would also work.