SteinHartEquation

A Thermistor linearisation program using a Stein-Hart equation, originally written for the PROTON compiler by Les Johnston

// LCD proton development board
    #option LCD_DATA = PORTD.4
    #option LCD_RS = PORTE.0
    #option LCD_EN = PORTE.1

    Include "LCD.bas" 
    Include "math.bas"
    Include "ADC.bas"
    Include "convert.bas"

{
 Thermistor linearization using a Stein-Hart equation
 based on a program written for the Proton compiler By
 Les Johnston

 The Program below is based On a 10K Ohm resistor As part of the thermistor's circuit: -

  +5 Volts
 --------
    |
    \
    /  10k Ohm 1% (Or better) Resistor
    \
    /
    |
    o-------------O To PORTA.0 of the PICmicro
    |
    \
   o/
    \  Thermistor
    /
    |
    |
  -----
   ---
    -

 The Stein-Hart linearising equation below is only suitable For describing a restricted range around 
 the rated TEMPERATURE Or RESISTANCE with sufficient accuracy.

 1
 Tt = ------------------------
 1/B * LN(Rt/R25) + 1/T25

 The B values For common NTC thermistors range from 2000K through To 5000K.
 For this application, the popular, And more complicated, Stein-Hart equation is more accurate.

 The thermistor used did Not provide the B value within its datasheet, but did give the T25 value. 
 i.e. RESISTANCE At 25 degrees Centigrade.
 To calculate the B value use the equation below.

 Tt * T25 R25
 B = ---------- * LN ------
 Tt - T25 R100

 Or: -

 (25 + 273.13) * (100 + 273.15) R25
 B = -------------------------------- * LN ------
 75 R100

 giving: -

 R25
 B = 1483.4 * LN ------
 R100

 Thus, knowing the RESISTANCE At 25 degrees Centigrade And also At 100 degrees Centigrade 
 we can use the above calculation To find the value of B For a given thermistor.

---------------------------------------------------------------------------------------
}

    // sort a word array...
    Sub BubbleSort(ByRef pArray() As Word)
       Dim SwapOccured As Boolean
       Dim index As Byte
       Dim SwapTemp As Word
       Repeat
          SwapOccured = false
          index = 0
          Repeat
             If pArray(index) > pArray(index + 1) Then
                SwapTemp = pArray(index)
                pArray(index) = pArray(index + 1)
                pArray(index + 1) = SwapTemp
                SwapOccured = true
             EndIf
             Inc(index)
           Until index = Bound(pArray)
       Until Not SwapOccured
    End Sub

    // Get the median of an array
    Function GetMedian(ByRef pSamples() As Word) As Word
       Dim index As Byte
       BubbleSort(pSamples)
       result = pSamples(Bound(pSamples) / 2)
    End Function

    // Perform the Stein Hart linearization taking into account the thermistors characteristics
    Function SteinHart(pValue As Float) As Float
        Const T25Val = 0.0033540                    // Thermistor's t25 value
        Const ThermistorBVal = 1.0 / 3489.0         // Thermistor's B value
        Dim  LogValue As Float

        LogValue = log(pValue / 10000)              // Calculate the log
        Result = ThermistorBVal * LogValue + T25Val  // linearize using the stein-hart algorithm
    End Function

//-----------------------------------------------------------------

    Const SymDegree(8) As Byte = ($06,$09,$09,$06,0,0,0,0) // Data for deg symbol in cgram char 0


    Dim SampleArray(20) As Word
    Dim TempF As Float
    Dim Temperature As Float
    Dim index As Byte
    Dim Resistance As Float
    Dim ThermistorValue As Word
    Const Quanta = 5000.0 / 1024.0                 // Quantizing constant for ADC reading to Voltage calculation

    ADCON1 = $07                                   // PORTE as digital (LCD)
    TRISA.0 = 1                                    // configure AN0 as an input
    ADCON1.7 = 1                                   // set analogue input on PORTA.0

    DelayMS(200)

    LCD.WriteItem(SymDegree)                       // Write the custom char data to the LCD

    While 1 = 1

        For index = 0 To Bound(SampleArray)
            SampleArray(index) = ADC.Read(0)       // Take 20 samples and store them in the array 
        Next
        ThermistorValue = GetMedian(SampleArray)   // Then get the median of the array

        Temperature = ThermistorValue * Quanta     // Work out the voltage
        TempF = 5000 - Temperature                 // Find the resistance across the thermistor

        Resistance = (Temperature * 10000) / TempF
        Temperature = SteinHart(Resistance)        // linearize with the Stein Hart calculation

        Temperature = (1 / Temperature) - 273.15   // Convert from Kelvin To Centigrade

        LCD.Cls

        LCD.WriteAt(1,1, FloatToStr(Temperature),0,"C ")

        DelayMS(500)                               // Delay 500ms

    Wend

    End