how to use ATMEGA2560 AD differential channel

hello guys!
I searched about this issue but didn't find any library! but we can use differential ADC by using registers. the code is here:

uint8_t low, high;

void setup() {
  Serial.begin(9600);
  ADMUX = 1<<REFS0;                //choose AVCC for reference ADC voltage
  ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);    //enable ADC, ADC frequency=16MB/128=125kHz (set of prescaler)
  ADCSRB = 0x00;
}

void loop() {
  Serial.println(read_differential());
  delay(100);
}

int16_t read_differential() {
  ADMUX |= (1<<MUX4);             //set MUX5:0 to 010000. Positive Differential Input => ADC0 and Negative Differential Input => ADC1 with Gain 1x. 
           
  ADCSRA |= (1<<ADSC);            //start conversion
  while (ADCSRA & (1<<ADSC));     //wait untill coversion be completed(ADSC=0);

  low = ADCL;
  high = ADCH;
  return (high << 8) | low;       //arrange (ADCH ADCL) to a 16 bit and return it's value.
}

this code can read differential ADC by A0(posetive) and A1(negetive) pins and show it on Serial Monitor. these registers are explained in the "ATmega 2560 datasheet". so you can change differential mode or differential with gain or single ended mode by changing MUX5:0 bits according to "table 26-4" at the datasheet.
But I see a problem! if we use differential mode or differential with gain, the out number is about 512(499 or 502) not 1023 :o ! but if use single ended mode the out number can be 1023.
Can any one tell me what's the problem??? :o I guess its because of its analog inner opamps. but not sure!

1 Like