Thermocouples in DAQFactory

Recommended Posts

Thermocouples are a very common way to measure temperature. Their wide temperature range and durability make them especially useful in high temperature applications. The problem with them is that they can be tricky to use properly.

First, you have to worry about how you wire them. I won't delve too much into hardware issues since I'm a software guy, but there are a couple important points: Thermocouple signals are typically around -5 to +50 millivolts. A small signal like this poses two concerns: noise and amplification. Because the signal is so small, noise injected into your wiring often is very large compared to the signal, creating huge errors. For this reason you must properly shield your thermocouple wires. Also keep the wires short, and if you can, use a differential analog input.

Most analog inputs don't have the resolution or range to read a 5 millivolt signal. 16 bit and higher converters probably do, but the more common 12 bit won't. For example, if you have a 12 bit analog input with a range of -1V to 1V (2V total), than the minimum step size it can read is 0.488 millivolts (that's 2 / 4096). Given a type K thermocouple with a voltage range of -6.4mV to 55mV that's 126 steps. Type K has a temperature range of -270 to 1370, or 1640C. 126 steps across this range gives us a maximum resolution of 13C. This assumes of course that there is no noise on the analog input, and usually there is one bit of noise minimum, which doubles the resolution to 26C. This resolution is likely unacceptable. To fix this you will need to use an amplifier, such as the LJTick-InAmp or EI1040 from LabJack. The amplifier will increase the voltage range. A 100x amplifier, for example, would take a Type K thermocouple to 640mV to 5.5V and thus decreasing the step size to around 0.2C, which is well within the accuracy limits of a thermocouple.

But enough of the hardware talk. Let us assume you have a thermocouple wired into an analog input with an amplifier giving a gain of 100x as in our example above. Reading the actual temperature within DAQFactory takes only a few steps:

1) create a channel to read the input. Exactly how to do this depends on what hardware you are using and is discussed in the users guide. You will now be getting voltage readings proportional to the temperature (though NOT linear). If the voltage goes down when the temperature goes up, you have the thermocouple wired backwards.

2) create a conversion. The expression for the conversion, assuming our 100x gain, type K thermocouple, and a fixed CJC value of 22 is:

TypeK(Value / 100, 22)

Note that we have to divide out the gain as the TypeK() function expects normal thermocouple voltages, not amplified ones. There are similar functions for all the other standard thermocouple types.

3) Apply the conversion to the channel. The channel will now read temperature.

Two details:

CJC or Cold Junction Compensation:

Thermocouples work because of a physical property of metals. If you place two different metals in contact with each other, a small voltage is generated that is proportional to the temperature at the point of contact. The different thermocouple types are simply different pairs of metals to achieve different ranges. The problem is that the point where you screw the thermocouple wire into the analog input is certainly also made of metal. Since it is a different metal than the thermocouple, a small voltage is also generated that is proportional to the temperature at this point, the so called "cold junction". To compensate for that, you have to specify the temperature of the cold junction to the TypeK() function.

How important is specifying an accurate CJC? Well, its basically one to one. If your CJC is off by 5C, then your final reading is likely off by 5C. If your CJC remains constant, this is not a big deal and can be calibrated out as described below, but if it moves around then you have introduced a pretty large source of error. The solution is to simply measure the temperature of the cold junction and use that instead of the fixed value I used above. Many DAQ devices have an internal temperature reading you can use, or you can use a simple temperature probe on a separate input. Either way, it will come into DAQFactory as a separate channel and the Conversion will change to something like this:

TypeK(Value / 100, CJCChannel[0])


Thermocouples are quite precise, but not terribly accurate. If you are using an amplifier, it also likely introduces some inaccuracies. Just because it says it has 100x gain, doesn't mean its not 101x or 99x. Because of this you probably should calibrate your thermocouples. Because the voltage out of a thermocouple is non-linear, I strongly recommend calibrating at the end using the resultant temperature reading as described above. To do so, use a standard two point calibration, ideally with two points that are spread out across your desired temperature range. If your temperature range is between maybe -50C and 200C the easiest two points to use are 0 and 100C. Here's how you would calibrate using these two points:

1) wire up your thermocouple and setup DAQFactory so that you get temperature readings displayed in degrees C.

2) Stick the thermocouple in an ice bath. This is a vessel filled with ice and water. Do not just stick it on a piece of ice. Once the reading settings, write down the value displayed in DAQFactory.

3) Stick the thermocouple in a boiling water. Make sure its a good boil and not just starting to boil. Again, once the reading settles, write down the value displayed in DAQFactory.

4) you now have your two points. Lets say you measured 3.2 for step #2, and 99.6 for step #3. What you want to measure is 0 for step #2 and 100 for step #3. To do this we need to multiply our current temperature reading by 1.0373 and subtract 3.319. To do this, we simply change our Conversion to:

TypeK(Value / 100, CJCChannel[0]) * 1.0373 - 3.319

How did I arrive at those numbers? Well, its simple slope line, y = mx + b. Slope (m) is DeltaY / DeltaX. DeltaY is the difference between the actual temperature values (y), 100 and 0, or 100. DeltaX is the difference between the measured temperature values (x), 99.6 and 3.2, or 96.4. Slope then is 100/96.4 or 1.0373. To determine the intercept, we simply plug in one of our two points and do a little algebra:

y = mx+b

100 = 1.0373 * 99.6 + b

b = 100 - 1.0373 * 99.6

b = 3.319

I think that covers the basics. Feel free to reply to this post with any questions.

Link to comment
Share on other sites

Hello DAQ,

Really a good post! Great that you guys look further than only the software app. I want to add a comment on the shielding of the TC's. Most controllers are filtering the TC value, this will catch short voltage peaks of the signal. So often it's not necessary to shield the signals or to worried about some starting up peaks when switching a valve or other disturbing instruments.

Of course check the polarity and crossing the wires at 2 places is the worst nightmare! This failure is hard to detect because at first glance you're measuring value looks good.

Good luck everyone,

Bart van Diepen


Pro Control B.V.

Link to comment
Share on other sites

Thanks for the reply and you are correct. There are actually two easy ways you can filter the TC value, one in hardware and one in software:

1) use a differential input. A differential input measures the difference in voltage between the two inputs instead of in reference to ground. Because most electrical noise ends up on both sides of the input, taking the difference between the inputs will subtract out the noise.

2) oversample the input and then average down to your desired data rate. So, if you want 1 second data, consider sampling at 0.1 seconds (set Timing to 0.1) and then check the Avg? column (in the Channel Table of DAQFactory) and put 10 in the # Avg column to average those readings down to 1 second data. Once you activate the avg, you won't really even be able to tell that its oversampling, other than quieter data. You can oversample up to about a timing of 0.05 from the Channel Table (depending on what else you have running on your system, and the hardware you are using). Anything faster would require hardware streaming.

Link to comment
Share on other sites

  • 6 months later...

Hi there,

A very interesting topic and I am wrestling with a very similar problem myself and I am a total novice at all this. My question is . . . I tried to work out the math question for myself as in your example above and when I tried to work out b = 100 - 1.0373 * 100 I got something very different - 9896.27 not 3.319. What have I done wrong?

Great idea to do this kind of subject as it really helps struggling mechanical engineers with data logging etc!


Shvetsov Engineering

Link to comment
Share on other sites

First, your math is just wrong: 1.0373 * 100 is 103.73. 100 - 103.73 is -3.73. Maybe you just hit the wrong keys on the calculator?

I also think you misunderstand the calculation. If using the freezing / boiling points, your formula indicates that you actually read 100 degrees C at the boiling point, which means you are dead on at boiling, but off a bunch at freezing. Its y = mx + b. X should be your measurement at one of the two points, not the desired reading. The desired reading is only used to determine m using the deltay/deltax formula I described.

Link to comment
Share on other sites

Many thanks,

I see now where I went wrong. Not being a mathamatician (as you can guess) I followed the sum literally and as it is written. 100 minus 1.0373 times 99.6 which gives the weird result. In fact it is 1.0373 times 99.6 minus 100.

On another problem I have, the readings from my thermocouples peak and trough by 30degrees. They are ordinary J Type thermocouples unamplified and fed directly into a LabJack UE9. I tried the water/ice cube and boiling water to see what I get but the reading bounces around so much that even with a MEAN reading it is still wild. Are the thermocouples dud? Or am I (once again) doing something wrong?

Thanks in advance!

Link to comment
Share on other sites

  • 1 year later...

Hi, first of all, thanks for the post, it's very helpful and clearly written.

I'm a first time DAQFactory and LabJack user, in fact I'm a first time DAQ user at all.

I just started a simple project in a university research lab where I would like to control a heater based upon a K Type thermocouple reading, and a user input desired temperature, using a labjack U3-LV, DAQFactory, and a relay. I'm going against the grain here and using DAQFactory and LabJack even though my lab is full of overpriced National Instruments equipment and all the computers have labview, on the down side it's a little hard to get help.

I understand the typek() conversion and use of avg function for signal smoothing but I think but am a little unclear about how to set up the channels. I have two wires, one silver colored and one copper colored. I plug one into channel FIO0 and one into FIO1 on the LabJack U3-LV. Now I need to find the voltage difference across these wires and apply the typek()conversion function to that voltage. I just can't seem to make that happen since I can only seem to apply conversions to channels... I'm sure this is a noob mistake but I'd really appreciate a pointer.

Now I'm not too concerned about accuracy here, I use the heater to burn wood samples so I can collect the smoke to measure particle losses across various types of sample apparatus. I just want the heater to take care of itself and it's outside the range of a toaster oven control circuit so I thought I'd try this for fun. So I know that without an amplifying circuit the voltage will give me +/-10C at best and with a 12 bit analog input resolution I don't even know if this is possible... I was going to try and get it set up at least, see how bad it is, and then amplify the signal if need be.

Thanks for your help in advance!


Link to comment
Share on other sites

To find the voltage difference, you want to read FIO0 in differential mode with FIO1 as the negative channel (not sure about which wire goes in which one though, if your signal goes in the opposite direction (i.e. lower voltage for hotter), then you have it reversed). To tell DAQFactory to read FIO0 with FIO1 as the negative, create a single channel, with channel # = 0. Then in the quick note/special/opc column, put 1. This tells DAQFactory that you want to use differential mode and that FIO 1 is the differential channel. This applies to the U3's only (any variety).

Link to comment
Share on other sites

Great, thanks for your help and fast response, that did the trick. My reading is terrible but I can at least tell what's going on now. I'll have to set up an amplifier and band pass for this to work at all it looks like.


Link to comment
Share on other sites

  • 4 weeks later...

Thanks for your advice, these forums have been very helpful for me while learning how to use this software.

I've got my K type thermocouple signal being amplified now and am reading the temperature, no problem. The heater control is fine too, I'm controlling a solid state relay with the labjack digital output to raise temperature to a user specified value and then turn off.

However, I'm overshooting very badly. So I'm attempting to learn about more controlled methods of approaching my desired temperature with this 120VAC 10A heater. I was thinking it would be nice to use a PWM output to control the solid state relay, and I know nothing about how to do this.

I also haven't had any luck finding a good tutorial or guide on how this could be done, could you help me out or point me in the right direction? I saw the PWMtimer recipe but don't really get it....


Justin Ellis

Link to comment
Share on other sites

You can do PWM in some hardware, such as the LabJack. If you are using a LabJack, check out the DAQFactory LabJack application guide and samples which include a PWM sample.

Otherwise, as long as the PWM can be slow, its pretty easy to do in software. Let's say your output channel is called "heater". Create a sequence that looks like this:

global heaterPercent = 0
while (1)
	 case (heaterPercent == 100)
		heater = 1
	 case (heaterPercent == 0)
		heater = 0
		heater = 1
		delay(heaterPercent / 100)
		heater = 0
		delay(1 - heaterPercent / 100)

Then set heaterPercent to the desired heater value from 0 (all off) to 100 (all on).

There are three states in this loop. The meat is in the default. Here we set the heater on, then delay for a fraction of a second corresponding to heaterPercent. We then set the heater off and delay the rest of the second. The other two states are just for full on and full off and keep the loop from momentarily switching the relay on or off in a full on or off state.

Link to comment
Share on other sites


This topic is now archived and is closed to further replies.