Here's another differential ADC code for the Teensy and Teensy++:
Code:
#define MUX_1V1 0b011110 // works for both
#define ADMUX_MASK 0b11111 // MUX4..0 in ADMUX works for both
#define ADSCRB_MUXMASK (1<MUX5) // MUX5 in
#define AREF_VCC (1<<REFS0)
#define AREF_2V56 ((1<<REFS0) | (1<<REFS1))
#define AREF_AREF 0
#define TENBIT_1V1_MV ((long)(1023L * 1000 * 1.1))
int analogReadMux(int aref,int mux,int twosComp=0){
// Read ADC based on an ADMUX setting
// teensy++ or at90usb1286-specific
int low,result;
#if defined(__AVR_AT90USB1286__) // Teensy ++ 2.0
ADMUX = aref | (mux & ADMUX_MASK);
#elif defined (__AVR_ATmega32U4__) // Teensy 2.0
ADMUX = aref | (mux & ADMUX_MASK);
ADCSRB = (ADCSRB & ~(1<<MUX5)) | (mux & (1<<MUX5));
#else
#error "analogReadMux defined only for Teensy 2.0 or Teensy++ 2.0"
#endif
delay(2);
ADCSRA |= (1<<ADSC);
while (ADCSRA & (1<<ADSC)) ;
low = ADCL;
result =(ADCH<<8)|low;
if (twosComp and result >= 0x200) result -= 0x3ff;
return result;
}
long readVcc() {
long result;
result= analogReadMux(AREF_VCC, MUX_1V1,0);
result = TENBIT_1V1_MV / result; // Back-calculate AVcc in mV
return result;
}
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.print("Vcc: ");
Serial.print( 1.0*readVcc()/1000, 3 );
#if defined (__AVR_ATmega32U4__)
Serial.print("V Temp: ");
Serial.print((analogReadMux(AREF_2V56,0b100111,0)-273),DEC);
Serial.print("C ");
#endif
Serial.print(" 1.1/2.56: ");
Serial.print(2.56*(analogReadMux(AREF_2V56,MUX_1V1,0)/1023.),3);
Serial.print(" 0V(GND)/2.56: ");
Serial.print(2.56*(analogReadMux(AREF_2V56,0b011111,0)/1023.),3);
Serial.print("V");
Serial.print(" 0V(GND)/2.56: ");
Serial.print(2.56*(analogReadMux(AREF_2V56,0b011111,0)/1023.),3);
Serial.print("V");
Serial.print(" ADC1-ADC0 x1: ");
Serial.print(2.56*(analogReadMux(AREF_2V56,0b010000,1)/512.0),3);
Serial.print("V");
Serial.print(" ADC1-ADC0 x10: ");
Serial.print(2.56*(analogReadMux(AREF_2V56,0b001001,1)/512.0/10),6);
Serial.print("V");
#if defined (__AVR_ATmega32U4__)
Serial.print(" ADC1-ADC0 x40: ");
Serial.print(2.56*(analogReadMux(AREF_2V56,0b100110,1)/512.0/40),6);
Serial.print("V");
#endif
Serial.print(" ADC0-ADC1 x200: ");
Serial.print(2.56*(analogReadMux(AREF_2V56,0b001011,1)/512.0/200),6);
Serial.print("V");
Serial.println("");
delay(1000);
}
Some output from my Teensy 2.0, with a jumper between A0 and A1:
Code:
Vcc: 5.046V Temp: 43C 1.1/2.56: 1.111 0V(GND)/2.56: 0.003V 0V(GND)/2.56: 0.003V ADC1-ADC0 x1: 0.020V ADC1-ADC0 x10: 0.002500V ADC1-ADC0 x40: 0.000500V ADC0-ADC1 x200: 0.000050V
Vcc: 5.068V Temp: 43C 1.1/2.56: 1.111 0V(GND)/2.56: 0.003V 0V(GND)/2.56: 0.003V ADC1-ADC0 x1: 0.020V ADC1-ADC0 x10: 0.002000V ADC1-ADC0 x40: 0.000375V ADC0-ADC1 x200: 0.000000V
Vcc: 5.068V Temp: 42C 1.1/2.56: 1.111 0V(GND)/2.56: 0.003V 0V(GND)/2.56: 0.003V ADC1-ADC0 x1: 0.020V ADC1-ADC0 x10: 0.003000V ADC1-ADC0 x40: 0.000375V ADC0-ADC1 x200: 0.000050V
Vcc: 5.068V Temp: 42C 1.1/2.56: 1.111 0V(GND)/2.56: 0.003V 0V(GND)/2.56: 0.005V ADC1-ADC0 x1: 0.025V ADC1-ADC0 x10: 0.002000V ADC1-ADC0 x40: 0.000375V ADC0-ADC1 x200: 0.000150V
Vcc: 5.068V Temp: 43C 1.1/2.56: 1.111 0V(GND)/2.56: 0.003V 0V(GND)/2.56: 0.003V ADC1-ADC0 x1: 0.020V ADC1-ADC0 x10: 0.001500V ADC1-ADC0 x40: 0.000500V ADC0-ADC1 x200: 0.000100V
Vcc: 5.068V Temp: 43C 1.1/2.56: 1.111 0V(GND)/2.56: 0.003V 0V(GND)/2.56: 0.003V ADC1-ADC0 x1: 0.020V ADC1-ADC0 x10: 0.002500V ADC1-ADC0 x40: 0.000625V ADC0-ADC1 x200: 0.000050V
Vcc: 5.068V Temp: 43C 1.1/2.56: 1.111 0V(GND)/2.56: 0.003V 0V(GND)/2.56: 0.003V ADC1-ADC0 x1: 0.020V ADC1-ADC0 x10: 0.002000V ADC1-ADC0 x40: 0.000500V ADC0-ADC1 x200: 0.000000V
Vcc: 5.068V Temp: 42C 1.1/2.56: 1.111 0V(GND)/2.56: 0.005V 0V(GND)/2.56: 0.003V ADC1-ADC0 x1: 0.015V ADC1-ADC0 x10: 0.002500V ADC1-ADC0 x40: 0.000500V ADC0-ADC1 x200: 0.000000V
Vcc: 5.068V Temp: 43C 1.1/2.56: 1.111 0V(GND)/2.56: 0.005V 0V(GND)/2.56: 0.003V ADC1-ADC0 x1: 0.020V ADC1-ADC0 x10: 0.002000V ADC1-ADC0 x40: 0.000500V ADC0-ADC1 x200: 0.000000V
Vcc: 5.068V Temp: 43C 1.1/2.56: 1.111 0V(GND)/2.56: 0.003V 0V(GND)/2.56: 0.003V ADC1-ADC0 x1: 0.025V ADC1-ADC0 x10: 0.002500V ADC1-ADC0 x40: 0.000625V ADC0-ADC1 x200: 0.000000V
Vcc: 5.068V Temp: 43C 1.1/2.56: 1.114 0V(GND)/2.56: 0.005V 0V(GND)/2.56: 0.003V ADC1-ADC0 x1: 0.025V ADC1-ADC0 x10: 0.002500V ADC1-ADC0 x40: 0.000375V ADC0-ADC1 x200: 0.000175V
Vcc: 5.068V Temp: 43C 1.1/2.56: 1.114 0V(GND)/2.56: 0.003V 0V(GND)/2.56: 0.003V ADC1-ADC0 x1: 0.020V ADC1-ADC0 x10: 0.002000V ADC1-ADC0 x40: 0.000500V ADC0-ADC1 x200: -0.000050V
Vcc: 5.068V Temp: 43C 1.1/2.56: 1.111 0V(GND)/2.56: 0.003V 0V(GND)/2.56: 0.003V ADC1-ADC0 x1: 0.020V ADC1-ADC0 x10: 0.002000V ADC1-ADC0 x40: 0.000375V ADC0-ADC1 x200: -0.000025V
Vcc: 5.068V Temp: 43C 1.1/2.56: 1.114 0V(GND)/2.56: 0.003V 0V(GND)/2.56: 0.003V ADC1-ADC0 x1: 0.020V ADC1-ADC0 x10: 0.002000V ADC1-ADC0 x40: 0.000625V ADC0-ADC1 x200: 0.000075V
Vcc: 5.068V Temp: 43C 1.1/2.56: 1.111 0V(GND)/2.56: 0.003V 0V(GND)/2.56: 0.003V ADC1-ADC0 x1: 0.025V ADC1-ADC0 x10: 0.002500V ADC1-ADC0 x40: 0.000500V ADC0-ADC1 x200: 0.000000V
Vcc: 5.068V Temp: 43C 1.1/2.56: 1.111 0V(GND)/2.56: 0.003V 0V(GND)/2.56: 0.003V ADC1-ADC0 x1: 0.020V ADC1-ADC0 x10: 0.002000V ADC1-ADC0 x40: 0.000375V ADC0-ADC1 x200: 0.000075V
Looks like there's some calibration issues between the different amplifications.
With a Teensy++'s at90usb1286 chip, the 1V1 bandgap, and differential A0:A1 x1, x10 and x200 MUX[4..0] codes are the same, but there isn't a temperature sensor nor the x40 gain. I've added some #ifdefs, and tested it on a Teensy++ 2.0:
Code:
Vcc: 4.957 1.1/2.56: 1.096 0V(GND)/2.56: 0.003V 0V(GND)/2.56: 0.003V ADC1-ADC0 x1: 0.045V ADC1-ADC0 x10: 0.003000V ADC0-ADC1 x200: 0.000125V
Vcc: 4.979 1.1/2.56: 1.096 0V(GND)/2.56: 0.003V 0V(GND)/2.56: 0.003V ADC1-ADC0 x1: 0.035V ADC1-ADC0 x10: 0.004000V ADC0-ADC1 x200: 0.000125V
Vcc: 4.979 1.1/2.56: 1.096 0V(GND)/2.56: 0.003V 0V(GND)/2.56: 0.003V ADC1-ADC0 x1: 0.040V ADC1-ADC0 x10: 0.003500V ADC0-ADC1 x200: 0.000075V
Vcc: 4.979 1.1/2.56: 1.096 0V(GND)/2.56: 0.003V 0V(GND)/2.56: 0.003V ADC1-ADC0 x1: 0.035V ADC1-ADC0 x10: 0.003000V ADC0-ADC1 x200: 0.000000V
Vcc: 4.957 1.1/2.56: 1.096 0V(GND)/2.56: 0.003V 0V(GND)/2.56: 0.000V ADC1-ADC0 x1: 0.035V ADC1-ADC0 x10: 0.003500V ADC0-ADC1 x200: 0.000075V
Vcc: 4.979 1.1/2.56: 1.096 0V(GND)/2.56: 0.003V 0V(GND)/2.56: 0.003V ADC1-ADC0 x1: 0.035V ADC1-ADC0 x10: 0.004000V ADC0-ADC1 x200: 0.000100V