Sunday, July 13, 2014

Designing a Brew Chamber Controller (Part 6)

In the previous post we created some python code based on some formulae to determine temperature from a thermistors internal resistance.

We are now going to paste that code into a file on the BBB so we can run it.

First we need to connect our BBBs client USB port to our computer.

After a minute or so we can now use PuTTY SSH client to log into the BBB.

We'll be using nano text editor on the BBB as it displays a menu at the bottom so we know the editor commands and also has a nice colorful display that highlights different parts of our code.  It doesn't do any syntax checking however, so we will look at using an Integrated Development Environment (IDE) later that will check our code as we write it and also provide a way to run and debug our code.

At the BBB SSH prompt type:

nano bcc_test.py

Now copy the code from the previous post (or from your notepad session) and in the PuTTY client terminal right click with your mouse to paste the code into nano.

Press CTRL-X to exit nano and press Y <enter> to save your file.

From the BBB SSH command prompt type:

python bbc_test.py

After a second you should see something similar to the following:

adcValue:  0.922  | res_therm:  47613.8813  | temp_kelvin:  299.2657  | temp_celsius:  26.1157  | temp_fahren:  79.0083

If the output is a lot different or your temperature reading doesn't correlate to your room temperature then check your thermistor voltage divider network.

If all looks OK, it's time to start designing our brew chamber controller program.

We'll be addressing the core essential specifications in this post:
  • Monitor ambient brew chamber air temperature
  • Turn on heating if needed
  • Turn on cooling if needed
Hopefully you have the following items:
  1. Beaglebone Black (BBB) with Adafruit BBB IO library installed
  2. Breadboard populated with the required components (see Part 3 and Part 4)
  3. Micro USB cable (came with BBB)
  4. Computer or laptop with PuTTY Client.
The goals of this experiment are to create a python script that accomplishes the following:
  1. Setup Program
    • Import libraries
    • Initialize global variables
    • Initialize constants
    • Initialize GPIO and ADC pins
    • Perform self test
  2. Main Program Loop
    • Call Calculate Temperature function
    • Call the heating function and pass the current temperature
    • Call the cooling function and pass the current temperature
  3. Calculate Temperature
    • Read AIN0 voltage (monitor ambient temperature)
    • Calculate thermistor resistance
    • Calculate thermistor temperature
    • Return current temperature
  4. Heating Function (current temperature)
    • Turn on the Red LED if the temperature is less than a certain level
    • Turn off the Red LED if the temperature is greater than a certain level
  5. Cooling Function (current temperature)
    • Turn on the Green LED if the temperature is greater than a certain level
    • Turn off the Green LED if the temperature is less than a certain level
These are the core requirements to make the BBB function as a temperature controller that you could use to control any device that needed heating and or cooling. You could control your house heating/cooling (with added code you could adjust desired temperature based on time of day etc) or a chicken egg incubator.

So let's start with section 1, setting up the program.

#############################################################################
#!/usr/bin/python
#import the libraries we will use in our program
import Adafruit_BBIO.ADC as ADC

import Adafruit_BBIO.GPIO as GPIO
import time
import math


#set Celsius to kelvin constant
c2kelvin = 273.15


#set the variables we'll use in our calculations

#global variables used when reading AIN0
r_bias = 50000 #resistor value used in the thermistor voltage divider
VDD_ADC = 1.8 #voltage divider input voltage

AIN_MIN = .7 #minimum voltage used during self test - will adjust as needed
AIN_MAX = 1.3 #maximum voltage used during self test - will adjust as needed


#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

GPIO.setup("P9_15", GPIO.OUT) #setup pin P9_48 as output pin HEATER
GPIO.setup("P9_23", GPIO.OUT) #setup pin P9_49 as output pin COOLER
 

#self test function to check AIN0 voltage is w/in normal range and GPIO pins/LEDs are working
#we use a function so we can call this code at a later time if we want
def self_test():
  print "Performing self tests"
  time.sleep(1) #sleep for 1 second to slow down test sequence - remove if desired
  #turn on heater LED
  print "Turning on RED LED"
  GPIO.output("P9_15",GPIO.HIGH)
  time.sleep(1)
  print "Turning off RED LED"
  GPIO.output("P9_15",GPIO.LOW)
  time.sleep(1)
  print "Turning on GREEN LED"
  GPIO.output("P9_23",GPIO.HIGH)
  time.sleep(1)
  print "Turning off GREEN LED"
  GPIO.output("P9_23",GPIO.LOW)
  time.sleep(1)

  adcValue = ADC.read("AIN0") * VDD_ADC
  if adcValue > AIN_MIN and adcValue < AIN_MAX: print "adcValue OK: ", adcValue
  time.sleep(1)
  print "Test complete"
  time.sleep(1)
  return


self_test()
##############################################################################

Copy and past the above code into a file on the BBB.

nano bbc.py
<copy><paste>
CTRL-X
y
<enter>

Now let's turn this file into an executable so we don't have to keep calling the python interperter.

chmod +x bbc.py

Now we should be able to run the program by typing:

./bbc.py <enter>

The output should be similar to the following:

root@beaglebone:~# ./bbc.py
Performing self tests
Turning on RED LED
Turning off RED LED
Turning on GREEN LED
Turning off GREEN LED
adcValue OK:  0.941000032425
Test complete
root@beaglebone:~#

Now we'll start to work on the section 2, the Main Program Loop.

##############################################################################
while True:
    #call the calculate temperature function and assign the results to current temperature
    current_temperature = calculate_temperature()

    #call the heater function and pass the current temperature
    heater_control(current_temperature)

    #call the cooler function and pass the current temperature
    cooler_control(current_temperature)

    time.sleep(5) #sleep for 5 seconds and repeat while True loop
##############################################################################

So now we have the beginning of the main program loop but we still need to define the calculate_temperature, heater_control, and cooler_control functions.

#############################################################################
#calculate temperature function
def calculate_temperature()
    #define global variables
    #make sure to add USE_CELSIUS to the global variables section at the top of the file
    global VDD_ADC, res_therm, c2kelvin, T_a, T_b, T_c, USE_CELSIUS

    #read AIN0 pin and calculate voltage 
    Vout = ADC.read("AIN0") * VDD_ADC

    #calculate thermistor resistance R1
    res_therm = r_bias * (Vin-Vout)/Vout

    #calculate temperatures
    temp_kelvin = 1/(T_a + T_b * math.log(res_therm) + T_c * pow(math.log(res_therm),3))
    temp_celsius = temp_kelvin - c2kelvin
    temp_fahren = (temp_celsius * 9/5) + 32

    if USE_CELSIUS: return temp_celsius
    else: return temp_fahren

############################################################################

############################################################################
def heater_control(current_temperature):
    global HEATER_ON, DESIRED_TEMP, DWELL
    if current_temperature < DESIRED_TEMP - DWELL:
      if not HEATER_ON:
        HEATER_ON = True
        print "Turning heater on\n\n"
        GPIO.output("P9_15",GPIO.HIGH)
    elif HEATER_ON:
      HEATER_ON = False
      print "Turning heater off\n\n"
      GPIO.output("P9_15",GPIO.LOW)

    return
############################################################################

############################################################################
def cooler_control(current_temperature):
    global COOLER_ON, DESIRED_TEMP, DWELL
    if current_temperature > DESIRED_TEMP + DWELL:
      if not COOLER_ON:
        COOLER_ON = True
        print "Turning cooler on\n\n"
        GPIO.output("P9_23",GPIO.HIGH)
    elif COOLER_ON:
      COOLER_ON = False
      print "Turning cooler off\n\n"
      GPIO.output("P9_23",GPIO.LOW)

    return
############################################################################

We now have a rudimentary functioning temperature controller.  In case you had trouble piecing the code together, here is the complete code to copy/paste.  Also this code is written so beginners can follow along and could do with some variable reduction and other optimization.

In future sessions we'll work on selecting and automating the temperature control for different beers and wines.

############################################################################
#!/usr/bin/python
#import the libraries we will use in our program
import Adafruit_BBIO.ADC as ADC
import Adafruit_BBIO.GPIO as GPIO
import time
import math

#set Celsius to kelvin constant
c2kelvin = 273.15

#set the variables we'll use in our calculations
#global variables used when reading AIN0
R_BIAS = 52000 #resistor value used in the thermistor voltage divider - actual measurement w/ ohm meter
VDD_ADC = 1.8 #voltage divider input voltage
AIN_MIN = .7 #minimum voltage used during self test - will adjust as needed
AIN_MAX = 1.3 #maximum voltage used during self test - will adjust as needed

#other global variables
USE_CELSIUS = 0 #set to 0 to use Fahrenheit
HEATER_ON = 0 #initialize HEATER_ON to False
COOLER_ON = 0 #initialize COOLER_ON to false
DESIRED_TEMP = 78 #set initial desired temp
DWELL = 2 #set initial dwell temp range

#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
GPIO.setup("P9_15", GPIO.OUT) #setup pin P9_48 as output pin HEATER
GPIO.setup("P9_23", GPIO.OUT) #setup pin P9_49 as output pin COOLER

#self test function to check AIN0 voltage is w/in normal range and GPIO pins/LEDs are working
#we use a function so we can call this code at a later time if we want
def self_test():
  print "Performing self tests"
  time.sleep(1) #sleep for 1 second to slow down test sequence - remove if desired
  #turn on heater LED
  print "Turning on RED LED"
  GPIO.output("P9_15",GPIO.HIGH)
  time.sleep(1)
  print "Turning off RED LED"
  GPIO.output("P9_15",GPIO.LOW)
  time.sleep(1)
  print "Turning on GREEN LED"
  GPIO.output("P9_23",GPIO.HIGH)
  time.sleep(1)
  print "Turning off GREEN LED"
  GPIO.output("P9_23",GPIO.LOW)
  time.sleep(1)

  adcValue = ADC.read("AIN0") * VDD_ADC

  if adcValue > AIN_MIN and adcValue < AIN_MAX: print "adcValue OK: ", adcValue

  time.sleep(1)
  print "Test complete\n\n"
  time.sleep(1)
  return

#calculate temperature function
def calculate_temperature():
    #define global variables
    global VDD_ADC, R_BIAS, c2kelvin, T_a, T_b, T_c, USE_CELSIUS

    #read AIN0 pin and calculate voltage
    Vout = ADC.read("AIN0") * VDD_ADC

    #calculate thermistor resistance R1
    res_therm = R_BIAS * (VDD_ADC - Vout) / Vout

    #calculate temperature in kelvin
    temp_kelvin = 1/(T_a + T_b * math.log(res_therm) + T_c * pow(math.log(res_therm),3))
    temp_celsius = temp_kelvin - c2kelvin
    temp_fahren = (temp_celsius * 9/5) + 32

    if USE_CELSIUS: return temp_celsius
    else: return temp_fahren

def heater_control(current_temperature):
    global HEATER_ON, DESIRED_TEMP, DWELL
    if current_temperature < DESIRED_TEMP - DWELL:
      if not HEATER_ON:
        HEATER_ON = True
        print "Turning heater on\n\n"
        GPIO.output("P9_15",GPIO.HIGH)
    elif HEATER_ON:
      HEATER_ON = False
      print "Turning heater off\n\n"
      GPIO.output("P9_15",GPIO.LOW)
    return

def cooler_control(current_temperature):
    global COOLER_ON, DESIRED_TEMP, DWELL
    if current_temperature > DESIRED_TEMP + DWELL:
      if not COOLER_ON:
        COOLER_ON = True
        print "Turning cooler on\n\n"
        GPIO.output("P9_23",GPIO.HIGH)
    elif COOLER_ON:
      COOLER_ON = False
      print "Turning cooler off\n\n"
      GPIO.output("P9_23",GPIO.LOW)
    return

self_test()

while True:

    #call the calculate temperature function and assign the results to current temperature
    current_temperature = calculate_temperature()

    print "Current temperature:",round(current_temperature,1)

    #call the heater function and pass the current temperature
    heater_control(current_temperature)

    #call the cooler function and pass the current temperature
    cooler_control(current_temperature)

    time.sleep(5) #sleep for 5 seconds and repeat while True loop


############################################################################

Click designing-brew-chamber-controller-part-7.html for the next part in the series.



No comments:

Post a Comment