Friday, October 31, 2014

Designing a Brew Chamber Controller (Update 9)

Latest version 0.06.0a available on GitHub.

https://github.com/cyberlord8/bcc

Version History
~~~~~~~~~~~~~~~

#0.06.0a (31 Oct 2014)
- Fixed minor display bug with alarm status display when SMS texts were sent
- Fixed bug where sometimes the high temp alarm was on but the cooler was not
- Added cell phone number to settings file instead of hard coded in software
- Settings file is now written to every time a command is entered in case the program crashes
- Added database (database.csv) that stores current system status every 15 minutes
- Added brew information - preparation for auto brew process

Screen Shot:



Sunday, October 26, 2014

Beta Testers Wanted

Looking for beta candidates to test the bcc.py software.

Requirements:

  1. Must have a Beaglebone Black Rev C running Debian distro.
  2. Must have two 3.3 volt 10A or better solid state relays (SSR) or two PowerSwitch Tails
  3. Must be able to install the required libraries and support software on the BBB and laptop/computer
  4. Must be able to use GitHub repository to install (clone) the bcc code on your BBB
  5. Must provide detailed bug reports and how to recreate the bug on GitHub
  6. A good working knowledge of linux command and GUI interfaces is preferred
  7. Programming knowledge is not required but would like a few knowledgeable Python programmers 
  8. A few novices/beginners may be selected to help write detailed setup and operation instructions
 If you are interested please reply with a comment to this post.

Thanks,

My BBB Projects

Saturday, October 25, 2014

Designing a Brew Chamber Controller (Update 8)

Latest version 0.05.0a available on GitHub.

https://github.com/cyberlord8/bcc

Version History
~~~~~~~~~~~~~~~

#0.05.2a
- Added a user manual

#0.05.1a
- Fixed bug in bcc.desktop that made the terminal window too small to display bcc properly

#0.05.0a
- Yeast profiles added - can now read in yeast database and select a yeast by it's ID number
- Modified the alarm system and added SMS texting of alarm status every hour (enter YOUR OWN phone number!!!)

Friday, October 24, 2014

Designing a Brew Chamber Controller (Update 7)

Latest version 0.04.0a available on GitHub.

https://github.com/cyberlord8/bcc

Version History
~~~~~~~~~~~~~~~
#0.04.0a
- Fixed bug where the different brew cycles were not calculating properly due to global variable not being declared
- bcc now saves current settings to a file (bccconfig.py)
- Increased precision in F/C conversion formulas which was causing a rounding error
- Added reset min and max temp variables function (ability to reset them for each brew session?)
- Added GPL 3.0 license verbiage
- Fixed bug where cycling brew cycle off and on would cause compressor to turn on and off with no 5 minute delay

Saturday, October 4, 2014

Designing a Brew Chamber Controller (Update 6)

A few screen shots of version 0.03a. The system is currently residing in my entertainment center so that is why the temperature readings are so warm.

This is the self test code where the LEDs are lit and the thermistor is checked to see if it reads a sensible value.

The initial startup screen where we are waiting for the average temperature to stabilize.

Once the average temperature stabilizes the system starts in the 'Off' mode.

The warm cycle is used to start the fermentation process. Once it gets underway the cycle is changed to normal cycle.

The normal cycle is used for the primary fermentation. Once the primary is complete a cold crash cycle is used to drop the suspended yeast faster.

The lager cycle is used for lagering a beer.

Cold crash is used to drop the yeast quickly.

Clear cycle can be used to age or secondary a beer.

Wednesday, October 1, 2014

Designing a Brew Chamber Controller (Update 5)

I've also updated the trend function.  I wanted to incorporate Object Oriented Programming OOP into the codebase and go full OOP in the final GUI version so I started on the trend function which is of no importance to the operation of the program in case I screwed it up :).

The main program loop calls the Trend Class  method move_averages(). Move_averages stores the last 4 temperature readings.  It then calls the set_average and set_trend methods. These methods store the average temperature over the last minute, and the trend.  These values are then accessible from other functions, for example, if we had an object called trending that was of the class Trend, we could access the average temperature and trend by calling trending.moving_avg_temp and trending.trend respectively.

The complete code can be found at: https://github.com/cyberlord8/bcc

#Trend Class##############################################
#calculates whether temp went up or down or stayed the same since last checked
#may make this an averaging function so we check the current temp compared to last # averages

class Trend:

  def __init__(self):#######################

    #initialize static variables
    self.trend ="-"
    self.moving_avg_temp = 0
    self.temp1 = 0
    self.temp2 = 0
    self.temp3 = 0
    self.temp4 = 0

    return


  def move_average(self):#Called every 15 seconds from main program loop#

    #move the temperatures through the 4 variables
    #since this is updated every 15 seconds there is one minute of data stored here
    self.temp4 = self.temp3
    self.temp3 = self.temp2
    self.temp2 = self.temp1
    self.temp1 = current_temperature

    self.set_average() #average the 4 values
    self.set_trend() #set the trend indicator

    return


  def set_trend(self):######################

    if current_temperature > self.moving_avg_temp+.01: self.trend = "^" #upward trend
    elif current_temperature < self.moving_avg_temp-.01: self.trend = "v" #downward trend
    else: self.trend = "-"
   
    return


  def set_average(self):###################

    self.moving_avg_temp = (self.temp1 + self.temp2 + self.temp3 + self.temp4) / 4

    return

Designing a Brew Chamber Controller (Update 4)

 I've made some major changes to the code in the last few weeks.

I've added the ability to accept user input so parameters can be adjusted on the fly instead of being hard-coded in the program.

To check if we have any keyboard activity we use the UNIX select function to check sys.stdin.  If there is data available, read it in and act on it.

Using S and D we can set the desired temperature and the dwell while the program is running.

Later we'll add some automated functionality like brew cycles (ferment start, ferment, cold crash, lager, etc) so the program can do most of the work.

I also added a delay loop function that prints a sequence of characters on the screen to show the program is still running.

#check for user input###############################################
def check_input():

  if select.select([sys.stdin],[],[],0.0)[0]:
    key_input = sys.stdin.readline()

    if key_input[0] == 's' or key_input[0] == 'S':
      set_desired_temp()

    if key_input[0] == 'd' or key_input[0] == 'D':
      set_dwell()

    if key_input[0] == 'x' or key_input[0] == 'X':
      exit_program()

    print_output()
    heater_control(trending.moving_avg_temp)
    cooler_control(trending.moving_avg_temp)
    print_menu()
    print "\033[12;0H                  "
    print "\033[10;0H"

  return

#exit program######################################################
def exit_program():
  print "\033[24;0HExiting program..."
  time.sleep(2)
  exit(0)

#set dwell#########################################################
def set_dwell():
  global DWELL

  print "\033[24;0H"
  DWELL = input("Enter dwell: ")
  print "\033[25;0H                                   "

  return

#set desired temperature##########################################
def set_desired_temp():
  global DESIRED_TEMP

  print "\033[24;0H"
  DESIRED_TEMP = input("Enter desired temperature: ")
  print "\033[25;0H                                  "

  return

#delay_loop function#############################################
def delay_loop():
  print "\033[10;0H"
   
  for x in xrange(15):
    if x % 5 == 0: print "\033[11;0HRunning: ."
    if x % 5 == 1: print "\033[11;0HRunning: o"
    if x % 5 == 2: print "\033[11;0HRunning: O"
    if x % 5 == 3: print "\033[11;0HRunning: 0"
    if x % 5 == 4: print "\033[11;0HRunning: *"

    check_input()

    time.sleep(1) #sleep for 1 second and repeat while True loop

  return