Hi everyone, I currently have my arduino uno set up to measure temperature using an RTD. The RTD is in series with a 1000 ohm resistor, and is used as a voltage divider. The positive voltage comes from the 5v output and the negative goes to ground (both on the arduino).
The arduino takes an analog input (Ao) from the divider, calculating the voltage across the RTD, using the formula: Vrtd = Ao*(5/1024). Then my code calculates the resistance of the RTD using a formula derived from the voltage divider equation. The temperature is then calculated from an expression taken from its datasheet.
This works fine, however the temperature values seem to only increase or decrease by a fixed amount each time (+/-1.15 degree). Is there a way for me to change this so that I see smaller, smoother changes, such as by 0.1 of a degree each time instead of 1.15 of a degree?
int analogPin= 0;
int raw= 0;
int Vin= 5;
int ledPin= 13;
float Vout= 0;
float R1= 1000;
float R2= 0;
float buffer= 0;
float temp= 0;
void setup()
{
Serial.begin(9600);
}
void loop()
{
raw= analogRead(analogPin); //reading input voltage to A0
buffer= raw * Vin;
Vout= (buffer)/1024.0;
buffer= (Vout)/(Vin-Vout);
R2= (R1 * buffer);
temp = (-3.81+sqrt(14.5161 -(-0.002408*(1000-R2))))/(-0.001204);
Serial.print("Vout:""\t");Serial.print(Vout);
Serial.print("\t""R2: ""\t");Serial.print(R2);
Serial.print("\t""\t""Temp:""\t");Serial.print(temp);
Serial.println("\t");
delay(1000);}
Take care for overflows, and for integer calculations where long or floating point is required. E.g. 5000*1024 as an intermediate result exceeds the 16 bit integer range and loses significant bits.
I'm trying a different approach now, I'm trying to take samples of the voltage at the analog input, and use the average of these voltages in the rest of the calculations (10 samples from pin Ao per second, Vo = avg value of sample). Here's the code I added in:
int raw0= 0;
int raw1= 0;
int raw2= 0;
int raw3= 0;
int raw4= 0;
int raw5= 0;
int raw6= 0;
int raw7= 0;
int raw8= 0;
int raw9= 0;
int rawavg= 0;
raw0= analogRead(analogPin); //reading input voltage to A0
delay(100);
raw1= analogRead(analogPin); //reading input voltage to A0
delay(100);
raw2= analogRead(analogPin); //reading input voltage to A0
delay(100);
raw3= analogRead(analogPin); //reading input voltage to A0
delay(100);
raw4= analogRead(analogPin); //reading input voltage to A0
delay(100);
raw5= analogRead(analogPin); //reading input voltage to A0
delay(100);
raw6= analogRead(analogPin); //reading input voltage to A0
delay(100);
raw7= analogRead(analogPin); //reading input voltage to A0
delay(100);
raw8= analogRead(analogPin); //reading input voltage to A0
delay(100);
raw9= analogRead(analogPin); //reading input voltage to A0
delay(100);
rawavg=(raw0+raw1+raw2+raw3+raw4+raw5+raw6+raw7+raw8+raw9)/10;
Does this approach make sense? And is it possible to take readings like this from Ao, or does it write each of the raw values as the same?
I do not see much scope for "calibration" in your code. You can resolve down to say 0.00001 deg C, but if the unit can be off as much by 0.5 deg C due to tolerance values, is the extra 10,000x resolution worth your while?
Repeating measurements WILL increase your confidence limit, but again, the accuracy of the device will still be off.
You can repeat 100000000 measurements and get a temperature of 25.002671 deg C on average, but if there is a bias/systematic accuracy issue that causes the sensor to read higher or lower by 0.5 deg C...the actual TRUE value for temperature is 25.5002671.
All you will be doing is increasing your confidence around an inaccurate value.
It is a bit like saying "I measured the distance to the sun by holding a ruler out vertically and measured 25.1cm from the Earth to the Sun". "I did that 10,000 times to be sure I got the right answer".
EDIT: In short, if there is any systemic error due to the manufacturing tolerances of the MCU, Analog Digital Converters in the MCU, the resistor tolerances on your divider, other components, the actual RTD itself, the power supply etc. Being able to read an inaccurate measurement a million times gives you one million inaccurate measurements and one inaccurate average that you can be sure is inaccurate.
I'd focus on ensuring you can calibrate the sensor and your MCU/electronics against a known standard to begin with before trying to narrow down the resolution to minute degrees.
DrD - Thanks for that, I changed them from int to float instead and the results are much better. How could I sum the values in a loop?
Johnny - I understand what you mean, inaccurate measurements and calibrations will result in inaccurate results. Let's say my sensor is calibrated correctly, then what would you suggest?
I think you need a MAX31865 preamp breakout board for those sensors to be useful.
Check that the reference resistor used on the board is about 4x the RTD value.
dunns:
One more quick question, would it still work if I used the 3.3v output instead of the 5v output instead?
No.
A resistor/resistive sensor needs to have a direct relationship with Aref.
Google "ratiometric sensor".
Leo..