Measuring Temperature From PT100 Using Arduino

by Roboro in Circuits > Arduino

191370 Views, 115 Favorites, 0 Comments

Measuring Temperature From PT100 Using Arduino

Full Arduino.jpg

The PT100 is a resistance temperature detector(RTD) which changes its resistance depending on its surrounding temperature, it's used widely for industrial processes with slow dynamics and relatively wide temperature ranges. It's used for slow dynamic processes because RTDs have slow response times (which I talk more about later) but are accurate and have low drift over time. What I'm going to show you in this Instructable wouldn't be up to industrial standard but it'll expose you to an alternate way to measure temperature than using the LM35 which a lot of hobbyists would be familiar with and the circuit theory shown can be applied to other sensors.

Components

1x PT100(Two Wire)

1x Arduino(Any Model)

3x 741 Operation Amplifiers (LM741 or UA741)

1x 80ohm Resistor

2x 3.9kohms Resistors

2x 3.3kohms Resistors

2x 8.2kohms Resistors

2x 47kohms Resistors

1x 5kohms Potentiometer

1x Two Terminal Power Supply or 8x 1.5V AA Batteries

I'm using a two wire PT100, three and four wire PT100s will have different circuits. The resistor values for most of these don't have to be the exact same as above but if there's a pair of resistors i.e. the 3.9Kohms, if you swapped them for let's say 5k, you'd need to swap both for 5k as then need to be the same. When we get the circuit I'll say the effect of choosing different values. For the operation amplifiers (op amps) you can use other op amps but these are the ones I used.

Wheatstone Bridge

Screenshot_1.jpg
Wheat.jpg
Linearity.jpg

I first need to talk about the formula for getting the temperature from the resistance for the PT100 before I talk about the first part of the circuit, the formula for the resistance is as follows:

where Rx is the PT100 resistance, R0 is the PT100 resistance at 0 degrees C, α is the temperature resistance coefficient and T is the temperature.

R0 is 100ohms as this is a PT100, if it was a PT1000, R0 would be 1000ohms. α is 0.00385 ohms/degrees C taken from the datasheet. There is also a more accurate formula that can be found here but the above formula will do for this project. If we transpose the formula we can calculate the temperature for a given resistance:

Let's say we want to measure something which would have a temperature range of -51.85 to 130 degrees C and we placed the PT100 in the circuit shown in picture 1. Using the equation above and the equation for the voltage out of a voltage divider (shown in the first picture) we can calculate the voltage range. Bottom of the range T = -51.85(80ohms)

and at 130 degrees(150ohms):

This would give a range of 0.1187V and a DC offset of 0.142 because we know our temperature will never get below -51.85 degrees C, this will decrease the sensitivity in the range we care about (80 to 130ohms) when we amplify this voltage. To get rid of this DC offset and increase our sensitivity we can use a Wheatstone bridge which is shown in the second picture.

The output of the second voltage divider (Vb-) will be subtracted from the first voltage divider output (Vb+) using a differential amplifier later. The formula for the output of the bridge is just two voltage dividers:

The voltage out for the PT100 being 80ohms and using the other values in the picture:

and for Pt100 being 150ohms:

By using the Wheatstone we get rid of the DC offset and increase the sensitivity after amplification. Now that we know how the Wheatstone bridge works we can talk about why we use 80ohms and 3.3kohms. The 80ohms is kind of explained from the formula above, choose this value (we'll call this the offset resistor Roff) to be the bottom range of your temperature or even better, slightly below the bottom of your range, if this being used for a control systems for temperature regulation or something like that, you'd want to know how low the temperature is getting below your temperature range. So if -51.85C is the bottom of your range, use 74.975 ohms(-65 degrees C) for your Roff.

I chose 3.3k for R1 and R3 for two reasons, to limit current and increase the linearity of the output. As the PT100 changes resistance due to temperature, passing too much current through it will give incorrect readings due to self-heating so I chose a max current of 5-10mA. When the PT100 is 80ohms the current is 1.775mA so safely below the max range. You decrease the resistance to increase the sensitivity but this could have a negative effect on the linearity, as we'll be using the equation of a line later(y=mx+c) having a non-linear output will introduce errors. The third picture has a graph of the bridge output using different top resistors, the solid line is the actual output and the dotted line is the linear approximation. You can see in the dark blue graph(R1&R3=200ohms) gives the biggest voltage range but the output is the least linear. The light blue(R1&R3=3.3kohms) gives the smallest voltage range but the dotted line and solid line are overlapped showing its linearity is very good.

Feel free to change these values to suit your application, also if you change the voltage, make sure the current doesn't get too high.

Amplification

Diff AMp.jpg
Instrumentation  amp.jpg

In the last step, we found the output range of the two voltage dividers subtracted was 0 to 0.1187 but we haven't talked about how to subtract these voltages. To do this we'll need a differential amp which will subtract one input from the other and amplify this by the gain of the amp. The circuit for a differential amp is shown in the first picture. You feed the Vb+ into the inverting input and Vb- in the non-inverting input and the output will be the Vb+ - Vb- with a gain of one i.e. no amplification but by adding the resistors shown in the picture we add a gain of 5.731. The gain is given by:

Ra is R5 & R7 and Rb is R6 & R8, the voltage out is given by:

There're two problems with just connecting this amp to the output of the bridge, the loading effect and changing the gain. Changing the gain of the amp requires you to change at least two resistor as the two pairs of resistors have to be the same, so having two pots which have to have the same value would be annoying so we'll use something called an instrumentation amp which I talk about below. The loading effect is the input resistors into the amp affecting the voltage drop across the PT100, we want the voltage across the PT100 to be unchanged and to do this we can choose very large resistors for the input resistors so that the parallel resistance of the PT100 and input resistor is very close the PT100 resistance but this can cause problems with noise and voltage output offset that I'm not going to go into. Just pick mid range in the Kohms range but as I was saying, having small resistors is bad as well so we'll change the circuit a bit.

In the second picture, we have the output of the bridge connected to an instrumentation amp which acts a buffer amp to separate the two halves of the circuits(the bridge and amplification) as well allows use to amplify the input by changing just one potentiometer (Rgain). The gain of the instrumentation amp is given by:

where Rc is the two 3.9k resistor above and below the pot.

By decreasing Rgain, the amplification increases. Then at point Va and Vb(amplified Vb+ and Vb-), it's just a differential amp as before and the total gain of the circuit is just the gains multiplied together.

To choose your gain you want to do something like we did before with the Roff, we should pick a resistance just above your max temperature in your range just in case it goes over. Because we're using the Arduino which has a 5V adc, the max output of the circuit should 5V at the max temperature you chose. Let's pick the 150ohms as the max resistance and the bridge voltage un-amplified was 0.1187V, the gain we need is 42.185 (5/0.1187)

Let's say we keep Ra, Rb and Rc as 8.2k, 47k and 3.9k, we just need to find the value for the pot Rgain:

So to get the full 5 volts out of the temperature range we are using, change the value of Rgain to 1.226k. The output voltage coming out of the differential amp is given by:

Powering the Circuit

Supply1.jpg
Supply 2.jpg
Supply 3.jpg

This is the last step of the circuit, you might have noticed the Vcc+ and the Vcc- on the op amp circuits, this is because they need both positive and negative voltage to function properly, you can get single rail op-amps but I decided to use these amp as that's what I had lying around. So we'll supply +6V and -6V, there're three ways we can do this. The first is shown in the first picture where we have to two power supplies or two output terminals from a single power supply, have both at 6V and have one positive output connected to the negative of the other. The 6V of the top supply will be our +6V, the positive of the bottom supply is the GND and the negative of the bottom supply is the -6V. ONLY CONNECT IT LIKE THIS IF THE GNDs OF THE TWO SUPPLIES ARE SEPARATED OR IT'LL DAMAGE YOUR POWER SUPPLY. All commercial power supplies would have separated GNDs but if you want to check, use the continuity tester on your multimeter, if it buzzes, don't use this setup and use the next one. On my homemade supply, I blew the fuse doing this.

In the second picture is the second setup we can have, it does require one supply to have double the voltage of other but won't damage the supply if the GNDs are connected. We have two supplies, one at 12V and other at 6V. The 12V will act as our +6V, the 6V out of the second supply will act as the GND and the two actual GNDs out of the supplies will act as -6V.

This last setup is for the power supplies with only one output, it uses a buffer amplifier of gain 1 to create a virtual ground by passing half the supply voltage through the buffer amp. Then the 12V will act as the +6V and the actual GND terminal will be -6V.

If you want to use batteries, I'd suggest the first setup but a problem with batteries is that the voltage will drop as they start to die and the voltage out of the bridge will drop as well, giving wrong temperature readings. You could of course read the voltage from the batteries and include them in the calculations or use regulators and more batteries. In the end, it's up to you.

Full Circuit and Code

Full Arduino.jpg
Circuit Diagram.jpg
LTSPice Circuit.jpg

The full circuit is shown above and it was made in Autodesk's new Circuits.io which lets you created circuits on breadboard, edit circuit diagram(shown in picture 2) and PCB diagrams and the best part, lets you simulate the circuit from the breadboard and can even program an Arduino and connect it in the breadboard mode, further down the page is the simulation and you can play around with two pots. If you want to duplicate the circuit and put in your own values, you can find the circuit here. The first pot is 70ohms and in series with an 80ohm resistor which simulates the PT100 with a range of 80-150ohms, the second pot is the gain of the instrumentation amp. Sadly I used a library I downloaded for my code, so the Arduino isn't included in the circuit below but the there's only two extra wires you need to connect. If you are more comfortable with LTspice, I included an asc file with the circuit.

Connect A0 pin to the output of the Differential amp

Connect the GND of the Arduino to the GND of the circuit(NOT THE -6V)

And that's the circuit done, now onto the code. Earlier I mentioned that we'll be using the formula y=mx+c, well now we're going to calculate m(the slope) and c(the offset). In the Arduino, we'll be reading voltage but the temperature equation needs us to know the resistance of the PT100 so a way we can do this is by replacing the Serial.println(temp) with Serial.println(V) and record the voltage and resistance at two temperatures. When doing this test leave the PT100 alone for a bit, like a minute or two and keep away from any heat sources(sunlight, laptop fan, your body, etc).

The first point we can take is room temperature, when you have the circuit connected and working, record the voltage(Vt1) read by the Arduino on the serial monitor and quickly disconnect the PT100 and record its resistance(Rt1), do not put your hands on the probe when disconnecting as this will change the resistance. For the second temperature, we could place the probe in ice water or hot water(be careful if using hot water) and repeat what we did before finding Vt2 and Rt2. Just after you place the probe in the liquid wait a minute or two for the resistance to settle. If you're interested in the time response of the PT100, record the voltage off of the serial monitor every 2 seconds or so and we can draw a graph from this and I'll explain it later. Using the two voltages and resistances, we can calculate the slope as follows:

Rt1 and Rt2 are the resistances at the two temperatures and same it true for the voltages Vt1 and Vt2. From the slope and one of the two sets of points you recorded we can calculate the offset:

C should be close to your real Roff, From my simulation I calculated these values:

From this resistance we can find our temperature using the formula we had at the start:

And that's it, the code for the Arduino is below, if you have any problems, just leave a comment and I'll try to help.

There are no pictures of the circuit I made as I made it a while ago and don't have the PT100 anymore to remake and test but you'll just have to believe me that it works. There isn't much about the PT100 on Instructables that I found so that's why I made this ible.

In the next step I'll be talking about the time response of the PT100 and if you're not interested in the maths, when you're measuring a temperature change, let the PT100 settle for a minute or so before taking the reading.

If you're interested to see other projects I've made, visit my

Blog: Roboroblog

YouTube Channel: Roboro

Or look at my other Instructables: here

If the HTML messes with the code below, the code is attached

* This code calculates the temperature using a PT100
 * Written by Roboro
 * Github: <a href="https://github.com/RonanB96/Read-Temp-From-PT100-With-Arduino"> <a> <a> <a> <a href="https://github.com/RonanB96/Read-Temp-From-PT100-...</a"> <a href="https://github.com/RonanB96/Read-Temp-From-PT100-...</a"> <a>  <a href="https://github.com/RonanB96/Read-Temp-From-PT100-..."> <a href="https://github.com/RonanB96/Read-Temp-From-PT100-...</a"> <a href="https://github.com/RonanB96/Read-Temp-From-PT100-...</a">  https://github.com/RonanB96/Read-Temp-From-PT100-...>>>>>>>>>>
 * Circuit: <a href="https://circuits.io/circuits/2962051-reading-temperature-from-pt100/"> <a> <a> <a> <a href="https://github.com/RonanB96/Read-Temp-From-PT100-...</a"> <a href="https://github.com/RonanB96/Read-Temp-From-PT100-...</a"> <a>  <a href="https://github.com/RonanB96/Read-Temp-From-PT100-..."> <a href="https://github.com/RonanB96/Read-Temp-From-PT100-...</a"> <a href="https://github.com/RonanB96/Read-Temp-From-PT100-...</a">  https://github.com/RonanB96/Read-Temp-From-PT100-...>>>>>>>>>>
 * Blog: <a href="https://roboroblog.wordpress.com"> <a> <a> <a> <a href="https://github.com/RonanB96/Read-Temp-From-PT100-...</a"> <a href="https://github.com/RonanB96/Read-Temp-From-PT100-...</a"> <a>  <a href="https://github.com/RonanB96/Read-Temp-From-PT100-..."> <a href="https://github.com/RonanB96/Read-Temp-From-PT100-...</a"> <a href="https://github.com/RonanB96/Read-Temp-From-PT100-...</a">  https://github.com/RonanB96/Read-Temp-From-PT100-...>>>>>>>>>>
 * Instrustable Post: <a href="https://www.instructables.com/id/Reading-Temperature-From-PT100-Using-Arduino/"> <a> <a> <a> <a href="https://github.com/RonanB96/Read-Temp-From-PT100-...</a"> <a href="https://github.com/RonanB96/Read-Temp-From-PT100-...</a"> <a>  <a href="https://github.com/RonanB96/Read-Temp-From-PT100-..."> <a href="https://github.com/RonanB96/Read-Temp-From-PT100-...</a"> <a href="https://github.com/RonanB96/Read-Temp-From-PT100-...</a">  https://github.com/RonanB96/Read-Temp-From-PT100-...>>>>>>>>>>
  *
*/


//You'll need to download this timer library from here
//http://www.doctormonk.com/search?q=timer
#include "Timer.h"

// Define Variables
float V;
float temp;
float Rx;

// Variables to convert voltage to resistance
float C = 79.489;
float slope = 14.187;

// Variables to convert resistance to temp
float R0 = 100.0;
float alpha = 0.00385;

int Vin = A0; // Vin is Analog Pin A0



Timer t; // Define Timer object</p><p>void setup() {
  Serial.begin(9600); // Set Baudrate at 9600
  pinMode(Vin,INPUT); // Make Vin Input
  t.every(100,takeReading); // Take Reading Every 100ms
}

void loop() {
  t.update(); // Update Timer
}

void takeReading(){
  // Bits to Voltage
  V = (analogRead(Vin)/1023.0)*5.0; // (bits/2^n-1)*Vmax 
  // Voltage to resistance
  Rx = V*slope+C; //y=mx+c
  // Resistance to Temperature
  temp= (Rx/R0-1.0)/alpha; // from Rx = R0(1+alpha*X)
  // Uncommect to convet celsius to fehrenheit
  // temp = temp*1.8+32; 
  Serial.println(temp);
}

Time Response of PT100

Step Response.jpg

So I mentioned that the PT100 has a slow response but we can get a formula for the current temperature read by the PT100 at any time t. The response of the PT100 is a first order response which in can be written in Laplace terms i.e. transfer function, as:

where tau(τ) is the time constant, K is the gain of the system and s is the Laplace operator which can be written as where ω is frequency.

The time constant tells you how long it takes a first order system to settle at its new value and a rule or thumb is that 5*tau is how long it'll take to settle at the new steady state. The gain K tells you how much the input will be amplified. With the PT100, the gain is how much the resistance changes divided by the temperature change, from picking two random values from this datasheet, I got a gain of 0.3856 ohm/C.

Before I said you could record the voltage every 2s after you put the probe in the liquid, hot or cold, from this we can calculate the time constant of the system. First you need to identify where the start point and end point, the start point being the voltage before you put the probe in the liquid and the end point being when it settled. Next subtract them and that's the voltage change of the step, the test you conducted was a step change which is a sudden change in input to a system, the step being temperature. Now on your graph go to 63.2% of the voltage change and this time is the time constant.

If you plug that value into the transfer function, you then have the formula to describes the frequency response of the systems but that's not what we want right now, we want the actual temperature at time t for a step in temperature so we're going to have to perform an inverse Laplace transform of a step into the system. The transfer function of a first-order system with an input of a step is as follows:

Where Ks is the step size i.e. the temperature difference. So let's say the probe is settled at 20 degrees C, placed into water at 30 degrees C and the probe has a time constant of 8s, the transfer function and time domain formula is as follows:

The δ(t) just means an impulse i.e. DC offset of 20 degrees C in this case, you can just write 20 in your equations when calculating this. This is the standard equation for the step into a first order system:


The above calculates the temperature at time t but this will work for the voltage as they are proportional to each other, you just need the starting and ending value, time constant and step size. A website called Symbolab is great for checking if your maths is right, it can do Laplace, integration, differentiation and lots of other things and it gives you all the steps along the way. The inverse Laplace transform the above can be found here.