I want to set 25KHz ADC sampling rate using timer prescaler, ADC prescaler and timer top.
Here I'm attaching my code to check the sampling rate and getting 61KHz instead of 25KHz.
Please check anything wrong.
int numSamples=0;
long t, t0, sampletime;
volatile int analogValue;
void setup()
{
Serial.begin(2000000);
// // TCCR1A to 0 (no pwm), and initialise TCR1B to 0
TCCR1A = 0;
TCCR1B = 0;
ADCSRA = 0;
// TCCR1B = (0 << CS12)|(0<<CS11) | (1<<CS10);
TCCR1B |= 1;
// Set CTC Mode with TOP value set to be ICR1
TCCR1B |= (1 << WGM12);
TCCR1B |= (1 << WGM13);
// Set TOP value of timer1 to give desired frequency
ICR1 = 639;
ADMUX |= (0 & 0x07); // set A0 analog input pin
ADMUX |= (1 << REFS0); // set reference voltage
ADMUX |= (1 << ADLAR); // left align ADC value to 8 bits from ADCH register
// sampling rate is [ADC clock] / [prescaler] / [conversion clock cycles]
// for Arduino pro mini ADC clock is 16 MHz and a conversion takes 13 clock cycles
ADCSRA |= 4;
// Set the trigger source for adc trigger to timer1 compare match B
ADCSRB |= (1 << ADTS2);
ADCSRB &= ~(1 << ADTS1);
ADCSRB |= (1 << ADTS0);
}
ISR(ADC_vect)
{
byte x = ADCH; // read 8 bit value from ADC
numSamples++;
}
EMPTY_INTERRUPT (TIMER1_COMPB_vect);
void loop()
{
// Enable the ADC
ADCSRA |= (1 << ADEN);
// Set conversion bit to zero
ADCSRA |= (1 << ADSC);
// Set auto trigger of adc (adc will trigger on the selected signal, in this
// case timer1 reaching a certain value)
ADCSRA |= (1 << ADATE);
// Enable adc interrupts (this allows an interrupt to be called once the adc has
// finished a conversion
ADCSRA |= (1 << ADIE);
// Allow timer interrupts for timer1 B
TIMSK1 |= (1<<OCIE1B);
// Set timer value to 0
TCNT1 = 0;
if (numSamples>=1000)
{
t = micros()-t0; // calculate elapsed time
Serial.print("Sampling frequency: ");
Serial.print((float)1000000/t);
Serial.println(" KHz");
delay(20);
// restart
t0 = micros();
numSamples=0;
}
}