Electronics > Metrology

PRT: Error Propagation - Callendar Van-Dusen

(1/4) > >>

okti:
Hey everyone! My daily job is a software engineering but I do love electronics and spend too much time and money on it! I’m currently working on several libraries in Python just for fun. Some are in early stages, some are pretty advanced.

Now my problem is how to calculate the error propagation from calibration pairs, pass it through model and factor in the resistance measured uncertainty into final RMS error in C/K.

Callendar Van-Dusen

Calibration pairs all with uncertainty:

--- Code: ---Temperature(0.0 ± 0.012, unit: .celsius)
ElectricResistance(100.0 ± 0.001, unit: .ohms)

Temperature(100.0 ± 0.019, unit: .celsius)
ElectricResistance(138.50 ± 0.001, unit: .ohms)

Temperature(-200 ± 0.03, unit: .celsius)
ElectricResistance(18.53 ± 0.001, unit: .ohms)

Temperature(600 ± 0.08, unit: .celsius)
ElectricResistance(313.65 ± 0.001, unit: .ohms)
--- End code ---

I can calculate this  model:

--- Code: ---A = 3.9078333333333335e-03
B = -5.783333333333349e-07
C = -4.166666666666635e-12
r0 = 100.0
--- End code ---

Then I can calculate the temperature from resistance using this model:

--- Code: ---// T > 0
Z1 = -A
Z2 = pow(A, 2) - 4.0 * B
Z3 = 4.0 * B / r0
Z4 = 2.0 * B
celsius = (sqrt(Z2 + Z3 * resistanceOhms) + Z1) / Z4

--- End code ---

But what is the uncertainty after the calculation?

Searched the internet for clues but no luck.

- https://www.gilsoneng.com/reference/rtdinfo.pdf
- https://www.itsirl.com/images/references/datasheets/1399021951CalVan.pdf
- https://doi.org/10.1080/23311916.2018.1558687
- https://www.ele.uva.es/~lourdes/docencia/itl/Data_Sheets/Sensors/Pt100.pdf

Maybe you can point me at your own methods used in your lab or some non-paywalled literature?

(Side note: I have the same problem with ITS-90 coefs but the library is in early stages, still didn’t figure out the coefficients fitting but I’m slowly getting there.)

Thank you for reading this and considering help!

MaxTesla:
Hey,

so i am no expert in programming (so no help to be expected there  ;D) but i use this tool for uncertainty propergation:

https://www.metas.ch/metas/en/home/fabe/hochfrequenz/unclib.html

This is a free tool from the swiss national laboratory (METAS) which they use themself. I am using it on a regular basis with Matlab, so no experience with Python, but there is a library for it.
I meet the guy who did the software, very nice dude. The have there own forum for specific questions related to the UncLib.

This tool can do some fancy stuff including error propergation and error budgets. It does Monte Carlo as well, but i didn't touch it till now.

BR,

Max

okti:

--- Quote from: MaxTesla on November 16, 2021, 05:10:38 pm ---https://www.metas.ch/metas/en/home/fabe/hochfrequenz/unclib.html

This is a free tool from the swiss national laboratory (METAS) which they use themself. I am using it on a regular basis with Matlab, so no experience with Python, but there is a library for it.
I meet the guy who did the software, very nice dude. The have there own forum for specific questions related to the UncLib.

--- End quote ---

Oh wow, this tool is superb!
Why not open sourced is beyond my comprehension.

Thank you so much Max!

mzzj:

Fiqure out sensitivity factors from ohms to degrees at each calibration point so that you can combine the uncertainties.
You can derive the equations or just "step" the ohm value like 138,5 and 138,6 ohms. dT/dR
Lets say you have 2.8 Cel/Ohms sensitivity at 100Cel = 0.001 ohm*2.8 Cel/Ohms = 0.0028 Cel uncertainty from resistance measurement and 0.0190 Cel from reference temperature.
RSS together and you get 0,019205 Cel combined uncertainty.

Pain in the butt comes when you attempt to interpolate between calibration values (I think you don't have enough many calibration points to even start with)
Unless you are math genius you probably get results easiest by calculating one set of values for example every 10 ohms, introduce known error at one of the calibration points and recalculate the values every 20ohms.
Repeat for other calibration points and plot the differences between the curves.

For ITS-90 the BIPM has the holy bible of them all:
https://www.bipm.org/documents/20126/41773843/Guide_ITS-90_5_SPRT_2021.pdf/c4bbbe56-4118-eef7-47cb-3ea234db40b8
Section 6 deals with error propagation between calibration points and it looks like lots of fun!

okti:

--- Quote ---Lets say you have 2.8 Cel/Ohms sensitivity at 100Cel = 0.001 ohm*2.8 Cel/Ohms = 0.0028 Cel uncertainty from resistance measurement and 0.0190 Cel from reference temperature.
RSS together and you get 0,019205 Cel combined uncertainty.
--- End quote ---

Thank you @mzzj! This is sort of like my approach now. It's logical, it seems to make sense and the results are believable but would feel better to link to some literature for sanity sake.

This is how I do it now (this is pseudocode):

--- Code: ---T // calculated temperature kelvin using CVD
// Get two calibration points encompassing the measured temperature:
pointLower // Pair T,R below  measured
pointHigher // Pair T,R above measured

// Resistance error in measurement
dR = measuredResistance.uncertainty
rMinus = measuredResistance - dR
rPlus = measuredResistance + dR
tMinus = calculateTemperatureCelsius(from: rMinus) + 273.15 // using CVD
tPlus = calculateTemperatureCelsius(from: rPlus) + 273.15  // using CVD
uncertaintyFromMeasuredResistance = max(abs(T-tMinus), abs(T-tPlus)) // is this correct approach?

// Temperature error in calibration points
differenceOfTemperature = temperatureHigher - temperatureLower
slopeOfUncertaintyPerTemperature = (temperatureHigher.uncertainty - temperatureLower.uncertainty) / differenceOfTemperature
uncertaintyFromCalibrationTemperature = temperatureLower.uncertainty + (slopeOfUncertaintyPerTemperature * (T - temperatureLower.quantity))

// Resistance error in calibration points
lowerRError = uncertaintyFromResistance(at: pointLower)
higherRError = uncertaintyFromResistance(at: pointHigher)
slopeOfCalibrationResistanceErrorPerOhm = (higherRError - lowerRError) / differenceOfTemperature
uncertaintyFromCalibrationResistance = lowerRError + (slopeOfCalibrationResistanceErrorPerOhm * (T - temperatureLower.quantity))

// how `uncertaintyFromResistance(at:)` is calculated:
R = point.resistance.quantity
dR = point.resistance.uncertainty
step = 0.001
rMinus = R - step
rPlus = R + step
tMinus = calculateTemperatureCelsius(from: rMinus) + 273.15
tPlus = calculateTemperatureCelsius(from: rPlus) + 273.15
tChange = tPlus - tMinus
slope = tChange / (step * 2.0)
uncertainty = slope * dR

// finally:
error = sqrt(pow(uncertaintyFromCalibrationTemperature, 2.0) + pow(uncertaintyFromMeasuredResistance, 2.0) + pow(uncertaintyFromCalibrationResistance, 2.0))

--- End code ---

As you can see I'm using sensitivity everywhere and just approximate the uncertainty linearly between two nearest calibration points.

This is not ideal but I don't see how I can guess what is happening with uncertainty gradient between points, this is the best I've got so far.

Example results:

--- Code: ---Temperature(0.0 ± 0.01, unit: .celsius)
ElectricResistance(100.0 ± 0.0017, unit: .ohms)

Temperature(100.0 ± 0.019, unit: .celsius)
ElectricResistance(138.50 ± 0.0022, unit: .ohms)

Temperature(uncertainQuantity: -200 ± 0.03, unit: .celsius)
ElectricResistance(18.53 ± 0.0005, unit: .ohms)

Temperature(uncertainQuantity: 600 ± 0.08, unit: .celsius)
ElectricResistance(313.65 ± 0.0067, unit: .ohms)

// Generated coefficients:
A 0.0039078333333333335
B -5.783333333333349e-07
C -4.166666666666635e-12

--- End code ---

Measured resistance: 119.40 ± 0.002 (ohms)

Result:

50.0146 ± 0.0162 (celsius)