Sunday, July 13, 2014

Designing a Brew Chamber Controller (Part 5)

In the previous sessions we established our Brew Chamber Controller specifications, built a mockup of the device, and tested it.  Now it's time to design the software to control it.

The first thing we need to do is figure out how to calculate our unknown value, temperature.

In order to calculate the temperature we first need to determine the resistance of the thermistor.  Once we determine the resistance of the thermistor we can use a formula to calculate the temperature.

But the problem is we can't directly measure resistance with the BBB IO pins, we can only measure voltage.  But knowing the input voltage, output voltage, and one resistance value in a voltage divider circuit we can calculate the missing resistance. The formula to calculate the unknown resistance in a voltage divider network is:

      R1 = R2*(Vin-Vout)/Vout
Where we are solving for R1, the thermistor resistance, R2 is the known resistance of the resistor in our divider network, and Vin and Vout are the input and output voltages.

Now that we know how to calculate the resistance of the thermistor we need to calculate the corresponding temperature.

The function of a thermistor's resistance over temperature is not linear, in other words the resistance is much greater at one end of the temperature range than the other.  This forms an exponential curve.

The formula to calculate temperature from a thermistors resistance is:

    T = 1 / (a + b * (ln R) + c * (ln R)^3)

Where T is in degrees kelvin, R is the resistance of the thermistor and a, b, and c are values obtained from the thermistor datasheet.

For my 503 thermistor the values are:

    ‘Grade 1’, 50KΩ (1H503 parts)
    a = 7.602330993 X 10-4
    b = 2.313331379 X 10-4
    c = 7.172007260 X 10-8

OK, so now we know how to calculate the temperature in kelvin, we need to convert it to units that we relate to more, Celsius and Fahrenheit.

    Celsius = kelvin - 273.15


    Fahrenheit = (9/5) * Celsius + 32

And finally all the formulae together:

    R1 = R2*(Vin-Vout)/Vout
    T = 1 / (a + b * (ln R) + c * (ln R)^3)
    Celsius = kelvin - 273.15
    Fahrenheit = (9/5) * Celsius + 32

So the first thing we need to do is figure out what our known variables are:
  • We know the ADC power rail on the BBB is 1.8 volts, so we know that Vin will be 1.8 volts
  • We know the resistor in our divider network needs to match the thermistor so we choose 50k ohm
  • We don't know right off what Vout is, but we read that from the BBB ADC AIN0 pin
  • We know a, b, and c for use in our polynomial equation to calculate temperature in kelvin
  • We know how to convert kelvin to Celsius
  • We know how to convert Celsius to Fahrenheit
So let's write some python code to do all these calculations.

Open notepad on your computer and type copy/paste the following:

#import the libraries we will use in our program
import Adafruit_BBIO.ADC as ADC
import time
import math

#set celsius to kelvin constant
c2kelvin = 273.15

#set the variables we'll use in our calculations
r_bias = 50000 #resistor value used in the thermistor voltage divider
VDD_ADC = 1.8 #voltage divider input voltage

#thermistor constants used in polynomial equation
T_a = 7.602330993E-4
T_b = 2.313331379E-4
T_c = 7.172007260E-8

#setup the BBB IO pins
ADC.setup() #setup ADC pins

#read the voltage on pin AIN0 and store it in variable adcValue 
#the ADC AIN pins read a value from 0 to 1, in other words they read the voltage level
#as a percentage of the ADC voltage rail (1.8V) so we need to convert the percentage
#value to an actual voltage by multiplying the percent with the ADC rail voltage
adcValue ="AIN0") * VDD_ADC

#now calculate the thermistor resistance
res_therm = r_bias*(VDD_ADC-adcValue)/adcValue

#now calculate the corresponding temperature in kelvin
#you will notice the formula looks different because we need to use python syntax
temp_kelvin = 1/(T_a + T_b * math.log(res_therm) + T_c * pow(math.log(res_therm),3))

#now convert kelvin to Celsius

temp_celsius = temp_kelvin - c2kelvin

#and also convert to Fahrenheit
temp_fahren = (temp_celsius * 9/5) + 32

#now let's display the results
#make sure this next part is all on one line
print "adcValue: ", round(adcValue,4)," | res_therm: ", round(res_therm,4)," | temp_kelvin: ",round(temp_kelvin,4)," | temp_celsius: ",round(temp_celsius,4)," | temp_fahren: ",round(temp_fahren,4)

In the next session we'll paste this code into a file one the BBB so we can run it.

See you then.

No comments:

Post a Comment