OWL2 to LM34 & AD590 temperature sensors
We offer both a field-ready probe (TF for Fahrenheit
and TC for Celsius) and do-it-yourself kit of parts
for cable mounting the LM34 or LM35 temperature sensors from
National Semiconductor. The sensor has the following
characteristics:
We usually recommend using the TF probe to cover the biological temperature range due to fact that the range that extends below freezing. It is easy to convert to Celsius in software if necessary. (Celsius=Farenheit -32 * 5/9)
gosub ADread ' result in millivolts degF=result ' degree F * 10, 1/8 degree resolution degC=degF*5/9-178 ' convert to degrees Celsius * 10 debug REP "-"\degC.bit15,DEC abs degC,".",SDEC1 degC
There are other ways to do the computation. The subtraction is done after the multiplication and division sot that it will handle temperatures down to -17.8 Celsius. (The stamp does not divide negative numbers properly.) The DEBUG statement prints out the value, and it is complicated by the need to display negative values for Celsius, with one decimal point and the tenths.
For temperature measurement, one classic sensor is the AD590 (metal can or ceramic flatpak) or AD592 (plastic TO92), from Analog Devices. The sensor has the following characteristics:
The AD590 or AD592 may be used with BASIC stamp in a couple of ways. The most accurate is to use a 12-bit or better A/D converter. The other way, less accurate but very easy to implement, is to use the RCtime command of the BASIC Stamp 2. The stamp measures the time it takes for the current from the sensor to charge a capacitor up to the switching threshold of the Stamp input pin. Details for both configurations follow:
+5 to + 15 volts ----------------------; + AD590 ;--------------' - | stamp P5 ---/\/\----| 100 | --- 0.1uF --- | common ------------'
The AD590 connects from the + power supply to the input pin. The 0.1 uF capacitor connects from the pin to common. The 100 ohm resistor is there to protect the stamp input pin from insults that might come down the sensor line, and to limit the capacitor discharge current. In operation, the pin starts out as an output, and the capacitor is discharged to zero volts. When the RCtime command operates, the pin switches to in input and the capacitor charges at a rate determined by the AD590 temperature. The RCtime command measures the time necessary for the voltage to rise from zero up to the 1.3 volt pin threshold. Then the pin is turned around to be an output again, and the process repeats the next time the program commands it. The 100 ohm resistor introduces a small scale error, because the current from the AD590 passes through that resistor while the capacitor is discharging. This will cancel out during the calibration procedure.
cal con 64020 ' calibration constant to be determined X var word ' raw count from RCtime, 2uS resolution kelvin var word ' kelvin temperature degC var word ' temperature in 'C degF var word ' degrees Fahrenheit low 5 ' initial discharge the capacitor on p5 loop: RCtime 5,0,X ' get charging time low 5 ' discharge the capacitor Kal = X*273 kelvin = cal/X degC = kelvin-273 ' calculate temperature degF = kelvin *9/5 - 460 debug cls,? X,? Kal,? kelvin,? degC, ? degF ' show raw count, and temperatures (positive display only) pause 2000 ' 2 second delay for demo goto loop
To calibrate the sensor, put it in ice water (in a thermos bottle if possible!), allow it to equilibrate, and read the value of X. Multiply that times 273. This is the number you should substitute for the constant "cal" in the program. If, for example, you read X=230 with the probe in an ice bath, use 230*273=58695 in the program instead of 62790. The program shows you the value of Kal. Once you substitute the new value, the temperature should read correct (+/- 1 degree C), for any value of temperature.
The theoretical charging time is given by:
2*rct = 1.3 * 106 * C / K
where
2*rct = time as measured in microseconds (2*rct) or in RCtime count (rct) The RCtime command counts in units of 2 microseconds 1.3 = the triggering threshold for RCtime, in volts. the threshold has a small negative temperature coefficient. C = capacitance in microfarads K = temperature in Kelvin
Combining the constants, and assuming C=0.1 microfarad:
rct = 65000/K
This assumes that the constants all have their nominal values. In actual situations, the capacitor will not be exactly 0.1 microfarad, the PIC threshold will not be exactly 1.3 volts, and the AD590 response will not be exactly 1 microamp per Kelvin. But in any case, the response is given by
rct = constant/K
And the constant can be determined by one calibration point for reasonable accuracy commensurate with 1 degree Celsius resolution. The value of rct will be about 238 when the temperature is 273 Kelvin (0 degrees Celsius). So each change in rct value amounts to a little more than one degree Celsius.
You can improve the resolution considerably by increasing the value of the capacitor to 0.22 uF or 0.33 uF. The numbers returned by RCtime will be larger, and there will be more steps (more resolution) over a given termperature range.
Suppose that you use a 0.22uf capacitor, and at 273 Kelvin (0 degrees C) you find a number from RCtime of 497. Then 273*497=135681. (The theoretical value is 143000.) This number is larger than the stamp can deal with in one word. The above program will not give the correct result. To compute this, you can use extended division:
Kelvin = 13568/X*10+(13568//X*10+1/X) ' Kelvin ' resolution 1.0 Kelvin degC = Kelvin - 273 ' degrees Celsius degF = Kelvin * 9/5 -460 ' Fahrenheit
This is a a kind of long division. The five most significant digits (13568) appear in two places, in a first division, (13568/X) to determine the most significant digits of the quotient, and then in the remainder term, (13568//X). The least significant digit is added onto the remainder, (13568//X*10+1/X) in a second division that determines the least significant figure of the quotient.
The above formula resolves the result to 1 degree. Use the following formula to resolve to 0.5 degree:
Kelvin = 13568/X*20+(13568//X*10+1*2/X)*5 ' Kelvin ' resolution 0.5 Kelvin degC = Kelvin - 2730 ' Celsius * 10 to units of 0.5 degree degF = Kelvin * 9 +25 /50 -460 ' Fahrenheit rounded off to 1 degree
There is a limit to the accuracy though, using the RCtime command, due to thermal drift in the PIC pin threshold, and noise.
In some cases it may be desireable to implement automatic calibration, where the user can press a button or enter a special routine that determines the calibration constant. All that is required is that the sensor be held at a reference temperature. This can be an ice bath a 273 Kelvin, or it can be a temperature bath being monitored by a reference thermometer being read by the BASIC Stamp. Call this Tref. The count returned by the RCtime at that temperature is rct. For the best accuracy, the calibration constant will in general be a double precision value, for example, 273*497=135681. What we need are the two values that appear in the equation just above. The easiest way is to rearrange the calculation as follows:
273*497 = 273*(49*10+7) X=497 X/10=49 X//10=7 = 273*49*10 + 273*7 = 13377*10 +1911 X/10*273=13377 X//10*273=1911 = 13377*10 +191*10 +1 X//10*273/10=191 X//10*273//10=1 = 13568*10 +1 X/10*273+(X//10*273/10)=13568 ^^^^^ ^ Kal1 Kal0
The following program starts off with a certain calibration constant in the data memory. The program reads the calibration constant and uses it to show the temperature in Kelvin and in degrees Celsius. Suppose you equilibrate the probe in an ice reference bath, and then push a button, which is the event that causes the program to branch to the "calibrate" routine. There the program calculates a new calibration constant, based on the assumption that the current temperature is equal to the reference temperature. New values of the calibration constants are written into the data memory. The program then continues, now using the new constants. The program shows how to read and write a word+ value in the data memory, as well as how to calculate the calibration value on the fly.
Tref con 273 ' reference temperature for calibration eKal1 data word 13568 ' calibration constant most significant digits eKal0 data 1 ' ditto, least significant digit Kal1 var word ' for calibration Kal0 var nib ' ditto X var word ' raw count from RCtime, 2uS resolution degC var word ' temperature in 'C K var word ' temperature in Kelvin dirs=$0000 ' initial discharge the capacitor loop: RCtime 5,0,X ' get charging time low 5 ' discharge the capacitor read eKal0,Kal0 ' get calibration factor, ones digit read eKal1,Kal1.byte0 ' calibration factor, byte0 of word read eKal1+1,Kal1.byte1 ' ditton, byte 1 of word K = Kal1/X*10+(Kal1//X*10+Kal0/X) ' Kelvin degC = K-273 ' degrees Celsius ' degrees Celsius debug home,dec? X,dec? K,sdec? degC ' show count & temperatures debug dec5 Kal1, dec1? Kal0 ' show calibration constants pause 500 ' .5 second delay for demo if event then calibrate ' write new calibration on event goto loop ' continue the demo calibrate: ' write the new calibration constants. Kal1=X/10*Tref+(X//10*Tref/10) ' new calibration constants Kal0=X//10*Tref//10 debug dec5 Kal1, dec1? Kal0 ' show new calibration constants write eKal0,Kal0 write eKal1,KAl1.byte0 write eKal1+1, Kal1.byte1 goto loop
On the OWL2c, with the AD590, a 10k½ termination resistor, a >9 volt power supply, and a 12 bit A/D converter referenced to 5.12 volts, it is possible to get a resolution of 1/8'C for temperatures up to 100'C. With a 6 volt supply and a 4.99kohm termination, the resolution is limited to 1/4'C. The termination resistor is limited by the requirement of keeping at least 4 volts across the AD590 sensor element.
+5 to + 15 volts ----------------------; + AD590 ;--------------' - | ADC input -;-/\/\----| | 100 | | \ --- .1 / 4.99kohm --- \ | | common --'---------'
The output across the 4.99k resistor is 5 millivolts per Kelvin. The resistor value can be trimmed for the specific sensor, or each sensor can be provided with its own calibration constant to be entered into software.
Calibration of the resistor: Equilibrate the sensor in an ice bath, and then trim the resistor value so that the program outputs zero degrees C, or 273 Kelvin.
ADch=5 gosub ADread0 ' get count, 1 count=1.25 millivolts=0.25 Kelvin degC=result*25-27300 debug dec degC/100,".",dec2 degC," degrees Celsius"
Calibration in software. The factor Kal is the correction factor, expressed as Kal/65536. For example, 0.987 is approximated as 64684/65536. Or 1.022 would be 1 + 1442/65536
ADch=5 gosub ADread0 ' get count, 1 count=1.25 millivolts=0.25 Kelvin degC=result**64684*25-27300 ' example where correction is *0.097 'degC=result**1442+result-27300 ' example where correction is *1.022 debug dec degC/100,".",dec2 degC," degrees Celsius"
This shows the result to a resolution of 0.25 degrees C. It is possible to calculate and store these calibration factors in memory automatically, in a manner similar to the case of RCtime. For example, if the reference temperature is 273 Kelvin, and the uncorrected reading is 274.25 Kelvin, then the calibration constant is:
274.25 * (Kal/65536) = 273 Kal=27300 * 65536 / 27425
This must be calculated using long division. Note that our binary long division routine automatically includes the factor of 65536. Once the Kal factor is determined, it can be written to the data memory.
In many cases it may be desireable to have one side of the temperature sensor grounded. The OWL2c provides a reference voltage output of 5.12 volts, and the sense resistor can be returned to that point:
+5.120 volts -,---------,---------- | | | | | \ --- .1 / 4.99kohm --- \ | 100 | ADC input -;-/\/\----'---------******* *AD590* common -----------------------*******
The signals are now all referenced to the 4095 count at 5.120 volts:
ADch=5 gosub ADread0 ' get count, 1 count=1.25 millivolts=0.25 Kelvin result=4096-result ' invert sense of result degC=result*25-27300 debug dec degC/100,".",dec2 degC," degrees Celsius"