bungernaut
Member
I am trying to maximize the ADC performance in my application on a Teensy 4.0. It is not going to be much more complex than the attached code. To test this I'm using another Teensy to send a pulse 50us wide every 2 seconds, I verified with a oscilloscope this is 50.54us wide. I am able to measure ~17 high ADC values with this code, suggesting a 0.34 MHz ADC rate. This seems a little bit slower than I would have expected, but I also cannot find specs on the ADC in the teensy 4.0.
If there is a way to get >0.5MHz or more out of the ADC I would be pretty happy. My fiddling around suggests the bottle neck is the ADC waiting at the isComplete() step. If I change the while(!isComplete()) to a if/else to count the number of times loop is run between isComplete, it's 18 loops.
If there is a way to get >0.5MHz or more out of the ADC I would be pretty happy. My fiddling around suggests the bottle neck is the ADC waiting at the isComplete() step. If I change the while(!isComplete()) to a if/else to count the number of times loop is run between isComplete, it's 18 loops.
Code:
#include <ADC.h>
#include <ADC_util.h>
#include <CircularBuffer.h>
const int readPin = A9; // ADC0
ADC *adc = new ADC(); // adc object
uint32_t currTime = 0;
uint32_t sample_count = 0;
uint16_t val = 0;
const int nsamples = 2000;
CircularBuffer<uint16_t, nsamples> wf_buffer;
CircularBuffer<uint16_t, nsamples> ts_buffer;
const int pre_sample = 50;
const int post_sample = (nsamples - pre_sample);
int trigger = 0; // 0 if not triggered, otherwise samples since trigger
const int threshold = 500;
uint32_t num_triggers = 0;
uint32_t checksum = 0;
uint32_t uptime;
void setup() {
Serial.begin(250000);
adc->adc0->setReference(ADC_REFERENCE::REF_3V3);
adc->adc0->setResolution(12);
adc->adc0->setConversionSpeed(ADC_CONVERSION_SPEED::VERY_HIGH_SPEED);
adc->adc0->setSamplingSpeed(ADC_SAMPLING_SPEED::VERY_HIGH_SPEED);
adc->adc0->startContinuous(readPin);
Serial.println("Begin...");
}
void loop() {
currTime = micros();
while(!adc->adc0->isComplete());
val = adc->adc0->analogReadContinuous();
wf_buffer.push(val);
ts_buffer.push(currTime);
if ((val > threshold) & (trigger == 0)) {
trigger += 1;
}
else if (trigger == post_sample) {
// write out the WF to the serial
sendData();
// reset trigger
trigger = 0;
}
else if (trigger > 0) {
// increment trigger until we get to the desired length
trigger += 1;
}
}
void sendData()
{
Serial.print("Waveform Start ");
Serial.println(millis());
checksum = 0;
for (int i = 0; i < 1000; i++) {
checksum += wf_buffer[i];
Serial.print(ts_buffer[i]);
Serial.print(",");
Serial.println(wf_buffer[i]);
}
Serial.print("Checksum ");
Serial.println(checksum);
Serial.print("Waveform End ");
Serial.println(millis());
Serial.println("ZZZ");
delay(10);
}