Introduction: Measuring Temperature From PT100 Using Arduino
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.
Step 1: 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.
Step 2: Wheatstone Bridge
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.
Step 3: Amplification
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:
Step 4: Powering the Circuit
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.
Step 5: Full Circuit and Code
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); }
Step 6: Time Response of PT100
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 jω 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.

Participated in the
Circuits Contest 2016
40 Comments
Question 1 year ago
Is there any benefit of using Dual Rails over Single Rail Opamp ??
2 years ago
Why do you connect Vb+ to op-amp (-) port and Vb- to (+) port?
2 years ago
The output of the electric network, what is read by the MCU is not linear. :(
4 years ago
Hi Roboro, Thank you very much. I use LM324 and it works well but this formula T=(Rx/R0)-1)/@ is not accurate. I use this formula
T = -247.29 + 2.3992 R + .00063962 R2 + 1.0241E-6 R3
and I have more accurate T according to PT100 temp table.
Thanks a lot.
Reply 2 years ago
Hi. Can you share your circuit with me?
4 years ago
Cool Instructable.Thank you.
It helped me much in my own project.
the PT100 I used is a
PCA1.1505 1M it has a fast response time of 0.3s when in direct contact.
I use an ESP8266 with 2.4" TFT Display, L324N Opamp 1% accuracy Resistors and ESP Basic for programming.
Reply 2 years ago
Can you share your circuit with me?
Question 2 years ago
I'm using Lm324 and 5V supply but I'm having issues connecting the 47k end and the PT100 end. When I connect them to GND they givile me a very low value of Vout.
Question 3 years ago
why do you use symmetric source rather than single source to supply opamp?
Answer 3 years ago
Bạn có thể mô tả các nguyên tắc hoạt động của mạch? thank you very much
3 years ago
3 years ago
Hello Sir,
I have tried it, I have some doubts with it. Can I get your mail ID Sir?
Question 4 years ago
Hi Roboro,
Nice to talk with you.
I have a problem after read your article. At step 5 when you introduce about full circuit, you recommended "Connect A0 pin to the output of the Differential amp". Because I didn't understand the point where i will connect it with A0 pin of arduino. I have attached a photo, I showed this point in this photo as my inference.
Please check for me the point i shown in picture is right? If i was wrong, could you show me the right point to connect to A0 pin of Arduino?
I am looking forward to getting your support.
Thank you so much.
Answer 4 years ago
Yes thats is where you connect A0 to
Question 4 years ago
So I did the assembly, but instead I chose to use only the potentiometer to adjust the gain, installing all the resistors in the amplifier with the same value of resistance. But I have a problem regarding the actual values of the resistance for each resistor. None of them have exactly the nominal value, and I need to have the most accuracy I can to have precise temperature measurings. How do you deal with that? ( obs: I'm a mechanical engineering student, so pardon the basic question.
Answer 4 years ago
So in the second half of step 5 I go through calculating the slope "m" (ohm/V) and the offset "C" (ohm) used in the code for calculating the temperature. These parameters describe the voltage output of your circuit to a change in resistance of the PT100 (including tolerances of the resistors). So if you calculate these values accurately, the tolerance shouldn't effect your measurements too much.
In step 5, I talk about using the PT100 for calculating the parameters but this can be swapped with a potentiometer which is probably a better way of doing it.
Hope this helps
5 years ago
Hi Roboro , I need your help
When you make your project and add an LCD to see the temperature, the value of the temperature changes quickly and never stops.
i measure the temperature from pt100 3 wire
the program :
#include "Timer.h"
// Define Variables
float V;
float temp;
float Rx;
float k;
// 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
#include <LiquidCrystal.h>
LiquidCrystal lcd(12,11,5,4,3,2);
void setup() {
lcd.begin(16,2);
lcd.print("temp =");
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
lcd.setCursor(6,0);
lcd.print(" ");
lcd.print(temp);
lcd.print((char)223);
lcd.print("c");
lcd.setCursor(5,1);
k=temp+273;
lcd.print("= ");
lcd.print(k);
lcd.print(" k");
}
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);
}
5 years ago
is it enaugh to use only this equation ( temp = V*slope+C ) on the code ?
Reply 5 years ago
Yes you could reduce it to just that line if you know the offset temperature (C) and the slope (Temperature/Volt)
Question 5 years ago on Step 3
How to calculate R5 value?