I've been fiddling with the x1 X10 and X200 gain differential ADC on the Teensy++ and hooked it up to a Type K thermocouple. Here's my code so far:
It does jump around a bit, but it is still pretty cool:
Wtih a Teensy 2.0's internal temp sensor, I could correct for the cold junction temperature and have a large-range temp logger for pretty cheap.
For increased thermal resolution, I guess I could use a much smaller Vref and not do the x200 gain. If I divide 5VDC with a 47K:100 to make a 10.25mV AREF, I wouldn't need the internal gain, and maybe I could measure +/-250C with about 1/2C resolution and accuracy within a few degrees.
It doesn't look like Teensy 3.0 has programmable gain on the ADCs, so the small AREF might be a super-cheap option for reading a thermocouple.
Anyone using the gain functions? The differential ADCs? Or tiny AREFs?
Code:
/* SPICE-ish Connections:
USBcable Teensy2.0++ Computer # direct connection to computer
Vth A0 A1 # type K thermocouple, 41 uV/C
*/
// Teensy ++ at90usb1286-specific ADMUX settings per http://www.pjrc.com/teensy/at90usb1286.pdf p.328
#define ADMUX_MASK 0b11111 //
#define DIFF_1_0_x1 0b10000
#define DIFF_1_0_x10 0b01001
#define DIFF_1_0_x200 0b01011
#define DIFF_3_2_x1 0b11011
#define DIFF_3_2_x10 0b01101
#define DIFF_3_2_x200 0b01111
#define ADC0x10 0b01000
#define ADC0x200 0b01010
#define ADC2x200 0b01110
void setup()
{
Serial.begin(38400);
analogReference(INTERNAL); // 2.56V
DIDR0 |= (1 <<0);
DIDR0 |= (1 <<1);
}
int val,temp;
char buffer[64];
int analogReadAdmux(int admux){
// Read ADC based on an ADMUX setting
// teensy++ or at90usb1286-specific
int low,result;
ADMUX = (ADMUX & ~ ADMUX_MASK) | admux;
ADCSRA |= (1<<ADSC);
while (ADCSRA & (1<<ADSC)) ;
low = ADCL;
result =(ADCH<<8)|low;
if (result >= 0x200) result |= ~(~0U >>8);
return result;
}
int fracpart(float val,int prec){
if (val >= 0 )
return int((val-int(val))*prec);
else
return int((int(val)-val)*prec);
}
void loop()
{
float v,c;
int iv,ic;
val = analogReadAdmux(DIFF_1_0_x200 | 0b11000000 ); // 2.56V
Serial.print("analog 1-0 x200 reads: ");
v=val*2.56/200/512;
c=v/41e-6; // Type : ~ 41u/C
sprintf(buffer,"%d %d.%03d mV %d.%03d C\n",val,int(v*1000),fracpart(v*1000,1000),int(c),
fracpart(c,1000));
Serial.print(buffer);
delay(250);
}
It does jump around a bit, but it is still pretty cool:
Code:
analog 1-0 x200 reads: 5 0.124 mV 3.048 C
analog 1-0 x200 reads: 0 0.000 mV 0.000 C
analog 1-0 x200 reads: 0 0.000 mV 0.000 C
analog 1-0 x200 reads: 2 0.049 mV 1.219 C
analog 1-0 x200 reads: -3 0.074 mV -1.829 C
analog 1-0 x200 reads: 3 0.074 mV 1.829 C
analog 1-0 x200 reads: 5 0.124 mV 3.048 C
analog 1-0 x200 reads: 5 0.124 mV 3.048 C
analog 1-0 x200 reads: 9 0.225 mV 5.487 C
... in oven:
analog 1-0 x200 reads: 232 5.799 mV 141.463 C
analog 1-0 x200 reads: 231 5.775 mV 140.853 C
analog 1-0 x200 reads: 232 5.799 mV 141.463 C
analog 1-0 x200 reads: 235 5.875 mV 143.292 C
analog 1-0 x200 reads: 232 5.799 mV 141.463 C
analog 1-0 x200 reads: 238 5.949 mV 145.121 C
analog 1-0 x200 reads: 236 5.899 mV 143.902 C
analog 1-0 x200 reads: 230 5.750 mV 140.243 C
analog 1-0 x200 reads: 239 5.974 mV 145.731 C
... in freezer:
analog 1-0 x200 reads: -28 0.700 mV -17.073 C
analog 1-0 x200 reads: -24 0.599 mV -14.634 C
analog 1-0 x200 reads: -26 0.650 mV -15.853 C
analog 1-0 x200 reads: -21 0.525 mV -12.804 C
analog 1-0 x200 reads: -19 0.475 mV -11.585 C
analog 1-0 x200 reads: -28 0.700 mV -17.073 C
.... in boiling water
analog 1-0 x200 reads: 130 3.249 mV 79.268 C
analog 1-0 x200 reads: 135 3.375 mV 82.317 C
analog 1-0 x200 reads: 136 3.400 mV 82.926 C
analog 1-0 x200 reads: 147 3.674 mV 89.634 C
analog 1-0 x200 reads: 144 3.599 mV 87.804 C
Wtih a Teensy 2.0's internal temp sensor, I could correct for the cold junction temperature and have a large-range temp logger for pretty cheap.
For increased thermal resolution, I guess I could use a much smaller Vref and not do the x200 gain. If I divide 5VDC with a 47K:100 to make a 10.25mV AREF, I wouldn't need the internal gain, and maybe I could measure +/-250C with about 1/2C resolution and accuracy within a few degrees.
It doesn't look like Teensy 3.0 has programmable gain on the ADCs, so the small AREF might be a super-cheap option for reading a thermocouple.
Anyone using the gain functions? The differential ADCs? Or tiny AREFs?
Last edited: