PT100 temerature sensor not stable reading

I’ve built a simple Nano setup to read values from PT100 sensors but my readings are all over the place. They’re +/- almost the whole degree celsius no matter how fast I’m reading inputs. I’ve tried three different sensors and three RTD 4-20mA transmitters, so I believe those components are not the problem. I’ve then concluded my 24V input is not stable because that’s the thing that could have impact on RTDs transmitting current, so I’ve tried different power supply- same thing. I’ve then started using old 500W ATX power supply thinking it surely has to have stable voltages. Well, after messing around with it to get 24V from it (-12V rail / +12 rail) I’ve come to the same problem, this time maybe 0.5 degrees but I can’t be sure…
I’ve now resorted to reading ten readings a second, then making the average of those and printing it out once a second, but it doesn’t help much.
If anyone has any idea what could be the problem and how to fix it I would greatly appreciate it.
Ps. I’ve tried putting capacitor (100uF/160V and 2200uF/35V) in parallel of the 24V output, but couldn’t see a positive change…

A Nano and a 4-20mA sensor returns 819 A/D values across the whole temp range of the RTD/preamp.
So what temp range are we looking at.

It might be better to use a 51ohm sense resistor, and switch to the internal potentially more stable 1.1volt Aref.

I will be using one of those at around 60°C, the second one over 100°C.
Testing has been done at normal house temperature and in hot water. It seems to be showing correctly, but I'm confused at its fluctuating..
Let's say I leave the sensor at room temperature, no outside heat or cooling sources, it reads e.g. 24.20, then next reading 24.35, 23.80, 24.05 and so on.. it constantly fluctuates... Just by looking at it I can make out that temperature is probably slightly over 24, but that's just not good enough, I want clear and precise reading.

What temp span are the 4-20mA boards calibrated for.
Then divide that by 819 to get temp granularity (with a 10-bit Arduino A/D).
If you can't answer this, then post a link to the sensor board.
Post your code (read forum rules first).

Why an RTD.
A DS18B20 is easier, cheaper, and has a 0.0625C granularity, that can be set to e.g. 0.25C or 0.5C steps.
Limitation could be temp range (-55C to 125C).

Sorry, I had the code on the other workstation and couldn’t get to it till now…

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include <OneWire.h> 
#include <DallasTemperature.h>

#define I2C_ADDR    0x27 // <<----- Add your address here.  Find it from I2C Scanner
#define BACKLIGHT_PIN     3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7

#define ONE_WIRE_BUS 2 

const float UPPER_LIMIT = 30.0;
const float LOWER_LIMIT = 29.0;
const char DEGREES_CHAR = (char)223;

int sensorValue1 = 0;
int sensorValue2 = 0;

int temperature1=0;
float f1 = 0;
float t1 = 0;

int temperature2=0;
float f2 = 0;
float t2 = 0;

bool isSwitchedOn = true;

int stateVar = 0;
int numOfReadings = 10;
int screenRefreshTime = 1;

LiquidCrystal_I2C  lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
OneWire oneWire(ONE_WIRE_BUS); 
DallasTemperature sensors(&oneWire);

void setup() {
  // put your setup code here, to run once:

  pinMode(RELAY, OUTPUT);

  // Switch on the backlight
  lcd.home (); 

void loop() {

  int sensorValue1 = analogRead(A0);
  f1 = temperature1;
  t1 += f1/100.0;
  //t1 = sensors.getTempCByIndex(0);

  int sensorValue2 = analogRead(A1);
  f2 = temperature2;
  t2 += f2/100.0;
  //t2 = sensors.getTempCByIndex(1);

  if(stateVar == (numOfReadings - 1)){
    t1 /= numOfReadings;
    t2 /= numOfReadings;
    printTemperature(1, t1);
    printTemperature(2, t2);
    t1 = 0;
    t2 = 0;

 delay((  screenRefreshTime * 1000) / numOfReadings);

 stateVar %= numOfReadings;

void printTemperature(int sensorNumber, float tempera){
  lcd.setCursor (0,sensorNumber-1);
  lcd.print("Sonda ");
  lcd.print(": ");
  lcd.print("C  ");

void controlRelayByTemperature(float tempera){
     if(tempera > UPPER_LIMIT){
        digitalWrite(RELAY, 0);
        isSwitchedOn = true;
      if(tempera < LOWER_LIMIT){
          digitalWrite(RELAY, 1);
          isSwitchedOn = false;

Code is kinda patched up with bunch of useless stuff I did while testing, but I think you’ll get the idea.

I’m using -50 to 150 degrees 4-20mA transmitter, similar to the one in the picture.

I’m using an RTD because I need to fit them into pipes and quite frankly I had them laying around. Also, I have a few of the DS18B20 sensors but they’re not waterproof and I managed to destroyed one while testing too hot of a measurement, I guess the 125°C top temperature is too close to needed…

-50C to +150C is a span of 200C, so with ~800 A/D values you get a granularity of about 0.25C.
A readout to 0.1C is pushing it, even with oversampling.

You now rely on (the potentially dirty/unstable) 5.00volt Aref (which it probably isn't).
I would start by using the more stable internal 1.1volt Aref.

Replace the 250ohm sense resistor with a 51ohm (standard E24 value) resistor.
Use 2*100ohm in parallel if you can't get one.
Give the resistor it's own ground connection to the Arduino (no sharing with e.g. LCD).

Then add this to void setup(), assuming you're using an Uno.


Print the temps to one decimal place.
lcd.print(tempera, 1);

I'm not using Uno but Nano.
After switching to 1.1V and changing to 51ohm resistor, situation looks even worse. Now the change is more like 1.5C.
Can you elaborate what you mean by giving resistor it's own ground connection to the Arduino? Aren't all the Arduino grounds basically the same point? Anyways, just in case, I did try connecting LCD to a different Arduino GND pin, nothing changed.

After switching to 1.1V and changing to 51ohm resistor, situation looks even worse. Now the change is more like 1.5C.

Can you elaborate what you mean by giving resistor it's own ground connection to the Arduino? Aren't all the Arduino grounds basically the same point? Anyways, just in case, I did try connecting LCD to a different Arduino GND pin, nothing changed.

That doesn't make sense. Maybe you should go back to basics.
Remove everything (LCD, etc.) and just use the sensor.
Write a simple sketch that displays raw A/D value and calculated temp on the serial monitor.

Current to/from other devices that share the same wires of sensors could influence sensor voltage.
Therefore it's generally not wise to share sensor wires with other devices.

You must have a clean analog supply for this sort of measurement, not an ATX switch-mode supply, that's
just bags of noise and then some. Maybe +/-10V linear regulators from your dirty +/-12V rails would clean
things up?
I'd add an anti-aliasing filter. A good low-pass filter on the analog pin (100k/10uF) will cut your noise
bandwidth down to a few Hz which is plenty for temperature readings and will throw away all the higher
frequency noise.

Adding more capacitance on the AREF pin may help too.

In the end I used ADS1115 16bit DAC and it solved the problem, so Wawa was right, 819 values was just to few.. It works perfectly stable, but I cannot get it to show temperature just right. I checked with multiple thermometers and it seems to be showing about 0.5C higher, even after I put in true measured resistance in account. In the end I just manually lowered the output by 0.5C, it will have to do for now..
Thank you for your help guys!

You will get the highest resolution with a 200ohm resistor and a PGA setting of 1x (4.096volt).
Post your code if you want help with that.

It seems that the sensor has trimmers for temp@4mA and temp@20mA.