Guidance on precise ADC sampling frequency

doggy1

New member
Hi All,
I have a signal processing project running on a PIC processor. I would like to take advantage of the much higher Teensy speed to perform more advanced DSP processing. I have a few hopefully simple questions:

On the PIC I have a hardware timer with 125uSec period which automatically triggers an ADC 12bit read (or indeed several which can be hardware averaged). I transfer the readings to a buffer within an ISR and process them separately. I can fine tune the sampling interval in increments of 1usec "on the fly" in order to maintain synchronization with a FSK signal.

What is the best way to do this on a Teensy 4.0/4.1? Is there a feature for timer-triggered ADC readings where I can also fine tune the sampling frequency "on the fly"? I did read that you can trigger the ADC from an internal PWM output. I'm happy to process the ADC readings in an ISR. I just need the actual sampling rate to be precise (crystal controlled) plus have the ability to trim the sampling frequency up/down by small amounts.

Given the sampling is quite slow compared with many applications, I realise that I could take a timer interrupt and trigger the ADC reading from an ISR.

The PIC has good voltage ref facilities and I realise I will need to provide something better than the internal reference on Teensy.
 
Can I suggest a Hybrid approach. You have the PIC currently triggering and collecting data from the ADC(s). Could you not continue to do this and transfer the readings to the Teensy (on the fly?) for Advanced DSP Processing?
 
Thanks. I could do that but I'm hopeful that advanced timers will do what I want on the Teensy and they seem to have a 1uSec resolution and probab;ly allow me to change while running. So I'd have more interrupts than the PIC but the spped of the Teensy is much, much better.
 
The ADC library has several examples of timed ADC conversion. Those would be a good starting point.

EDIT: I tried the adc_timer example on a T4.1, and it worked nicely.

First, add these two lines shown below just above #ifdef ADC_USE_TIMER

Code:
#define ADC_USE_TIMER
#define ADC_DUAL_ADCS

The program should build and download to your T4.x. If you enter "s1000" <send>, you will configure the 2 x ADCs to sample at 1 kHz. Then type "t" <send> to do a timed read. The default buffer size if 500, so 500 samples at 1 kHz will run in 500 ms, and the program will print out the elapsed time (ms), min, max, and avg. You can increase the buffer size to collect more samples.

After 1 kHz, I tried 10 kHz, 100 kHz, and 500 kHz, and they all seemed to work correctly.
 
Last edited:
I have yet to check jitter and a few other things, but it seems to be working nicely as follows:
1. I'm using an IntervalTimer set for 125uSecs and seem to be able to change it "on the fly" 1usec at a time.
2. Upon the timer interrupt I am doing the ADC read using the medium speed which takes about 3usecs
3. I'm reading the data into an array.
4. I'm processing the array data, one value at a time, in the main loop. This involves (among other things) an orthogonal phase detector which involves a number of 32bit multiplies and accumulates. Here the Teensy shines because code that was taking 75uSecs on the PIC is taking 500nSecs on the Teensy! So it's looking like a good solution and will allow me to add extra processing.
 
Last edited:
Back
Top