Introduction: Fast Temperature Sensor
We all want to minimise our domestic energy costs and finding the especially cold walls, doors and air leaks around the house is a big help. A thermal camera is great for this, but a simple temperature sensor is a lower-cost alternative. It should be handy enough to sweep around, quickly checking for cold spots. Probes used for cooking are OK, but we can do better with DIY. The big problem is that most thermometers react very slowly in still air, perhaps 30s in each place, so not good for sweeping. What we need is a fast temperature sensor that reacts in a small fraction of a second.
Supplies
Finest possible wire (copper, gold, iron etc), ideally less than 25µm diameter. This is the hardest item to find. Try to repurpose a low current relay or a broken quartz watch drive-coil. I found a bit of gold chip bonding wire.
Resistors, metal film 50ppm/°C or better (100Ω, 2x 510Ω, 1kΩ ).
Capacitors (100nF, 2x1µF, 1000µF 6.3V).
Voltage reference or regulator, 3.3V or 4V (MP1700-3302 or similar).
Analog Digital Converter I2C (Adafruit ADS1115 16-bit 4-channel with PGA: # 1085).
Arduino Nano.
Single-supply Instrumentation amplifier (AMP04, AD623 or similar).
Stripboard.
Pushbutton.
Step 1: THE THEORY
Semiconductor temperature sensors such as LM35, TMP36 and similar are great and come pre-calibrated, for example with 10mV/°C. However, in plastic TO92 packages they are very slow. Metal packages are a bit faster, SMD packages faster still. You can also use small silicon rectifiers and LEDs in 0603 or 0402 format as temperature sensors. Thermocouples too can be small. All useful, but a simple resistance wire has been most successful for this job.
A fine metal wire has a large surface area to volume ratio, allowing it to heat and cool quickly. I found some gold wire with about 25 µm diameter. The resistance of this is ρL/A where ρ the material resistivity, L is the length and A the cross sectional area. My 20mm long gold wire has a resistance of about 1 Ω.
We can calculate the sensitivity of the wire from its temperature coefficient of resistivity. The gold wire’s resistance will change by about 1/290 of its value for every °C change – not much, but good enough. With a bit of amplification and/or a high resolution analog to digital converter (ADC) it should be usable. Let’s give it a go. You can equally use copper wire; the specs are similar.
Resistivity (Ωm) TempCo (/°C)
Gold 2.44 10^-8 0.0034
Copper 1.68 10^-8 0.0040
Step 2: THE CIRCUIT
We pass a stable current of a few mA through the wire and use an instrumentation amplifier to amplify the small voltage produced. Using two resistors R2/R3 raises the amplifier inputs to the middle of the supply range. Rg = 1kΩ sets the gain of 100, giving about 350 mV at the ADC input A0. For best noise rejection we use the ADC in differential mode – inputs A0 and A1 measure between amplifier output and the pin 4/5 ground. ADC range is set to ±1.024 V.
It is important that the current through the gold wire is quiet and stable. Hence we use a 3.3V regulator followed by a 1.6 Hz low pass filter. This does a good job of filtering the inevitable junk on the 5V supply from the Arduino and from the connected laptop.
Step 3: BUILD THE ELECTRONICS
These few components are quickly wired on a 10 hole-wide piece of stripboard. As I wanted to measure very close to cold surfaces such as a window the stripboard was carved to produce a fork with the wire soldered between the fork ends. Full metallic screening of the whole assembly would be ideal, but I just fixed a 27 mm wide piece of grounded clad epoxy circuit board under the stripboard. Flying leads to the ADC inputs were kept as short as possible.
Soldering the fine gold wire takes some practice, as gold is quite soluble in solder. One technique is to pre-tin the stripboard tracks and then lay the wire onto them. Then a quick touch of a soldering iron to the pad, NOT to the wire, allows the wire to settle into the molten metal. This works first time, most times.
Step 4: TEST THE ELECTRONICS
A good way to test the electronics is to connect a 1 Ω resistor in place of the wire. Quick tests with a multimeter should confirm correct operation. Measure 3.3 V at the regulator output, about 1.5 V at the wire terminals, 3.5 mV across the wire, 350 mV at the amplifier output.
Now load the Arduino code to read the two temperature channels. It is essentially just the Adafruit ADS1115 library example at https://learn.adafruit.com/adafruit-4-channel-adc-breakouts/arduino-code. The default gain is increased and differential measurements made using:
ads1115.setGain(GAIN_FOUR); // +/-1.024V
int16_t adc0 = ads1115.readADC_Differential_0_1();
int16_t adc1 = ads1115.readADC_Differential_2_3();
Run the basic code and check the returned values using the Arduino IDE facility Tools | Serial Monitor. Readings should be around 2^15 * 350/1024 or 10000. Now close the Serial Monitor and try Tools | Serial Plotter. The trace will show system noise. The trace fluctuation should be not more than three or four least-significant-bits (LSB), visible as clear levels like on the plot above. If it is greater than this then something is wrong. In particular, there should be no big periodic spikes due to the laptop. Otherwise check out the 3.3V regulator and low-pass filter.
If all is well solder the thin sensing wire and restart the Arduino plotter. You should see the stable LM35 output and the much noisier wire output. A finger near to the wire will instantly register on the plot. Place a thick cloth over the whole electronic assembly to reduce air currents and ensure that the trace settles down to the few LSB seen with the 1 Ω resistor.
If you are using the LM35 temperature sensor, this is conveniently calibrated as 10 mV/°C, so simple division of the ADC reading by 2^15/100 = 327.68 gives °C (in floating point arithmetic).
Step 5: CALIBRATION
If all you want is to measure relative temperature changes, then you can use the TempCo values given above. If the ADC reading is about 10000, then a 1°C change should change the reading by 10000x0.0034 = 34. If you need true temperature values make a calibration run as follows.
Find a block of metal big enough to take the stripboard. Heat it to the top of your desired range in warm water, say 35°C, place the stripboard temperature sensor on the warm block and cover with several layers of cloth or other insulating material. Run Serial Monitor and note the two temperature readings every few minutes as the block cools. When it is down to the lowest temperature, draw a calibration curve (true temperature versus wire reading) on paper or in a spreadsheet. It should be fairly linear. From the slope and the lowest point determine the formula that converts reading to temperature and add that to your code.
If you want to slow down the readings and dampen fluctuations, a sliding exponential filter is easy to implement. You need three float variables: Old, New and a variable α between 0.0 and 1.0. Initialise Old and New as 10000.0. Each time an ADC-reading is taken, calculate:
New = α x ADC-reading + (1 - α) x Old
Output the New value to the Serial Plotter. Then set Old = New. If α is close to 1.0 the Current value reacts quickly to changes – it essentially tracks the instantaneous temperature. When α is close to 0.0 New reacts very slowly, like after a low-pass filter. This is useful during calibration to average out fast fluctuations and is perhaps easier to implement than a sliding average.
Step 6: GOING FOR SPEED
For now, however, we are interested in a fast response. Looking at the output of the instrumentation amplifier on an oscilloscope we can estimate the cooling time constant in still air. Place a soldering iron a few mm from the wire. Set the oscilloscope to 50 ms/division and quickly more the iron away from the wire. Setting the scope to Normal triggering will show the roughly exponential decrease in output voltage. Estimate the time constant from the initial slope of the curve and the time it takes to reach final value. I estimated about 75 ms.
Alternatively set the Adafruit ADS1115 breakout board to its fastest sampling rate, 860 samples per second (sps). Repeat the close encounters with a finger or soldering iron. Each sample in the plot above takes 7 ms, so the time constant can be estimated to be about 35ms. However, the air in this case is probably not quite still. For most domestic applications the default mode of 8 sps is quite well matched to the wire and is fast enough.
Step 7: WHAT ELSE?
The fine wire temperature sensor running Serial Plotter does a good job of scanning around a room for cold drafts, areas of ceiling which are lacking insulation and uncomfortable temperature stratification from floor to ceiling. Alternative displays can be a character OLED showing the temperature in °C, an analog meter (much better), a large LED bar-chart or a graphical OLED.
There is one more useful modification. To measure temperature we used a wire current of a few mA to minimise self-heating. If instead we use 100 mA or even the most before the wire fuses (~450 mA for this wire), wire temperature becomes very sensitive to air currents – we have a “hot-wire anemometer”. Clearly the circuit will have to be modified, resistors changed, amplifier gain reduced and the voltage reference perhaps changed. This configuration is also useful in detecting air leaks, wind speed and in many scientific studies. We will save this for another Instructable.
Links:
https://en.wikipedia.org/wiki/Electrical_resistivity_and_conductivity
https://www.adafruit.com/product/1085
https://github.com/adafruit/Adafruit_ADS1X15
https://learn.adafruit.com/adafruit-4-channel-adc-breakouts/
https://learn.adafruit.com/adafruit-4-channel-adc-breakouts/arduino-code