# Thermocouple reading different from Commercial Datalogger when using Arduino

A K-type thermocouple is connected to a thermocouple breakout board that outputs 1.2V to 8.8V that covers the entire -260C - 1380 °C of K-type thermocouple. This output is than divided by 2 using a potential divider made of two 10k ohm 1/4W 5% resistors, which is fed into an analog pin A0 of an Arduino Mega. The k-type thermocouple is not in contact with anything, essentially measuring the ambient temperature.

Problem: Using the Arduino sketch below, Arduino is measuring the temperature of about 10.6 deg C. However using a commercial temperature datalogger Omega HH309A, the measurement is 26.7 deg C.

Measuring the output of the thermocouple breakout board using a multimeter gives 2.19 V.

What could be the reason for this significant difference in measurement?

Sketch

void setup() {
pinMode(tcPin, INPUT);
Serial.begin(9600);
}

void loop() {

// Take the average of multiple readings
tempSum = 0;
for(int i = 0; i < tempSamples; i++) {
voltage = tc1 / 1024.0 * 5000 * 2;  // in mV after correcting for V_divider
tempSum += (voltage - 2.05) * 0.005;
delay(100);
}
temp = tempSum / tempSamples;

Serial.print("tc1: ");
Serial.println(tc1);

Serial.print("voltage: ");
Serial.println(voltage);

Serial.print("temp: ");
Serial.println(temp);

delay(1000);
}


Serial Monitor Output

tc1: 218
voltage: 2128.91
temp: 10.62
-
tc1: 217
voltage: 2119.14
temp: 10.60
-
tc1: 218
voltage: 2128.91
temp: 10.61
-
tc1: 218
voltage: 2128.91
temp: 10.63
-


Updated Arduino Sketch

void loop() {

// Take the average of multiple readings
tc1Sum = 0;
for(int i = 0; i < tcSamples; i++) {
tc1Sum += tc1;
delay(100);
}
tc1Average = tc1Sum / tcSamples;
// Arduino ADC has 1024 steps
// 10V max output from TC breakout board halved to 5000 mV before Arduino reads it
voltage = tc1Average * 5.0 * 2.0 / 1024.0;  // in V after correcting for V_divider
temp = (voltage - 2.05) * 0.005;

Serial.print("tc1Average: ");
Serial.println(tc1Average);

Serial.print("voltage: ");
Serial.println(voltage);

Serial.print("temp: ");
Serial.println(temp);
Serial.println("-");

}


Output

-
tc1Average: 218.20
voltage: 2.13
temp: 0.00
-
tc1Average: 218.40
voltage: 2.13
temp: 0.00
-
tc1Average: 218.20
voltage: 2.13
temp: 0.00
-
tc1Average: 218.40
voltage: 2.13
temp: 0.00
-

-

The formula you are using in your program does not agree with that given in the specifications for your thermocouple board. There is a 2.05 volt offset and a scale factor of 5 millivolts/deg C. Therefore to convert the board output voltage to deg C, the following should be done:

  deg C = (voltage - 2.05)/.005


Thus if the board voltage is 2.19 volts, the temperature calculates out to 28 deg C, close to your other temperature measuring device. In your program you are multiplying by .005 instead of dividing. That is why in your sample printout, you get a temperature of 0.00 for 2.13 volts instead of the correct value of 16 deg C.

-
From the board's website, they provide Ttc = ((Vout - 2.05) * 0.005)°C. I guess they made a mistake there? –  Nyxynyx Jun 17 at 4:15
It certainly looks like it. –  Barry Jun 17 at 12:06

A ten degree change would induce 50 millivolts of change on the output of the thermocouple board (or 25 mvolts after your divider). This is a relatively small number. I suspect a number of things that can cause errors of this size

First bet would be resistor mismatch. If your 210kohm resistors don't match perfectly, what would your output voltage be. Start by assuming one resistor is perfect, and the other is worst case off. If those are 5% tolerance resistors, assume one is at 210Kohms, and the other is at 220kohms (for a roughly 5% error), and figure out what your divider really outputs. Thumbnail calcs show that if you're measuring across the 220Kohm, a 5 volt input would give you 2.558 volts out, and there's your 50 mvolts!

Next, you may be having input impedance problems on your A/D input. You have a relatively high impedance source (>100kOhms) going into a cheap A/D with modest input impedance. Your A/D could very well be loading your voltage divider.

Precision measurement in this case calls for precision techniques. If you build an op amp circuit (these have low output impedance) with an amplifier that has a very low input offset voltage, give it a gain of 0.5 (yes-- you'll have to invert to get a gain less than 1.0), and use pots to trim all the resistances and maybe offsets, you'll do better.

If you still want to do things this way, try using 1% tolerance (or better) resistors of much lower value, maybe 5kOhms.

As a last possibility, maybe there's an offset somewhere on your thermocouple board that you have little control over. Thermocouples can be tricky to use correctly, and maybe their cold junction compensation isn't what it should be.

Also, you'll learn more about your error if you actually chart it across a temp range rather than a single point. I recommend a slow transition between an ice/water mix at 0 degrees, to hot tap water at around 40.

-
Thank you, the resisters used are indeed 5%. I guess 1% resistors should be sufficient. How will a high impedance source affect the accuracy of the readings from a cheap ADC? What resistances would you recommend? –  Nyxynyx Jun 16 at 21:27
I replaced the 10k 5% resistors with 22k 1% resistors (thats the smallest 1% resistors I have right now) and the Arduino readings are giving 10.66 deg C. –  Nyxynyx Jun 16 at 21:31
edited to add just that, probably while you were typing! Depends on the input resistance of the Arduino A/D's, which I don't know. I'd try 5K, which should be safer. 1K or less if your board can supply enough current. You'll still likely have an offset. Perhaps it would be safest to match the temp to your commercial logger with a trimpot for one of the resistors. Use two resistors, a high and a low (maybe 10% lower), and on the low add in series a ten turn trimpot of around 20% of the value of the high resistor, with the wiper shorted to one end. –  Scott Seidman Jun 16 at 21:31
Ordered some 100 and 1K 1% resistors, they should take a few days to arrive. The thermocouple is drawing its power from the 5V output of Arduino. Do you think this problem can be due to Arduino supplying slightly lesser than 5V? I'll need to get hold of a 5V power supply to test this. –  Nyxynyx Jun 16 at 21:36
Btw the commercial logger is giving 26.7 deg C, more than twice the value from Arduino of 10 deg C! –  Nyxynyx Jun 16 at 21:39
voltage = tc1Average * 5.0 * 2.0 / 1024.0;  // in V after correcting for V_divider


Your calculations are assuming that your board (and hence your Vref) is exactly 5V. It is highly unlikely that this is the case, especially if you are running from USB. I suggest getting a DMM and measuring the exact voltage of the 5V rail of the Arduino and using that in your calculations.

Secondly, you should be dividing by 1023, not 1024.

This, coupled with the other problems stated in the other answers, could account for the amount of drift.

-

There is a possibility that the thermo couple interface also provides an output for cold junction compensation. I have a suspicion that this should also feed into an analogue input of the arduino and that you may need to add the two readings together in software.

In case you didn't know cold junc comp is needed to compensate for the electric potential that occurs when the thermo couple wires are connected to copper tracks of the PCB. This is called the cold junction and it generates an error voltage that needs to be accounted for.

-
Thanks, I took a look at analog.com/en/mems-sensors/digital-temperature-sensors/ad8495/… and saw that the chip has internal cold junction compensation. Being new to electronics, do you think any more has to be done for the cold junction compensation? I do not see any more outputs from the thermocouple breakout board. –  Nyxynyx Jun 16 at 22:39