Thermistor calibration.¶
Step 1: Calibration data collection¶
- Use your therm_plotter.ipynb script to help you make a file of datetime, temperature, and resistence.
- Place your thermistor in the bath and then start logging with your thermplotter.
- Collect measurements of Resistence in a bath of ice water. Collect a minimum of N = 100 measurements over several minutes. This means your delay() should be 1 second or so.
- Move your thermistor to the other bath and collect measurements of Resistence in boiling water. Collect a minimum of N = 100 measurements over several minutes.
- Save the data in a .csv file for loading with this .ipynb.
- Plot the data and check that it is clean, no spikes or intermediate temps. Cut away the bad data as needed.
- Create an dataframe of $T_{Reference}$ that matches the resistance data you collected at 0 and 100 C.
- Use a curve fitting algorithm (curve_fit() in Python, nls() in R) or the least-squares solution below to determine the new fit coefficients in the Steinhart-Hart equation. These take an objective function - a module with the Steinhar-Hart equation programmed in.
- Quantify the goodness of fit using Pearson's Correlation Coefficient.
Step 2: Complete this worksheet.¶
You will use the measurements of temperature and resistance to determine your own value of a,b, and c from the Steinhart-Hart equation:
$$ \frac{1}{T_{bath}} = a + b \cdot log_e(R) + c \cdot log_e(R)^3 $$Use the Steinhart-Hart equation. Solve for the three coefficients, a, b, c that are in the Steinhart-Hart equation.
NOTE: The output for the Steinhart-Hart equation is in Kelvin, so you should use Kelvin when generating a,b,c, but report your values of temperature in deg C.
###/////////////// Python /////////////
# Load the libraries we need.
# import numpy as np
# import pandas as pd
# import matplotlib.pyplot as plt
# import datetime as dt
# import numpy.linalg as linalg
# from scipy.optimize import curve_fit
#%matplotlib qt
#from matplotlib.dates import DateFormatter
#myFmt = DateFormatter("%H:%M")
###/////////////// R /////////////
#library(tidyverse)
#library(lubridate)
#library(xts) # adds ability to merge data frames on date.
#library(dplyr)
#library(zoo)
#library(patchwork)
# Load your recorded measurements and plot the time series to confirm clean data.
# df = pd.read_csv(filename, parse_dates=[0]); # Note, use the parse_dates input to tell pandas which column has
# datetimes in it.
# df.info() # Python
# summary(df) # R
# Load the calibration data with pd.read_csv() or read.csv() in R.
# Plot the Resistance vs. datetime to determine if there is some data that needs to be cut out.
Clean up your data as needed¶
(if your data is already clean, proceed).
# Cut out bad data points from the beginning and end, or from the transition between ice bath and boiling bath.
# These bad data will introduce bias into your results.
# Note, R and pands lets you compare datetime values against text strings, e.g. df['time'] > '2021-10-19 09:51:00' to
# make a boolean array and eliminate rows where the boolean array is false.
# cut = (df['time'] > '2021-10-19 09:51:00') & (df['time'] < '2021-10-19 09:53:00')
# df.drop(df.index[cut])
What is $T_{Reference}$?¶
We explicitly chose to calibrate in boiling and icy water, because we know the temperature at these two phase transitions, on the celcius scale without having to measure it. Therefore, these are the values of $T_{Ref}$. You need to create a column vector, called $T_{Ref}$. Every row (time) that you measured $R_{100}$ the value of $T_{Ref}$ should be 100. Every row (time) that measured $R_0$, the value of $T_{Ref}$ should be 0.
Hint: If you also measured temperature, you can round to the 10's place to create a vector or 0 and 100 that matches your measured resistences.
Tbath = np.round(df['Temp'],-1)+273.16;
Fit the model using the Resistence and $T_{Ref}$ data.¶
Choose one of the two approaches:
Use curve_fit() from scipy.optimize. Refer to the Scipy help for details of curve_fit()
solve the linear algebraic equation below, with design matrix A. Assemble the elements of $ x = \left(A^TA)^{-1}\times A^T T_{bath} \right) $. The columns in A are a column of 1's and a column of measurements of $R_{100}$ and $R_{0}$, or resistance at 100 and 0 celcius. Talk to Brice, he can help you set this up.
# Choice 1, define the objective function, which defines the inputs to the Steinhar-Hart equation. You will pass
# this function to curve_fit. You can name this function, what you want.
# https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html
# Make a column vector with values of TRef.
# Define an R data frame or pandas pd.series() of values of Resistence from the bath calibration.
# You will input these to curve_fit()
# Set up and solve the curve_fit. Capture the values of a,b,c which are output from curve_fit()
# pp,__ = curve_fit(objective_fun,R, 1/TRef). # In Python
# fit <- nls(1/TRef ~ steinhart_hart(R, A, B, C), start = list(A = ..., B = ..., C = ...))
# Extract the fitted parameters
# coef(fit)
# a,b,c = pp
# print(a,b,c)
# Choice 2, use linear algebra to solve for a, b, c where
# x = [a,b,c]^T
# A = [1, np.log(R_i), np.log(R_i)^3]
# x = inv(A^T*A)*A^T*TRef
# Assemble the columns of the design matrix, A.
# Use linalg.inv() and np.matmul() to carry out the matrix multiplication.
Plot and quantify the fit.¶
# Model the temperature.
# Use your measured resistences and the new S-H coefficients (A,B,C) that you determine from the calibration to compute
# Tmod, the modeled temperature.
# Make a plot of Resistance vs. Tref and Resistence vs. Tmod. Are the modeled values visually consistent?
Compute and report the Pearson correlation coefficient to show how well your curve fits to the data.¶
$$ R^2 = 1 - \frac{SS_{Residual}}{SS_{Total}} $$$T_{mod}$ = Temperature you get from using the new A, B, C's with the Steinhar-Hart Equation.
$T_{Ref}$ = Reference temperatures in the bath at 0 and 100 C.
$\overline{T_{Ref}}$ = Mean of the Reference temperatures.
$SS_{Residual} = \sum_{i=1}^{N} (T_{mod,i} - \overline{T_{ref,i}})^2$
$SS_{Total} = \sum_{i=1}^{N} (T_{Ref,i} - \overline{T_{Ref}})^2$
What to turn in? Turn in your completed .ipynb and make sure to attach the files containing data you recorded during the calibration in class.