Increase sampling frequency ... anything ihas changed

Hi,

I have used this program

const byte adcPin = 0;  // A0

const int MAX_RESULTS = 256;

volatile int results [MAX_RESULTS];
volatile int resultNumber;

// ADC complete ISR
ISR (ADC_vect)
{
if (resultNumber >= MAX_RESULTS)
  ADCSRA = 0;  // turn off ADC
else
  results [resultNumber++] = ADC;
}  // end of ADC_vect

EMPTY_INTERRUPT (TIMER1_COMPB_vect);

void setup ()
{
Serial.begin (115200);
Serial.println ();

// reset Timer 1
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
TCCR1B = bit (CS11) | bit (WGM12);  // CTC, prescaler of 8
TIMSK1 = bit (OCIE1B);  // WTF?
OCR1A = 39;    
OCR1B = 39;   // 20 uS - sampling frequency 50 kHz

ADCSRA =  bit (ADEN) | bit (ADIE) | bit (ADIF);   // turn ADC on, want interrupt on completion
ADCSRA |= bit (ADPS2);  // Prescaler of 16
ADMUX = bit (REFS0) | (adcPin & 7);
ADCSRB = bit (ADTS0) | bit (ADTS2);  // Timer/Counter1 Compare Match B
ADCSRA |= bit (ADATE);   // turn on automatic triggering

// wait for buffer to fill
while (resultNumber < MAX_RESULTS)
  { }
  
for (int i = 0; i < MAX_RESULTS; i++)
  Serial.println (results [i]);

}  // end of setup

void loop () { }

to take datas from a sine wave with a fixed amplitude, freq. I have changed OCR1B to change the sampling frequency and i have observed strange thing.

For OCRA1B = 39

49
166
286
335
286
166
44
0
44
165
286
335
286
166
45
0
44
165
286
334
286
165
44
0

for OCRA1B= 79

50
231
322
99
9
230
322
99
9
231
321
99
8
231
322
99
9
231
321
99

and this is what i expect (to find less points)

but for OCR1B= 19 i continue finding this:

49
166
286
335
286
166
44
0
44
165
286
335
286
166
45
0
44
165
286
334
286
165
44
0

Why? Is it possible that there is a max sampling frequency and with OCRA1B= 19 i have overcame it?

Please edit your post to add code tags ("</>" editor button). Additional instructions in “How to use this forum”.

The ADC is clock driven at a frequency selected by you. If you try to read the result before the ADC has finished a conversion, then you can expect nonsense. Good tutorial here.

The ADC does have a maximum conversion rate and its interrupt service routine is called only when the conversion is complete, so your results are not surprising.
You can speed up the conversion rate by changing the prescaler value but you lose some accuracy. See the data sheet for your particular MCU to get the maximum conversion rate at your desired resolution.

Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html . Then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Is this associated with this thread?

https://forum.arduino.cc/index.php?topic=624295.0

If you are trying to just measure frequency, then there are other methods.

google arduino frequency measurement

Thanks.. Tom.. :slight_smile:

6v6gt:
The ADC does have a maximum conversion rate and its interrupt service routine is called only when the conversion is complete, so your results are not surprising.
You can speed up the conversion rate by changing the prescaler value but you lose some accuracy. See the data sheet for your particular MCU to get the maximum conversion rate at your desired resolution.

Hi, Thanks I know that i have an Arduino UNO with a "Armega328P" processor.

I know that ADC takes 13 adc clock cycles and it has a 16 MHz clock cycle, i know the freq. that in my program should be around 50 kHz (16 MHz /(8*39)) so can we derive the MCU from these features?

Moreover I have some doubts about the program

TCCR1B = bit (CS11) | bit (WGM12);  // CTC, prescaler of 8
TIMSK1 = bit (OCIE1B);  // WTF?
OCR1A = 39;    
OCR1B = 39;   // 20 uS - sampling frequency 50 kHz

ADCSRA =  bit (ADEN) | bit (ADIE) | bit (ADIF);   // turn ADC on, want interrupt on completion
ADCSRA |= bit (ADPS2);  // Prescaler of 16

We have two prescaler. In the first part we can modify the sampling frequency. Infact 50 kHz= 16 MHz /(8*39). In the second part which frequency do we modify? The adc clock frequency?

Update: Yes the ADC clock frequency is 16 MHz /(13*16)= 76 kHz for our case. So if we modify the sampling frequency to 100 kHz we overcome that frequency, and we will be stuck at 76 kHz, is this correct? Now the question is, whe should see more points however, why do we see Always the same point?

The ADC cannot collect data faster than the ADC sampling rate.

Do your homework to determine what the program you blindly copied from somewhere else sets that rate to be.

Hi,
What exactly are you trying to achieve?
What do you want to measure?
Frequency?
Amplitude?
What is the shape of the signal?
Where is it coming from?

Thanks.. Tom.. :slight_smile:

. . . and what resolution (accuracy) do you need ? 10 bit ? Only 8 bit ?
If the built-in adc does not have the necessary performance, you can try an external adc e.g. AD7219 which can sample at 1MHz. The limiting factor is then likely to be the SPI bus speed.