jremington
Member
I would like to sample a single ADC channel at a constant frequency of about 100 kHz and began with the adc_pdb example.
I've simplified the example code as well as I understand it, and it seems to work reasonably well. Monitoring the LED pin using my old 100 MHz analog scope shows that the adc isr is activated at the correct frequency but with occasional surprisingly large jitter of +/- 2 usec. The jitter gets worse if I print the values in loop (unsurprisingly).
I would appreciate suggestions to remove the jitter, or an explanation! Code follows.
Additional questions:
Are my choices of sample and conversion rates appropriate? The voltage source is low (~100 Ohms) impedance.
In the stock adc_pdb example code, why is the ADC value read in loop(), but read and ignored in the adc isr?
Thanks!
I've simplified the example code as well as I understand it, and it seems to work reasonably well. Monitoring the LED pin using my old 100 MHz analog scope shows that the adc isr is activated at the correct frequency but with occasional surprisingly large jitter of +/- 2 usec. The jitter gets worse if I print the values in loop (unsurprisingly).
I would appreciate suggestions to remove the jitter, or an explanation! Code follows.
Additional questions:
Are my choices of sample and conversion rates appropriate? The voltage source is low (~100 Ohms) impedance.
In the stock adc_pdb example code, why is the ADC value read in loop(), but read and ignored in the adc isr?
Thanks!
Code:
#include <ADC.h>
// based on adc_pdb example
const int readPin = A9; // ADC0
ADC *adc = new ADC(); // adc object;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
pinMode(readPin, INPUT);
Serial.begin(115200);
while (!Serial);
Serial.println("Begin setup");
///// ADC0 ////
adc->setAveraging(0); // set number of averages
adc->setResolution(12); // set bits of resolution
adc->setConversionSpeed(ADC_CONVERSION_SPEED::VERY_HIGH_SPEED); // change the conversion speed
adc->setSamplingSpeed(ADC_SAMPLING_SPEED::VERY_HIGH_SPEED); // change the sampling speed
int freq = 100000;
Serial.print("Start pdb with frequency ");
Serial.print(freq);
Serial.println(" Hz.");
adc->adc0->stopPDB();
adc->adc0->startSingleRead(readPin); // call this to setup everything before the pdb starts, differential is also possible
adc->enableInterrupts(ADC_0);
adc->adc0->startPDB(freq); //frequency in Hz
// Print errors, if any.
adc->printError();
adc->resetError();
}
volatile uint16_t value;
volatile uint8_t new_val = 0;
volatile uint8_t led_stat = 0;
void loop() {
if (new_val) {
new_val = 0;
// Serial.println(value);
// digitalWriteFast(LED_BUILTIN, (led_stat = !led_stat));
}
}
// Make sure to call readSingle() to clear the interrupt.
void adc0_isr() {
value = (uint16_t) adc->adc0->readSingle();
//adc->adc0->readSingle();
new_val = 1;
digitalWriteFast(LED_BUILTIN, (led_stat = !led_stat));
}
// pdb interrupt is enabled in case you need it.
void pdb_isr(void) {
PDB0_SC &= ~PDB_SC_PDBIF; // clear interrupt
// digitalWriteFast(LED_BUILTIN, (led_stat = !led_stat));
}
Last edited: