Curve Fitting the Calibration Data of a Thermistor Voltage Divider Gerald Recktenwald Portland State University Department of Mechanical Engineering [email protected] March 5, 2013 EAS 199B: Engineering Problem Solving
Curve Fitting the Calibration Dataof a Thermistor Voltage Divider
Gerald Recktenwald
Portland State University
Department of Mechanical Engineering
March 5, 2013
EAS 199B: Engineering Problem Solving
Thermistor Calibration Measurements
To make measurements with an Arduino, the
thermistor is located in the upper leg of a
voltage divider.thermistor
10 kΩ
5V
Analog input
For the calibration measurements, the
thermistor is placed in an insulated thermos,
along with a thermometer and water.
Voltage divider forArduino input
+5V or digital output
analog inputInsulatedCoffee mug
Thermistorprobe
ReferenceThermometer
EAS 199B: Engineering Problem Solving page 1
Calibration Data Set
Data storage
• Repeated readings of the voltage divider are
averaged. The averaged values are displayed
in the Arduino Serial Monitor.
• The displayed data is copied and pasted into
columns of an Excel spreadsheet.
• The first row of the spreadsheet is the
temperature for the data set.
• Columns under the first row are the averaged
raw analog input values.
• After the measurements are complete, the data
in the Excel worksheet is saved as a tab-
delimited text file.
Temperaturein first row
Analog input valuesin other rows
1 2 3 nc...
EAS 199B: Engineering Problem Solving page 2
Analysis of Calibration Data with Matlab
The analysis of the calibration data involves these steps
1. Read the data into Matlab.
2. Plot histograms of the raw readings to determine the variability of the calibration
readings.
3. Compute the mean of the raw readings
4. Curve fit the raw voltage divider readings as a function of temperature
5. Swap the roles of the data to curve fit the temperature as a function of voltage divider
readings.
The quality of the curve fits is assessed with plots of the residuals.
EAS 199B: Engineering Problem Solving page 3
Read the Calibration Data into Matlab
The built-in load function reads an array of plain text data into a matrix
D = load(’thermistor_data.txt’)
D is a matrix. The first row of D is the temperature.
T = D(1,:);
The remaining rows are voltage divider readings
V = D(2:end,:);
Most of the work involves analyzing the data in the new
matrix V.
Temperaturein first row
Analog input valuesin other rows
1 2 3 nc...
EAS 199B: Engineering Problem Solving page 4
Read the Calibration Data into Matlab
Compute the average of each of the columns in V
Vave = mean(V);
Vave is a row vector with the same number of elements as T.
The length (number of elements) in both T and Vave is equal to the number of columns
in the data set.
EAS 199B: Engineering Problem Solving page 5
Plot the Calibration Data
It is easy to plot the mean data.
plot(T,Vave,’o’);
xlabel(’Temperature (C)’);
ylabel(’Analog reading’);
But we are getting ahead of
ourselves. We should first look at
the quality of the data by making
histograms of the readings for each
calibration temperature.0 10 20 30 40 50 60
300
350
400
450
500
550
600
650
700
750
Temperature (C)A
nalo
g re
adin
g
For convenience, the following page lists a Matlab function to load and plot the data.
EAS 199B: Engineering Problem Solving page 6
Plot Calibration Data
function plot_calibration_data(fname)
% plot_calibration_data Plot raw calibration data for the thermistor
% -- Supply a default file name
if nargin<1, fname=’thermistor_data.txt’; end
% -- Load the data and compute summary statistics for each column
D = load(fname);
T = D(1,:); % Temperature values in first row
V = D(2:end,:); % Voltage data in columns from second row until end
Vave = mean(V); % Mean of data in each column
% -- Plot the averaged reading versus the calibration temperature
plot(T,Vave,’o’);
xlabel(’Temperature (C)’); ylabel(’Analog reading (10-bit scale)’);
EAS 199B: Engineering Problem Solving page 7
Histogram of the Calibration Data (1)
It is easy to plot a histogram of the data in
the first column.
hist(V(:,1))
xlabel(’Analog reading (10-bit scale)’)
ylabel(’Number of readings’)
V(:,1) is the vector of data in the first
column of V. The : is a wildcard meaning
all of the row indices.
There appears to be some spread in the
data, but look at the range!739.1 739.2 739.3 739.4 739.5 739.60
2
4
6
8
10
12
14
16
18
20
Analog reading (10−bit scale)
Num
ber
of r
eadi
ngs
The analog readings are integer values. The entire set of readings at this temperature fall
between 739.1 and 739.6. The non-integer values occur because each of the readings in
the data set is an average of 20 readings.
EAS 199B: Engineering Problem Solving page 8
Histogram of the Calibration Data (2)
There is no significant variability for the
data in the first column.
Let’s check the other columns (other
temperatures).
739.1 739.2 739.3 739.4 739.5 739.60
2
4
6
8
10
12
14
16
18
20
Analog reading (10−bit scale)
Num
ber
of r
eadi
ngs
The histogram of the second column is
obtained with
hist(V(:,2))
which produces the plot to the right.
Again, the readings fall in a very narrow of
analog input values.665 665.1 665.2 665.3 665.4 665.50
5
10
15
20
25
30
Analog reading (10−bit scale)
Num
ber
of r
eadi
ngs
EAS 199B: Engineering Problem Solving page 9
Histogram of the Calibration Data (3)
We can automate the creation of histograms with a loop over all columns in V.
First, extract the number of columns for the data set with the built-in size command
nc = size(V,2)
This is nice: our data analysis automatically adjusts to the size – number of columns and
number of rows – of the data set. No mouse clicks involved!
With nc known, the following loop computes histograms for each of the columns in V
nc = size(V,2)
for j=1:nc
figure % Open a new plot window
hist(V(:,j)) % Histogram of data in column j
xlabel(’Analog reading (10-bit scale)’)
ylabel(’Number of readings’)
end
EAS 199B: Engineering Problem Solving page 10
Histogram of the Calibration Data (4)
We can combine the histograms in a single window by using the subplot command to
create an array of plots.. The syntax is
subplot(nrow,ncol,p)
where nrow is the number of rows in the array, ncol is the number of columns in the
array, and p is a counter for the plot number in the array.
The diagram to the right shows
three possible layouts of subplots.
All practical combinations of
nrow and ncol are allowed.1
2
subplot(2,1,p)p = 1,2
1
3
5
2
4
6
subplot(3,2,p)p = 1,2,...6
1 2
3 4
nc
nprow
subplot(nprow,2,p)p = 1,2,...nc
••••••
EAS 199B: Engineering Problem Solving page 11
Histogram of the Calibration Data (5)
The following code snippet uses the subplot command to layout the histograms for the
columns of V in an nprow × 2 array
nc = size(V,2); % number of columns
nprow = ceil(nc/2); % number of rows for array of subplots
for j=1:nc
subplot(nprow,2,j); % Move to the next subplot
hist(V(:,j)); % Bin the data and plot the histogram
ylim( [0, 40] ); % Set the same y-axis limits in all plots
end
The plot_thermistor_histograms.m function (on the next slide) mass-produces
histograms: one for each column in the data set.
EAS 199B: Engineering Problem Solving page 12
Histogram of the Calibration Data (6)
function plot_thermistor_histograms(fname)
% plot_thermistor_histograms Plot histograms of calibration data for thermistor
if nargin<1, fname=’thermistor_data.txt’; end % Default name of data file
% -- Load the data and compute summary statistics for each column
D = load(fname);
T = D(1,:); % Temperature values in first row
V = D(2:end,:); % Voltage data in columns from second row until end
Vave = mean(V); % Mean of data in each column
Vmed = median(V); % Median of data in each column
Vstd = std(V); % Standard deviation of each column
nc = size(V,2); % Number of columns in V
nprow = ceil(nc/2); % Number of rows in the array of histograms
fprintf(’\n T(C) mean(V) median(V) std_dev(V)\n’);
for j=1:nc
subplot(nprow,2,j); % Move to the next subplot
hist(V(:,j)); % Bin the data and plot the histogram
ylim( [0, 40] ); % Set the same y-axis limits in all plots
text(min(V(:,j))+0.1, 33, sprintf(’T = %-6.1f’,T(j))); % label the subplot
fprintf(’%8.1f %8.1f %8.1f %8.2f\n’,T(j),Vave(j),Vmed(j),Vstd(j));
end
EAS 199B: Engineering Problem Solving page 13
Histogram of the Calibration Data (7)
Variability at all temperatures the data sets is negligible.
739 739.2 739.4 739.6 739.8 7400
20
40T = 51.9
665 665.2 665.4 665.6 665.8 6660
20
40T = 42.4
578 578.2 578.4 578.6 578.8 5790
20
40T = 32.4
528 528.2 528.4 528.6 528.8 5290
20
40T = 27.1
493 493.5 494 494.5 4950
20
40T = 23.7
470 470.2 470.4 470.6 470.8 4710
20
40T = 21.3
447 447.5 448 448.5 4490
20
40T = 19.0
429 429.2 429.4 429.6 429.8 4300
20
40T = 17.3
386 386.5 387 387.5 3880
20
40T = 13.2
325 325.5 326 326.5 3270
20
40T = 6.4
314 314.5 315 315.5 3160
20
40T = 6.0
EAS 199B: Engineering Problem Solving page 14
Summary data
The plot_thermistor_histograms.m function also prints the mean, median and
standard deviation of each column of data. Remember: each column contains the analog
readings for a given calibration temperature.
plot_thermistor_histograms
T(C) mean(V) median(V) std_dev(V)
51.9 739.3 739.3 0.08
42.4 665.3 665.3 0.08
32.4 578.4 578.4 0.07
27.1 528.7 528.7 0.06
23.7 494.1 494.1 0.07
21.3 470.5 470.5 0.07
19.0 448.1 448.1 0.07
17.3 429.6 429.6 0.08
13.2 386.9 386.9 0.07
6.4 325.9 325.9 0.15
6.0 315.0 315.0 0.07
The next step is to create a curve fit of the analog readings versus the temperature.
EAS 199B: Engineering Problem Solving page 15
Calibration Curve Fit Equation
The calibration process suggests a curve fit of the form V = f(T ): the water
temperature was chosen by mixing warm and cold water supplies, and the voltage output
was recorded with the Arduino.
We could use a polynomial for V (T ).
V = c1Tn
+ c2Tn−1
+ · · · + cn−1T + cn. (1)
However, to control the temperature of the fish tank, we will need T = f(V ).
T = a1Vn
+ a2Vn−1
+ · · · + an−1V + an. (2)
EAS 199B: Engineering Problem Solving page 16
Polynomial Curve Fit in MATLAB
Assume the data is in the T and
Vave vectors.
c = polyfit(T,Vave,2);
Tfit = linspace(min(T),max(T));
Vfit = polyval(c,Tfit);
plot(T,Vave,’o’,Tfit,Vfit,’r--’);
xlabel(’Temperature (C)’);
ylabel(’Analog output’);
0 10 20 30 40 50 60300
350
400
450
500
550
600
650
700
750
Temperature (C)
Ana
log
outp
ut
The fit looks good, but we should dig deeper
EAS 199B: Engineering Problem Solving page 17
Residual of the Curve Fit (1)
We often use R2 as an indicator of the fit. There is more information in the residuals
ri = yi − yfit(xi)
where (xi, yi) are the measured data and yfit(x) is the fitting function, e.g., a
polynomial.
ri = yi - yfit(xi)
EAS 199B: Engineering Problem Solving page 18
Residual of the Curve Fit (1)
Given the curve fit evaluated with polyfit, we can compute the residuals in one line
c = polyfit(T,Vave,2); % coefficients of polynomial curve fit: V = f(T)
rfit = Vave - polyval(c,T); % residuals of the fit: r(xi) = yi - f(xi)
Vave is a row vector of the average for each column
polyval(c,T) is a row vector of the curve fit evaluated at each of the measured T values.
Vave - polyval(c,T) is a row vector of residuals: the difference between the measured
(average) V values and the V values predicted by the curve fit.
The fit_thermistor_calibration function puts the curve fit and residual computation
and plot together in one m-file.
EAS 199B: Engineering Problem Solving page 19
Matlab Function for Curve Fit
function fit_thermistor_calibration(npoly,fname)
% fit_thermistor_calibration Polynomial curve fits of calibration data for thermistor
% ... See fit_thermistor_calibration.m for missing code to read data and compute Vave
% -- Perform curve fit
c = polyfit(T,Vave,npoly);
fprintf(’\nCurve fit coefficients\n’); fprintf(’\t%12.7e\n’,c);
% -- Plot the curve fit
Tfit = linspace(min(T),max(T));
vfit = polyval(c,Tfit);
subplot(2,1,1)
plot(T,Vave,’o’,Tfit,vfit,’r--’);
xlabel(’Temperature (C)’); ylabel(’Analog output’);
legend(’Data’,sprintf(’Degree %d poly fit’,npoly),’Location’,’Northwest’);
% -- Evaluate residuals at the known (measured) input values
rfit = Vave - polyval(c,T);
subplot(2,1,2)
plot(T,rfit,’o’);
xlabel(’Temperature (C)’); ylabel(’Residual of the fit’);
EAS 199B: Engineering Problem Solving page 20
Matlab Quadratic Curve Fit
fit_thermistor_calibration(2) produces a quadratic fit and a residual plot
0 10 20 30 40 50 60300
400
500
600
700
800
Temperature (C)
Ana
log
outp
ut
DataDegree 2 poly fit
0 10 20 30 40 50 60−5
0
5
10
Temperature (C)
Res
idua
l of t
he fi
t
EAS 199B: Engineering Problem Solving page 21
Matlab Quadratic Curve fit
Notice that the residuals appear to have a pattern.
The quadratic fit is missing information in the data.
0 10 20 30 40 50 60300
400
500
600
700
800
Temperature (C)
Ana
log
outp
ut
DataDegree 2 poly fit
0 10 20 30 40 50 60−5
0
5
10
Temperature (C)
Res
idua
l of t
he fi
t
EAS 199B: Engineering Problem Solving page 22
Matlab Cubic Curve Fit
fit_thermistor_calibration(3) produces a cubic fit. The residuals appear to be
random When the residuals are random, stop increasing the order of the polynomial.
0 10 20 30 40 50 60300
400
500
600
700
800
Temperature (C)
Ana
log
outp
ut
DataDegree 3 poly fit
0 10 20 30 40 50 60−4
−2
0
2
4
6
Temperature (C)
Res
idua
l of t
he fi
t
EAS 199B: Engineering Problem Solving page 23