Below (attached) are two plots from an Arduino Nano taking ADC readings.
1kHZ is a nice sine wave @ 1kHz
10kHz is ...
20kHz is ...
Both are about 3.5V peak to peak and come from a very low impedance source.
My ADC has been set to take samples @ 66kSa/s which is my conversion rate with an ADC clock of 1MHz. Each plot is 500 samples and on my Nano an ADC reading of 1024 = 4.72V as that is REF when the Nano is powered via USB. Clearly the first example works.
In the second, the sine wave frequency is approximately (sample rate) /3, which is above the Nyquist frequency. With Nyquist frequencies and aliasing effects I'm unable to satisfy myself that the thing's working correctly. I'm hoping it should be possible to confirm this from the graphs alone. My code is below anyway. Just take my word for it that I have timed a sample duration of 15uS. Not quite sure why this isn't 20uS as expected for a 1 MHz rate. (It reports 7520 mS for 500 samples.) I have used this code example.
Is my ADC working correctly @ 66kSa/s, and the weird 20kHz plot is just aliasing? I have little experience of sampling near the Nyquist frequency.
/*
Read adc as fast as possible using all the tricks.
*/
const int portNo = 7;
int const totalSamples = 500;
int buffer[totalSamples];
// Define various ADC prescaler
const unsigned char PS_16 = (1 << ADPS2);
const unsigned char PS_32 = (1 << ADPS2) | (1 << ADPS0);
const unsigned char PS_64 = (1 << ADPS2) | (1 << ADPS1);
const unsigned char PS_128 = (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
void setup() {
Serial.begin(9600);
pinMode(portNo, INPUT);
// set up the ADC
ADCSRA &= ~PS_128; // remove bits set by Arduino library
// you can choose a prescaler from above.
// PS_16, PS_32, PS_64 or PS_128
ADCSRA |= PS_16;
delay(1000);
}
void loop() {
unsigned long start_times = micros();
for (int i = 0; i < totalSamples; i ++) {
buffer[i] = analogRead(portNo);
}
unsigned long stop_times = micros();
// /*
for (int i = 0; i < totalSamples; i ++) {
Serial.println(buffer[i]);
}
// */
// Serial.println(stop_times - start_times);
delay(10000);
}