Mega2560 - free running mode

I want to use the ADC 'A0' to read my analoge values. Therefore I tried the following code:

int numSamples=0;
long t, t0;

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

  ADCSRA = 0;             // clear ADCSRA register
  ADCSRB = 0;             // clear ADCSRB register
  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 Uno ADC clock is 16 MHz and a conversion takes 13 clock cycles
  //ADCSRA |= (1 << ADPS2) | (1 << ADPS0);    // 32 prescaler for 38.5 KHz
  ADCSRA |= (1 << ADPS2);                     // 16 prescaler for 76.9 KHz
  //ADCSRA |= (1 << ADPS1) | (1 << ADPS0);    // 8 prescaler for 153.8 KHz

  ADCSRA |= (1 << ADATE); // enable auto trigger
  ADCSRA |= (1 << ADIE);  // enable interrupts when measurement complete
  ADCSRA |= (1 << ADEN);  // enable ADC
  ADCSRA |= (1 << ADSC);  // start ADC measurements
}

ISR(ADC_vect)
{
  byte x = ADCH;  // read 8 bit value from ADC
  numSamples++;
}
  
void loop()
{
  if (numSamples>=1000)
  {
    t = micros()-t0;  // calculate elapsed time

    Serial.print("Sampling frequency: ");
    Serial.print((float)1000000/t);
    Serial.println(" KHz");
    delay(2000);
    
    // restart
    t0 = micros();
    numSamples=0;
  }
}

That code works fine, but I need to increase the accuracy to a range of 0...1023. I allways found a 8-bit solution. So my question is: how can i increase the accuracy to 10 bit, or is it limited by the 8-bit-databus, which is connected to the ADC-Data-Register?

Many Thanks..
Dave

Got it by myself...

Add this:

ISR(ADC_vect)
{
  x = ADCL | ADCH<<8;  // read 10 bit value from ADC
  
  numSamples++;
}

instead of:

 ISR(ADC_vect)
{
  byte x = ADCH;  // read 8 bit value from ADC
  numSamples++;
}

Will the

  ADMUX |= (1 << ADLAR);  // left align ADC value to 8 bits from ADCH register

not shift the whole result by 4 bit?

You should probably just drop that line (or clear that bit).

Sorry, i forgot to post this line... Yes, you need to change it into:

ADMUX |= (0 << ADLAR);

Thank you !

Dave

ADMUX |= (0 << ADLAR);

This is not correct, if you want to clear the bit you would have to write

ADMUX &= ~(1 << ADLAR);

One more thing that caught my eye

 ADMUX |= (0 & 0x07);    // set A0 analog input pin

This will not select A0, but because A0 was selected before (reset condition) it seems to work.

It has to be

 ADMUX &= ~7;    // set A0 analog input pin

to work, even if a different channel was selected before.

You should use

volatile int numSamples=0;

and loop should be (one variant)

void loop()
{
  noInterrupts();
  if (numSamples>=1000)
  {
    numSamples=0;
    interrupts();
    t = micros()-t0;  // calculate elapsed time

    Serial.print("Sampling frequency: ");
    Serial.print((float)1000000/t);
    Serial.println(" KHz");
    delay(2000);
   
    // restart
    t0 = micros();
  }
  interrupts();
}