Today’s lecture in BME 101 (the Applied Electronics for Bioengineers class) went very smoothly. I started with a little light entertainment: a video about blowing up capacitors, sent to me by Jameco: http://www.jameco.com/Jameco/content/incorrectly-using-capacitors.html This video reinforced the message that I had given them in lab last week about electrolytic capacitors.
I had two topics to cover: the optimization problem from last weekend’s homework, which only one student had managed to do, and model fitting to extract parameters for the thermistor model from the data collected in lab yesterday.
I gave the students the choice of order for the topics, and they wanted the optimization first. The problem is fairly straightforward from an engineering standpoint: we want to maximize the sensitivity of the circuit that converts temperature to voltage at a specific operating temperature Topt. I first sketched very rough plots of what the voltage would look like as a function of temperature: monotone increasing but not particularly linear. I reminded them that sensitivity is the change in output that you get for a given change in input: dV/dT. I coaxed out of the class the idea that to maximize the function dV/dT, we need to take its derivative and set it to 0: . We only have one free variable in our circuit to change (the load resistor R), so we need to take that equation and solve it for R, to get the value of R that maximizes sensitivity.
I reminded them of the simple model for the resistance of a thermistor that we’d had on Monday: , and they had no trouble coming up with the equation for the output voltage . I then suggested using Wolfram Alpha to solve the equation, and switched from the chalkboard to the screen to type
solve d^2 (R/(R+S e^(B/T)))/ dT^2 = 0 for R
(changing R∞ to S, to avoid confusing Wolfram Alpha with subscripts).
Wolfram Alpha conveniently replied with two solutions: R=0 (which would result in a constant 0 output voltage, clearly a minimum sensitivity) and . I pointed out that the first part was just the resistance of the thermistor at the temperature we were optimizing for, and the second term scales that down a little.
We then moved on to fitting the model. I showed three data sets that students had sent me—one which was a little messy, but still quite usable, one that was a little better, and one that was really beautiful. I continued with the really good data set. I explained that gnuplot tries to minimize the error on the y-axis for a function of things on the x-axis, and the students decided that minimizing the temperature error for a given resistance was probably best here. (I suspect it doesn’t make much difference with this data, but it is good to get them to think about that as a decision that needs to be made for each modeling problem.)
On the board, I turned around the equation for the model, to get temperature in terms of R: .
I then developed the gnuplot script for the problem live, debugging as I went. Some of the errors to debug were ones I introduced deliberately, others were inadvertent, but all were good for teaching both the process of debugging and the notion of doing sanity checks. My first mistake was an inadvertent one: I capitalized a variable differently in the parameter list and in the function body, and gnuplot is case-sensitive. This was very easy to find and fix, and gave me an opportunity to tell students that gnuplot was sensitive to case, since that had not come up previously. My second mistake was a deliberate one: I typed in the model exactly as we had derived it on the board, knowing full well that the model was for °K, but the data was for °C. I’d even reminded students of that earlier, when we were doing the optimization problem.
I then ran the fit in gnuplot and asked students if we were done, or if there was a sanity check we could do. A couple of them asked if we could plot the model and the data on the same plot, so I did that. The fit was very obviously completely wrong. So I asked the students what was wrong and how we could fix it. I did dice-assisted cold calling to put 3 or 4 students on the spot, getting not very useful answers, then took answers from a couple of students who raised their hands. The second student pointed out the °C vs °K problem.
So I fixed the formula and ran the fit again, expecting everything to work fine. It didn’t! So we went into debugging mode, trying to see if starting with better estimates of B and R∞ would help. Nope. Then I realized that I had made a second inadvertent error: I’d put in 273.15 with the wrong sign! I fixed that, ran the fit again, and again things failed (producing negative values for R∞). This time, though when I put in better initial estimates, everything converged to a very good fit, which gave me a teachable moment about the need to have decent estimates before fitting, so that the optimization algorithm that did the fitting could converge.
The final script was
temp(R,B,Rinf) = B / ( log(R) - log(Rinf)) - 273.15 B=3000; Rinf=1e-4 fit temp(x,B,Rinf) 'student-thermistor-data-3.txt' using 2:1 via Rinf,B plot 'student-thermistor-data-3.txt' using 2:1, \ temp(x,3435,10*exp(-3435/(25+273.15))), \ temp(x,B,Rinf)
The second curve of the plot is using the data sheet values for the B value and for R25°C=10kΩ.
Here is the plot produced:
The model fit is slightly better than the data sheet values, but the data sheet values were closer than I had expected based on previous years’ fits. I think that it may be that the students had a properly calibrated thermometer (I’d removed any digital thermometers that reported ice water as warmer than 0.5°C—about 1/3 of them were that far out of calibration), and that this particular pair of students had been very careful with their measurements.