SPLat Logo

Display temperature in 3 lines of code

NOTICE: SPLat Controls has moved. We are now at 1/85 Brunel Rd, Seaford, 3198. map

NTC (Negative Temperature Coefficient) thermistors are resistors that exhibit large changes in resistance with varying temperature. Because they change a lot, they are easy to interface into an analog input. The only drawback is that they are very nonlinear. This EasyStep shows you how easy it is to handle a thermistor with the EC1.

It should take you way less than an hour to do this EasyStep, depending on how deeply you delve into the SPLat code. The screen shot below shows you the end result displayed on the PC screen, using the SimpleHMI function in SPLat/PC.

What you will need (in addition to an EC1!)

Rather than separate thermistor and resistor I used a little module I happened to have, like this. It came in this collection (middle of bottom row in the photo). You don't need a module, though, it's just a bit easier to wire. A separate thermistor and resistor will do just fine, providing you have the capacity to hook them up.

Thermistors still give the best bang per buck in terms of accuracy. You can buy a 10KΩ, 5% thermistor for well under a dollar. As a rough rule of thumb, the temperature error in °C is about the half the percentage tolerance of the device. Don't fret too much over accuracy; if you need good accuracy, say for fermentation control, you should in any event calibrate your system.

Wiring it up

The illustrations below show the connections for my module on the left, and for breadboarding a thermistor and resistor on the right. The wire colours are the same in both

    

The resistor and thermistor form a simple voltage divider, with the thermistor in the lower leg. At 25°C the thermistor resistance is 10KΩ, so the analog input voltage will be exactly half the supply voltage. Under those conditions an fAnIn 0 instruction will return the number 0.5. If the thermistor is heated up, its resistance will drop, the analog input voltage will drop and the number returned by fAnIn 0 will get smaller. From there it is a "simple" matter to calculate the temperature.

The source voltage for the voltage divider is the EC1's 3.3V supply. That is the same voltage that is used as the reference voltage for the EC1's analog to digital converter. This means the measurement is ratiometric. The analog reading will not change with variations in the 3.3V (nominal) supply, because the analog reading is just the fraction of the reference voltage seen at the analog input pin.

What the program does

Those are the primary functions. They take 3 lines of code. However it does some other smart stuff as well:

To run the program

I am going to introduce this program in several easy stages, to make it as easy as possible for you to understand the explanations. If you are impatient and just want an end result, you can run the full program now and take it for a spin. Later I will break it down into small bite sized chunks, and show you that just 8 lines of code perform the basic measurement and display.

To install and run the full program:

Note: If the reading goes the wrong way, i.e. reduces when you heat the thermistor, and you are using a module similar to mine, try swapping the red and black wires. If it is still behaving strangely, use an ohmmeter to find the pair of pins with >12KΩ between them at room temperature. Those two pins should be red and black. Try either way around for those two, and swap if the reading goes the wrong way when you heat the thermistor.

The program stage 1

The very basic program is listed below. To show/hide the program listing click here. There are pop-ups for each major functional block of code, and clickable links on individual instructions that take you to the formal descriptions of the instructions.

;[...]

Place your mouse over the ;[...] to see the pop-up.

;--- Simple NTC thermistor temperature measurement ---- 
; This is the very basic program, with no filtering.
; It takes 3 lines of code (flagged like this [3]) to read the thermistor, convert to °C and display the result

;[...]
aiTherm         EQU     0       ;define the analog input being used  
HMIPort         EQU     251     ;Declare the serial port we are using to display readings = USB -> SPLat/PC SIO window
oGreenLed       oEQU    0       ;Name the output that controls the green LED on the EC1
iButton         iEQU    0       ;Name the input on the EC1 that has a push button

;[...]
# Open_Serial Port(HMIPort) User(38400,8,N)    ;Open the serial port

;[...]
        LaunchTask      ReadTherm 
        LaunchTask      KillSwitch 
        LaunchTask      HeartBeat
        RunTasksForever

;------------ Thermistor temperature measurement and display
ReadTherm: 
        fAnIn           aiTherm    ;Read raw thermistor voltage to W                                            [1]
;[...]
# Thermistor Params(10000, 3840) Theta(1) Feed(3.3, 3.3, 10000) RangeC(0, 80) Order(5) ;Display(12) ; °C in W   [2]
;[...]
# HMI   Port(HMIPort) Cursor(0,0) fDispW(5, 1) Text("°C    ")     ;Display °C                                   [3]
        Pause           10         ;Do it 10 times per second
        GoTo            ReadTherm  ; Do it all over again

;--------------------------------------------------------------------------        
;[...]
KillSwitch:
        WaitOnK         iButton
Die:    GoSub           Die

;--------------------------------------------------------------------------        
;[...]
HeartBeat:
        On              oGreenLed
        Pause           5
        Off             oGreenLed
        Pause           95
        GoTo            HeartBeat      

Stage 2 - Filtering the results

If you run the basic stage 1 program above (go ahead, copy/paste it into SPLat/PC), you will observe that the readings fluctuate quite a lot, sometimes by several tenths of a degree. This fluctuation is caused by circuit noise, electrical interference that can be very hard to eliminate. The next thing I am going to do is add a filter that will calculate a running average of many readings, in order to minimise the effect of the noise.

To show/hide the program listing click here. I have bolded the new bit.

;--- Simple NTC thermistor temperature measurement ---- 
; This version adds filtering to the result, to reduce the noise.

;[...]
aiTherm         EQU     0       ;define the analog input being used  
HMIPort         EQU     251     ;Declare the serial port we are using to display readings = USB -> SPLat/PC SIO window
oGreenLed       oEQU    0       ;Name the output that controls the green LED on the EC1
iButton         iEQU    0       ;Name the input on the EC1 that has a push button


;[...]
# Open_Serial Port(HMIPort) User(38400,8,N)    ;Open the serial port 
                                                                                                       
;[...]
        LaunchTask      ReadTherm
        LaunchTask      KillSwitch 
        LaunchTask      HeartBeat
        RunTasksForever 

;------------ Thermistor temperature measurement and display
ReadTherm: 
        fAnIn           aiTherm    ;Raw thermistor voltage to W 
;[...]
# Thermistor Params(10000, 3840) Theta(1) Feed(3.3, 3.3, 10000) RangeC(0, 80) Order(5) ;Display(12) ; °C in W  
;vvvvvvvv  Noise filter vvvvvvvvvvvv
;[...]
kFactor    fEQU         100        ;Filter constant. Bigger number = heavier filtering
fTempOld   defFLOAT                ;Stores the "old" (long term average) reading
fTempNew   defFLOAT                ;Temporary storage for the current reading
        fStore          fTempNew   ;Save for use later
        fLoadQ          kFactor    ;The filter constant
        fRecallW        fTempOld   ;Old value
        fMul                       ;Old x Factor
        fRecallQ        fTempNew   ;New
        fAdd                       ;(Old * Factor) + New
        fSwap                      ;Move it to Q
        fLoadW          kFactor    ;Filter factor
        fInc                       ;Filter factor + 1
        fDiv                       ;((Old * Factor) + New) /  (Filter factor + 1)   = New value
BigJump:        
        fStore          fTempOld   ;Save for next time
;^^^^^^^^  Noise filter  ^^^^^^^^^^^^^^^
;[...]
# HMI   Port(HMIPort) Cursor(0,0) fDispW(5, 1) Text("°C    ")     ;Display °C 
        Pause           10         ;Do it 10 times per second
        GoTo            ReadTherm  ; Do it all over again  

;--------------------------------------------------------------------------        
;[...]
KillSwitch:
        WaitOnK         iButton
Die:    GoSub           Die

;--------------------------------------------------------------------------        
;[...]
HeartBeat:
        On              oGreenLed
        Pause           5
        Off             oGreenLed
        Pause           95
        GoTo            HeartBeat      

Go ahead and copy/paste the filtered version into SPLat/PC and run it in your EC1 board. Notice it takes quite a while for the result to rise to its full value and settle. But once it is settled, it will not have all the random fluctuations of the earlier version.

State 3 - Speeding up the filter

The filter was great at reducing the noise, but cost us quite dearly in terms of response time. The next (and final) version of the program overcomes much of the slowdown introduced by the filter. It does this by comparing each new reading with the old filtered result. If the change is more than one degree it forces the end result to equal the new reading.

To show/hide the program listing click here. I have bolded the new bits, including some added code for displaying °F.

;--- Simple NTC thermistor temperature measurement ---- 
; This version has filtering plus rapid step response.

;[...]
aiTherm         EQU     0       ;define the analog input being used  
HMIPort         EQU     251     ;Declare the serial port we are using to display readings = USB -> SPLat/PC SIO window
oGreenLed       oEQU    0       ;Name the output that controls the green LED on the EC1
iButton         iEQU    0       ;Name the input on the EC1 that has a push button


;[...]
# Open_Serial Port(HMIPort) User(38400,8,N)    ;Open the serial port 
                                                                                                       
;[...]
        LaunchTask      ReadTherm
        LaunchTask      KillSwitch 
        LaunchTask      HeartBeat
        RunTasksForever 

;------------ Thermistor temperature measurement and display
ReadTherm: 
        fAnIn           aiTherm    ;Raw thermistor voltage to W 
;[...]
# Thermistor Params(10000, 3840) Theta(1) Feed(3.3, 3.3, 10000) RangeC(0, 80) Order(5) ;Display(12) ; °C in W
          fStore          fTempNew   ;Save the new C reading  
;vvvvv  Rapid step response vvvvvvvv
kChangeLim    fEQU      1          ;This number of degrees change is treated as a genuine step change
        fRecallQ        fTempOld   ;The old value
        fSub                       ;Calculate the change since last time
        fAbs                       ;Absolute value of the change
        fLoadQ          kChangeLim ;Value to compare with
        fTestWgtQ                  ;Test if change > limit
        fRecallW        fTempNew   ;Get back the new reading, in case we jump next
        GoIfT           BigJump    ;g/ the test showed change > limit
;^^^^^   Rapid step response ^^^^^^^^^
;vvvvvvvv  Noise filter vvvvvvvvvvvv
;[...]
kFactor    fEQU         100        ;Filter constant. Bigger number = heavier filtering
fTempOld   defFLOAT                ;Stores the "old" (long term average) reading
fTempNew   defFLOAT                ;Temporary storage for the current reading
        fLoadQ          kFactor    ;The filter constant
        fRecallW        fTempOld   ;Old value
        fMul                       ;Old x Factor
        fRecallQ        fTempNew   ;New
        fAdd                       ;(Old * Factor) + New
        fSwap                      ;Move it to Q
        fLoadW          kFactor    ;Filter factor
        fInc                       ;Filter factor + 1
        fDiv                       ;((Old * Factor) + New) /  (Filter factor + 1)   = New value
BigJump:        
        fStore          fTempOld   ;Save for next time
;^^^^^^^^  Noise filter  ^^^^^^^^^^^^^^^
;[...]
# HMI   Port(HMIPort) Cursor(0,0) fDispW(5, 1) Text("°C    ")     ;Display °C 

        fLoadQ          1.8        ;Converting to °F
        fMul
        fLoadQ          32
        fAdd
# HMI  fDispW(5, 1) Text("°F")    ;Display °F

        Pause           10         ;Do it 10 times per second
        GoTo            ReadTherm  ; Do it all over again  

;--------------------------------------------------------------------------        
;[...]
KillSwitch:
        WaitOnK         iButton
Die:    GoSub           Die

;--------------------------------------------------------------------------        
;[...]
HeartBeat:
        On              oGreenLed
        Pause           5
        Off             oGreenLed
        Pause           95
        GoTo            HeartBeat