#!/usr/bin/python
# /usr/share/adafruit/webide/repositories/my-pi-projects/boiler_Mk2/Boiler_Controller_LCD.py
#*************************************************************************************
#*************************************************************************************
#*************************************************************************************
# This HLT/Boiler Controller software has been written by Robbo100 (username from
# [url]www.thehomebrewforum.co.uk[/url]). This software uses elements of code from Daniel Berlin
# (with some changes by Adafruit Industries/Limor Fried) and Matt Hawkins.
#*************************************************************************************
#*************************************************************************************
#*************************************************************************************
# Copyright 2012 Daniel Berlin (with some changes by Adafruit Industries/Limor Fried)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal MCP230XX_GPIO(1, 0xin
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
# of the Software, and to permit persons to whom the Software is furnished to do
# so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#------------------------------------------------------------------------------
# IMPORT OTHER FUNCTIONS AND CLASSES
#------------------------------------------------------------------------------
from Adafruit_I2C import Adafruit_I2C
import smbus
import time
import os
import glob
import RPi.GPIO as GPIO
import threading
import datetime
from threading import Thread
import struct
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
#------------------------------------------------------------------------------
# ONE WIRE THERMOMETER SYSTEM SUB ROUTINES
#------------------------------------------------------------------------------
def read_temp_raw_1(device1_file):
f = open(device1_file, 'r')
lines = f.readlines()
f.close()
return lines
def read_temp_1(device1_file):
try:
lines = read_temp_raw_1(device1_file)
while lines[0].strip()[-3:] != 'YES':
time.sleep(0.001)
lines = read_temp_raw_1(device1_file)
equals_pos = lines[1].find('t=')
if equals_pos != -1:
temp_string = lines[1][equals_pos+2:]
temp_c_1 = float(temp_string) / 1000.0
temp_f_1 = temp_c_1 * 9.0 / 5.0 + 32.0
return temp_c_1
except Exception:
temp_c_1=(-100)
return temp_c_1
def read_temp_raw_2(device2_file):
f = open(device2_file, 'r')
lines = f.readlines()
f.close()
return lines
def read_temp_2(device2_file):
try:
lines = read_temp_raw_2(device2_file)
while lines[0].strip()[-3:] != 'YES':
time.sleep(0.001)
lines = read_temp_raw_2(device2_file)
equals_pos = lines[1].find('t=')
if equals_pos != -1:
temp_string = lines[1][equals_pos+2:]
temp_c_2 = float(temp_string) / 1000.0
temp_f_2 = temp_c_2 * 9.0 / 5.0 + 32.0
return temp_c_2
except Exception:
temp_c_2=(-100)
return temp_c_2
#------------------------------------------------------------------------------
# INITIALISE THE SLICE OF PI/O
#------------------------------------------------------------------------------
MCP23017_IODIRA = 0x00
MCP23017_IODIRB = 0x01
MCP23017_GPIOA = 0x12
MCP23017_GPIOB = 0x13
MCP23017_GPPUA = 0x0C
MCP23017_GPPUB = 0x0D
MCP23017_OLATA = 0x14
MCP23017_OLATB = 0x15
MCP23008_GPIOA = 0x09
MCP23008_GPPUA = 0x06
MCP23008_OLATA = 0x0A
class Adafruit_MCP230XX(object):
OUTPUT = 0
INPUT = 1
def __init__(self, address, num_gpios):
assert num_gpios >= 0 and num_gpios <= 16, "Number of GPIOs must be between 0 and 16"
self.i2c = Adafruit_I2C(address=address)
self.address = address
self.num_gpios = num_gpios
# set defaults
if num_gpios <= 8:
self.i2c.write8(MCP23017_IODIRA, 0xFF) # all inputs on port A
self.direction = self.i2c.readU8(MCP23017_IODIRA)
self.i2c.write8(MCP23008_GPPUA, 0x00)
elif num_gpios > 8 and num_gpios <= 16:
self.i2c.write8(MCP23017_IODIRA, 0xFF) # all inputs on port A
self.i2c.write8(MCP23017_IODIRB, 0xFF) # all inputs on port B
self.direction = self.i2c.readU8(MCP23017_IODIRA)
self.direction |= self.i2c.readU8(MCP23017_IODIRB) << 8
self.i2c.write8(MCP23017_GPPUA, 0x00)
self.i2c.write8(MCP23017_GPPUB, 0x00)
def _changebit(self, bitmap, bit, value):
assert value == 1 or value == 0, "Value is %s must be 1 or 0" % value
if value == 0:
return bitmap & ~(1 << bit)
elif value == 1:
return bitmap | (1 << bit)
def _readandchangepin(self, port, pin, value, currvalue = None):
assert pin >= 0 and pin < self.num_gpios, "Pin number %s is invalid, only 0-%s are valid" % (pin, self.num_gpios)
#assert self.direction & (1 << pin) == 0, "Pin %s not set to output" % pin
if not currvalue:
currvalue = self.i2c.readU8(port)
newvalue = self._changebit(currvalue, pin, value)
self.i2c.write8(port, newvalue)
return newvalue
def pullup(self, pin, value):
if self.num_gpios <= 8:
return self._readandchangepin(MCP23008_GPPUA, pin, value)
if self.num_gpios <= 16:
lvalue = self._readandchangepin(MCP23017_GPPUA, pin, value)
if (pin < 8):
return
else:
return self._readandchangepin(MCP23017_GPPUB, pin-8, value) << 8
# Set pin to either input or output mode
def config(self, pin, mode):
if self.num_gpios <= 8:
self.direction = self._readandchangepin(MCP23017_IODIRA, pin, mode)
if self.num_gpios <= 16:
if (pin < 8):
self.direction = self._readandchangepin(MCP23017_IODIRA, pin, mode)
else:
self.direction |= self._readandchangepin(MCP23017_IODIRB, pin-8, mode) << 8
return self.direction
def output(self, pin, value):
# assert self.direction & (1 << pin) == 0, "Pin %s not set to output" % pin
if self.num_gpios <= 8:
self.outputvalue = self._readandchangepin(MCP23008_GPIOA, pin, value, self.i2c.readU8(MCP23008_OLATA))
if self.num_gpios <= 16:
if (pin < 8):
self.outputvalue = self._readandchangepin(MCP23017_GPIOA, pin, value, self.i2c.readU8(MCP23017_OLATA))
else:
self.outputvalue = self._readandchangepin(MCP23017_GPIOB, pin-8, value, self.i2c.readU8(MCP23017_OLATB)) << 8
return self.outputvalue
self.outputvalue = self._readandchangepin(MCP23017_IODIRA, pin, value, self.outputvalue)
return self.outputvalue
def input(self, pin):
assert pin >= 0 and pin < self.num_gpios, "Pin number %s is invalid, only 0-%s are valid" % (pin, self.num_gpios)
assert self.direction & (1 << pin) != 0, "Pin %s not set to input" % pin
if self.num_gpios <= 8:
value = self.i2c.readU8(MCP23008_GPIOA)
elif self.num_gpios > 8 and self.num_gpios <= 16:
value = self.i2c.readU8(MCP23017_GPIOA)
value |= self.i2c.readU8(MCP23017_GPIOB) << 8
return value & (1 << pin)
def readU8(self):
result = self.i2c.readU8(MCP23008_OLATA)
return(result)
def readS8(self):
result = self.i2c.readU8(MCP23008_OLATA)
if (result > 127): result -= 256
return result
def readU16(self):
assert self.num_gpios >= 16, "16bits required"
lo = self.i2c.readU8(MCP23017_OLATA)
hi = self.i2c.readU8(MCP23017_OLATB)
return((hi << 8) | lo)
def readS16(self):
assert self.num_gpios >= 16, "16bits required"
lo = self.i2c.readU8(MCP23017_OLATA)
hi = self.i2c.readU8(MCP23017_OLATB)
if (hi > 127): hi -= 256
return((hi << 8) | lo)
def write8(self, value):
self.i2c.write8(MCP23008_OLATA, value)
def write16(self, value):
assert self.num_gpios >= 16, "16bits required"
self.i2c.write8(MCP23017_OLATA, value & 0xFF)
self.i2c.write8(MCP23017_OLATB, (value >> 8) & 0xFF)
# RPi.GPIO compatible interface for MCP23017 and MCP23008
class MCP230XX_GPIO(object):
OUT = 0
IN = 1
BCM = 0
BOARD = 0
def __init__(self, busnum, address, num_gpios):
self.chip = Adafruit_MCP230XX(busnum, address, num_gpios)
def setmode(self, mode):
# do nothing
pass
def setup(self, pin, mode):
self.chip.config(pin, mode)
def input(self, pin):
return self.chip.input(pin)
def output(self, pin, value):
self.chip.output(pin, value)
def pullup(self, pin, value):
self.chip.pullup(pin, value)
if __name__ == '__main__':
#------------------------------------------------------------------------------
# CONFIGURE THE SLICE OF PI/O INPUT AND OUTPUTS
#------------------------------------------------------------------------------
# Set num_gpios to 8 for MCP23008 or 16 for MCP23017!
# mcp = Adafruit_MCP230XX(address = 0x20, num_gpios = 8) # MCP23008
mcp = Adafruit_MCP230XX(address = 0x20, num_gpios = 16) # MCP23017
# List outputs here
mcp.config(7, mcp.OUTPUT) # Buzzer
mcp.config(12, mcp.OUTPUT) # Relay 1 on
mcp.config(13, mcp.OUTPUT) # Relay 2 on
# Set inputs with the pullup resistor enabled here
mcp.config(14, mcp.INPUT)
mcp.pullup(14, 1)
mcp.config(15, mcp.INPUT)
mcp.pullup(15, 1)
# Set all outputs to off for startup (note - some outputs are reversed
# depending upon connected device)
mcp.output(7, 0)
mcp.output(12, 1)
mcp.output(13, 1)
#------------------------------------------------------------------------------
# HD44780 LCD SETUP
#------------------------------------------------------------------------------
# Author : Matt Hawkins
# Site : [url]http://www.raspberrypi-spy.co.uk[/url]
# Date : 26/07/2012
# The wiring for the LCD is as follows:
# 1 : GND
# 2 : 5V
# 3 : Contrast (0-5V)*
# 4 : RS (Register Select)
# 5 : R/W (Read Write) - GROUND THIS PIN
# 6 : Enable or Strobe
# 7 : Data Bit 0 - NOT USED
# 8 : Data Bit 1 - NOT USED
# 9 : Data Bit 2 - NOT USED
# 10: Data Bit 3 - NOT USED
# 11: Data Bit 4
# 12: Data Bit 5
# 13: Data Bit 6
# 14: Data Bit 7
# 15: LCD Backlight +5V**
# 16: LCD Backlight GND
# Define GPIO to LCD mapping
LCD_RS = 17
LCD_E = 18
LCD_D4 = 22
LCD_D5 = 23
LCD_D6 = 24
LCD_D7 = 25
# Define some device constants
LCD_WIDTH = 16 # Maximum characters per line
LCD_CHR = True
LCD_CMD = False
LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line
LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line
# Timing constants
E_PULSE = 0.00005
E_DELAY = 0.00005
#------------------------------------------------------------------------------
# HD44780 LCD INITIALISATION
#------------------------------------------------------------------------------
def lcd_init():
# Initialise display
lcd_byte(0x33,LCD_CMD)
lcd_byte(0x32,LCD_CMD)
lcd_byte(0x28,LCD_CMD)
lcd_byte(0x0C,LCD_CMD)
lcd_byte(0x06,LCD_CMD)
lcd_byte(0x01,LCD_CMD)
def lcd_string(message):
# Send string to display
message = message.ljust(LCD_WIDTH," ")
for i in range(LCD_WIDTH):
lcd_byte(ord(message[i]),LCD_CHR)
def lcd_byte(bits, mode):
# Send byte to data pins
# bits = data
# mode = True for character
# False for command
GPIO.output(LCD_RS, mode) # RS
# High bits
GPIO.output(LCD_D4, False)
GPIO.output(LCD_D5, False)
GPIO.output(LCD_D6, False)
GPIO.output(LCD_D7, False)
if bits&0x10==0x10:
GPIO.output(LCD_D4, True)
if bits&0x20==0x20:
GPIO.output(LCD_D5, True)
if bits&0x40==0x40:
GPIO.output(LCD_D6, True)
if bits&0x80==0x80:
GPIO.output(LCD_D7, True)
# Toggle 'Enable' pin
time.sleep(E_DELAY)
GPIO.output(LCD_E, True)
time.sleep(E_PULSE)
GPIO.output(LCD_E, False)
time.sleep(E_DELAY)
# Low bits
GPIO.output(LCD_D4, False)
GPIO.output(LCD_D5, False)
GPIO.output(LCD_D6, False)
GPIO.output(LCD_D7, False)
if bits&0x01==0x01:
GPIO.output(LCD_D4, True)
if bits&0x02==0x02:
GPIO.output(LCD_D5, True)
if bits&0x04==0x04:
GPIO.output(LCD_D6, True)
if bits&0x08==0x08:
GPIO.output(LCD_D7, True)
# Toggle 'Enable' pin
time.sleep(E_DELAY)
GPIO.output(LCD_E, True)
time.sleep(E_PULSE)
GPIO.output(LCD_E, False)
time.sleep(E_DELAY)
#------------------------------------------------------------------------------
# ERROR LOGGING FUNCTION
#------------------------------------------------------------------------------
def scriptdebug(errormessage):
errorlog = open('/home/pi/error.log', 'a')
print >> errorlog, datetime.datetime.now(), errormessage
errorlog.flush()
#------------------------------------------------------------------------------
# BOIL FUNCTION
#------------------------------------------------------------------------------
def boil_mode(boil_temperature):
while ((mcp.input(15) < 2) & (mcp.input(14) < 2)):
time.sleep(0)
global target_temperature_glob
target_temperature_glob = boil_temperature
global Element_Switch_glob
Element_Switch_glob = 0
global Line1_String
global Line2_String
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = " FULL BOIL MODE "
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("Boiler Temp = " + (str(int(Temperature))))
lcd_string(Line2_String)
time.sleep(1);
target_temperature_glob = 100
while (True):
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = " FULL BOIL MODE "
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("Boiler Temp = " + (str(int(Temperature))))
lcd_string(Line2_String)
if (mcp.input(15) < 2):
lcd_init()
if (mcp.input(15) < 2) & (mcp.input(14) < 2):
target_temperature_glob = 72
while ((mcp.input(15) < 2) & (mcp.input(14) < 2)):
time.sleep(0)
break
if (Temperature > 96): # SET TO 96 DEG
buzzer_count = 0
while (buzzer_count < 6):
mcp.output(7, 1)
time.sleep(1)
mcp.output(7, 0)
time.sleep(1)
buzzer_count = buzzer_count + 1
mcp.output(7, 0)
Boil_Start_Time = datetime.datetime.now()
Elapsed_Time = datetime.datetime.now()-Boil_Start_Time
Countdown = ((60*60)-Elapsed_Time.total_seconds())
#Countdown = ((60)-Elapsed_Time.total_seconds()) #Countdown Test Line
while (Countdown > 0):
Elapsed_Time = datetime.datetime.now()-Boil_Start_Time
Countdown = ((60*60)-Elapsed_Time.total_seconds())
#Countdown = ((60)-Elapsed_Time.total_seconds()) #Countdown Test Line
if ((int(Countdown//60))<10):
Countdown_Mins = ("0" + (str(int(Countdown//60))))
else:
Countdown_Mins = str(int(Countdown//60))
if (int((Countdown - (int((Countdown//60)*60))))<10):
Countdown_Secs = ("0" + str(int(Countdown - (int((Countdown//60)*60)))))
else:
Countdown_Secs = str(int(Countdown - (int((Countdown//60)*60))))
global Countdown_String
Countdown_String = "Boil Time " + Countdown_Mins + ":" + Countdown_Secs
# Display temperatures on LCD
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = " FULL BOIL MODE "
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = (Countdown_String)
lcd_string(Line2_String)
if (mcp.input(15) < 2):
lcd_init()
if ((Countdown < (60*15)) & (Countdown > ((60*15)-5))):
buzzer_count = 0
while (buzzer_count < 6):
mcp.output(7, 1)
time.sleep(1)
mcp.output(7, 0)
time.sleep(1)
buzzer_count = buzzer_count + 1
mcp.output(7, 0)
# Alternate the elements to turn on and off every 10 mins after 10 mins of boiling
if ((Countdown < (60*50)) & (Countdown > ((60*50)-5))):
Element_Switch_glob = 1
if ((Countdown < (60*40)) & (Countdown > ((60*40)-5))):
Element_Switch_glob = 0
if ((Countdown < (60*35)) & (Countdown > ((60*35)-5))):
Element_Switch_glob = 2
if ((Countdown < (60*25)) & (Countdown > ((60*25)-5))):
Element_Switch_glob = 0
if ((Countdown < (60*20)) & (Countdown > ((60*20)-5))):
Element_Switch_glob = 1
if ((Countdown < (60*10)) & (Countdown > ((60*10)-5))):
Element_Switch_glob = 0
if ((Countdown < (60*5)) & (Countdown > ((60*5)-5))):
Element_Switch_glob = 2
# Display temperatures on LCD
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = " FULL BOIL MODE "
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = (" Boil Complete ")
lcd_string(Line2_String)
buzzer_count = 0
while (buzzer_count < 6):
mcp.output(7, 1)
time.sleep(1)
mcp.output(7, 0)
time.sleep(1)
buzzer_count = buzzer_count + 1
mcp.output(7, 0)
while(mcp.input(14) > 2):
if (mcp.input(15) < 2):
lcd_init()
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = (" READY FOR COOL ")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("PRESS TEMP DOWN")
lcd_string(Line2_String)
# Start the cooling process
target_temperature_glob = 1 # This is needed to force the boiler to OFF in the main scropt
while(Temperature > 28): # SET TO 28 DEG
# Display temperatures on LCD
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = (" COOLING MODE ")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("Boiler Temp = " + (str(int(Temperature))))
lcd_string(Line2_String)
time.sleep(1)
if (mcp.input(15) < 2):
lcd_init()
buzzer_count = 0
while (buzzer_count < 6):
mcp.output(7, 1)
time.sleep(1)
mcp.output(7, 0)
time.sleep(1)
buzzer_count = buzzer_count + 1
mcp.output(7, 0)
while(mcp.input(14) > 2):
if (mcp.input(15) < 2):
lcd_init()
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = (" COOLING MODE ")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("Cooling Complete")
lcd_string(Line2_String)
time.sleep(3)
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("SHUTDOWN CONTLR?")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = (" HOLD TEMP DOWN ")
lcd_string(Line2_String)
time.sleep(3)
# Shutdown Pi
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("*****REMOVE*****")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("**BOILER POWER**")
lcd_string(Line2_String)
buzzer_count = 0
while (buzzer_count < 12):
mcp.output(7, 1)
time.sleep(0.5)
mcp.output(7, 0)
time.sleep(0.5)
buzzer_count = buzzer_count + 1
mcp.output(7, 0)
time.sleep(8)
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = (" SHUTTING DOWN ")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("Please Wait...")
lcd_string(Line2_String)
time.sleep(3)
os.system("sudo shutdown -r now")
#------------------------------------------------------------------------------
# DISPLAY AND BUTTON DETECTION FUNCTION
#------------------------------------------------------------------------------
def display(target_temperature, ):
global target_temperature_glob
target_temperature_glob = target_temperature
global Element_Switch_glob
Element_Switch_glob = -1
global Line1_String
global Line2_String
while (True):
Element_Switch_glob = -1
# Detect Switch Presses
if (mcp.input(15) < 2):
target_temperature_glob = target_temperature_glob+1
lcd_init()
if (mcp.input(14) < 2):
target_temperature_glob = target_temperature_glob-1
if target_temperature_glob < 0:
target_temperature_glob = 0
if target_temperature_glob > 99:
target_temperature_glob = 99
if (mcp.input(15) < 2) & (mcp.input(14) < 2):
boil_temperature = target_temperature_glob
boil_mode(boil_temperature)
time.sleep(0.15)
# Display temperatures on LCD
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("Target Temp = " + (str(target_temperature_glob)))
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("Boiler Temp = " + (str(int(Temperature))))
lcd_string(Line2_String)
############################################################################################
############################################################################################
#------------------------------------------------------------------------------
# BOILER_HLT MODE FUNCTION
#------------------------------------------------------------------------------
############################################################################################
############################################################################################
def Boiler_HLT_Mode(temp_reached, tens, units, target_temperature, dateString, Line1_String, Line2_String):
global target_temperature_glob
target_termperature_glob = target_temperature
try:
with open('/sys/bus/w1/devices/' + Thermometer1_Address + '/w1_slave'):
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = (" Thermometer")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = (" No. 1 Found")
lcd_string(Line2_String)
time.sleep(2)
except IOError:
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("**THERMOMETER**")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("**No. 1 ERROR**")
lcd_string(Line2_String)
buzzer_count = 0
while (buzzer_count < 12):
mcp.output(7, 1)
time.sleep(0.1)
mcp.output(7, 0)
time.sleep(0.1)
buzzer_count = buzzer_count + 1
while(mcp.input(14) > 2):
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("CONNECT DEVICE")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("TO THERMOMETERS")
lcd_string(Line2_String)
time.sleep(2)
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("THEN HOLD TEMP")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("DOWN TO REBOOT")
lcd_string(Line2_String)
time.sleep(2)
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("***REBOOTING***")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("Please Wait...")
lcd_string(Line2_String)
os.system("sudo shutdown -r now")
try:
with open('/sys/bus/w1/devices/' + Thermometer2_Address + '/w1_slave'):
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = (" Thermometer")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = (" No. 2 Found")
lcd_string(Line2_String)
time.sleep(2)
except IOError:
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("**THERMOMETER**")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("**No. 2 ERROR**")
lcd_string(Line2_String)
buzzer_count = 0
while (buzzer_count < 12):
mcp.output(7, 1)
time.sleep(0.1)
mcp.output(7, 0)
time.sleep(0.1)
buzzer_count = buzzer_count + 1
while(mcp.input(14) > 2):
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("CONNECT DEVICE")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("TO THERMOMETERS")
lcd_string(Line2_String)
time.sleep(2)
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("THEN HOLD TEMP")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("DOWN TO REBOOT")
lcd_string(Line2_String)
time.sleep(2)
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("***REBOOTING***")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("Please Wait...")
lcd_string(Line2_String)
os.system("sudo shutdown -r now")
#------------------------------------------------------------------------------
# SETUP THE BOILER LOG FILE
#------------------------------------------------------------------------------
try:
with open('/var/www/Boiler_Log.csv'):
os.remove('/var/www/Boiler_Log.csv')
except IOError:
print "No File to Delete"
Boiler_Log = open('/var/www/Boiler_Log.csv', 'a')
print >> Boiler_Log, "Date and Time" ',', "Boiler Temperature", ',', "Target Temperature", ',', "Element 1 Status", ',', "Element 2 Status"
Boiler_Log.flush()
#------------------------------------------------------------------------------
# SETUP THE ONE WIRE THERMOMETER SYSTEM
#------------------------------------------------------------------------------
base_dir = '/sys/bus/w1/devices/'
# Setup Thermometer 1 Location
device1_folder = glob.glob(base_dir + Thermometer1_Address)[0]
device1_file = device1_folder + '/w1_slave'
# setup Thermomenter 2 Location
device2_folder = glob.glob(base_dir + Thermometer2_Address)[0]
device2_file = device2_folder + '/w1_slave'
# Initialise the Three Wire Thermometer
while(mcp.input(15) > 2):
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = (" READY TO START")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = (" PRESS TEMP UP")
lcd_string(Line2_String)
time.sleep(0.5)
print ""
print ""
print ""
print ""
print ""
print ""
print ""
print ""
print ""
print ""
print ""
print " Average Temperature = "
print " Target Temperature = "
print " ____________________________________"
print " ", Line1_String
print " ", Line2_String
print " ____________________________________"
# Start Display Thread
display_thread = Thread(target = display, args = (target_temperature, ))
display_thread.start()
# Loop the following tasks forever
Logging_Time = datetime.datetime.now()
while(True):
# Read Temperatures From Thermometers, calculate the average, and print
# them, along with the current global target temperature parameter, to
# the terminl screen
temperature1 = read_temp_1(device1_file)
temperature2 = read_temp_2(device2_file)
global Temperature
Temperature = ((temperature1+temperature2)/2)
print ""
print ""
print ""
print ""
print ""
print ""
print ""
print ""
print ""
print ""
print ""
print " Average Temperature = ", Temperature
print " Target Temperature = ", target_temperature_glob
print " ____________________________________"
print " ", Line1_String
print " ", Line2_String
print " ____________________________________"
# If the measured temperature is lower than the target temperature, then
# turn on the boilers (0 is ON, 1 os OFF)
# Boiler 1
if ((Temperature < target_temperature_glob) & ((Element_Switch_glob == -1) | (Element_Switch_glob == 0) | (Element_Switch_glob == 1))):
mcp.output(12, 0)
Element1 = 10
else:
mcp.output(12, 1)
Element1 = 0
# Boiler 2
if ((Temperature < target_temperature_glob-1) & (Element_Switch_glob == -1)):
mcp.output(13, 0)
Element2 = 10
elif ((Temperature < target_temperature_glob) & ((Element_Switch_glob == 0) | (Element_Switch_glob == 2))):
mcp.output(13, 0)
Element2 = 10
else:
mcp.output(13, 1)
Element2 = 0
# Heating Mode Temperature Reached Buzzer
if ((Temperature > target_temperature_glob) & (temp_reached == 0)) & (target_temperature_glob != 1):
buzzer_count=0
while (buzzer_count < 6):
mcp.output(7, 1)
time.sleep(1)
mcp.output(7, 0)
time.sleep(1)
buzzer_count = buzzer_count + 1
mcp.output(7, 0)
temp_reached=1
if ((temp_reached == 1) & (Temperature <(target_temperature_glob-4))):
temp_reached=0
Logging_Time_Counter = (datetime.datetime.now() - Logging_Time)
Logging_Time_Counter_Secs = Logging_Time_Counter.total_seconds()
# Write the data to the log file
if Logging_Time_Counter_Secs > 5:
print >> Boiler_Log, datetime.datetime.now().strftime(dateString), ',', Temperature, ',', target_temperature_glob, ',', Element1, ',', Element2
Boiler_Log.flush()
Logging_Time = datetime.datetime.now()
GPIO.cleanup()
############################################################################################
############################################################################################
#------------------------------------------------------------------------------
# THE FRIDGE MODE FUNCTION
#------------------------------------------------------------------------------
############################################################################################
############################################################################################
def FV_Fridge_Mode():
# Thermometer Error Detection
mcp.output(12, 1)
mcp.output(13, 1)
try:
with open('/sys/bus/w1/devices/' + Thermometer3_Address + '/w1_slave'):
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = (" Thermometer")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = (" No. 1 Found")
lcd_string(Line2_String)
time.sleep(2)
except IOError:
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("**THERMOMETER**")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("**No. 1 ERROR**")
lcd_string(Line2_String)
buzzer_count = 0
while (buzzer_count < 12):
mcp.output(7, 1)
time.sleep(0.1)
mcp.output(7, 0)
time.sleep(0.1)
buzzer_count = buzzer_count + 1
while(mcp.input(14) > 2):
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("CONNECT DEVICE")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("TO THERMOMETERS")
lcd_string(Line2_String)
time.sleep(2)
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("THEN HOLD TEMP")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("DOWN TO REBOOT")
lcd_string(Line2_String)
time.sleep(2)
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("***REBOOTING***")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("Please Wait...")
lcd_string(Line2_String)
os.system("sudo shutdown -r now")
try:
with open('/sys/bus/w1/devices/' + Thermometer4_Address + '/w1_slave'):
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = (" Thermometer")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = (" No. 2 Found")
lcd_string(Line2_String)
time.sleep(2)
except IOError:
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("**THERMOMETER**")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("**No. 2 ERROR**")
lcd_string(Line2_String)
buzzer_count = 0
while (buzzer_count < 12):
mcp.output(7, 1)
time.sleep(0.1)
mcp.output(7, 0)
time.sleep(0.1)
buzzer_count = buzzer_count + 1
while(mcp.input(14) > 2):
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("CONNECT DEVICE")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("TO THERMOMETERS")
lcd_string(Line2_String)
time.sleep(2)
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("THEN HOLD TEMP")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("DOWN TO REBOOT")
lcd_string(Line2_String)
time.sleep(2)
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("***REBOOTING***")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("Please Wait...")
lcd_string(Line2_String)
os.system("sudo shutdown -r now")
# Find out if the fermentation from previous power-down is complete or not
try:
with open('/home/pi/Fridge_Start_Time.dat'):
Ferm_Start_Time = open('/home/pi/Fridge_Start_Time.dat', 'r')
# Create a data list from Fridge_Start_Time.dat row 1 (2nd row)
try:
Ferm_Start_Data = [i.strip().split() for i in Ferm_Start_Time.readlines()][1]
except:
New_Cycle()
# Join up the first and second parameters from the list to create a single string (date time)
Ferm_Start_Date_Time_Str = (str(Ferm_Start_Data[0]) + " " + str(Ferm_Start_Data[1]))
# Convert the date time string into a datetime parameter
Ferm_Start_Date_Time = datetime.datetime.strptime(Ferm_Start_Date_Time_Str, '%Y-%m-%d %H:%M:%S.%f')
# Use the third parameter from the list and save it as int Ferm_Duration
Ferm_Duration = int(Ferm_Start_Data[2])
# Convert Ferm_Duration to seconds
Ferm_Duration_Secs = Ferm_Duration*60*60*24
# Work out the difference between the Fermenation start date and time the current date and time
Time_Delta = datetime.datetime.now() - Ferm_Start_Date_Time
# Convert the time difference into seconds to then compare with the Ferm_Duration_Secs parameter
# If duration is higher than delta, then the last cycle didn't finish, so needs sets Power Interrupt
# flag to 1 and calls the Fridge cooling and display functions.
Time_Delta_Secs = Time_Delta.total_seconds()
if (Time_Delta_Secs < Ferm_Duration_Secs):
Power_Interrupt = 1
Power_Interrupt_Time = datetime.datetime.now()
Fridge_Run(Power_Interrupt, Power_Interrupt_Time)
else:
# If the previous Fermentation is complete (i.e. no power interrupt)
# Delete the old Instrumentation Log File (if it exists)
New_Cycle()
except IOError:
Power_Interrupt = 0
Power_Interrupt_Time = 0
Fridge_Run(Power_Interrupt, Power_Interrupt_Time)
#------------------------------------------------------------------------------
# SETUP THE FRIDGE LOG FILE
#------------------------------------------------------------------------------
# - Only want to delete the file if the Fridge cycle is finished!
def New_Cycle():
try:
with open('/var/www/Fridge_Log.csv'):
os.remove('/var/www/Fridge_Log.csv')
except IOError:
print "No File to Delete"
Fridge_Log = open('/var/www/Fridge_Log.csv', 'a')
print >> Fridge_Log, "Time" ',', "Fridge Temp" ',', "Wort Temp", ',', "Tgt Wort Temp", ',', "Tgt Fridge Temp" , ',', "Fridge Status", ',', "Heater Status"
Fridge_Log.flush()
#Set the power interrupt flag to 0
Power_Interrupt = 0
Power_Interrupt_Time = 0
#Gather New Fermentation Cycle Data
# Ask User How Many Days for Fermentation
Days_Total = 14
lcd_init()
while ((mcp.input(15) > 2) | (mcp.input(14) > 2)):
if ((Days_Total >5) & (Days_Total <80)):
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("Set Ferm Days")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = (" = " + str(int(Days_Total)))
lcd_string(Line2_String)
if Days_Total == 5:
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("Set Ferm Days")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = (" = " + str(int(Days_Total)) + " MIN")
lcd_string(Line2_String)
time.sleep(0.1)
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("Set Ferm Days")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = (" = " + str(int(Days_Total)))
lcd_string(Line2_String)
time.sleep(0.1)
if Days_Total == 80:
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("Set Ferm Days")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = (" = " + str(int(Days_Total)) + " MAX")
lcd_string(Line2_String)
time.sleep(0.1)
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("Set Ferm Days")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = (" = " + str(int(Days_Total)))
lcd_string(Line2_String)
time.sleep(0.1)
if (mcp.input(15) < 2):
Days_Total = Days_Total + 1
time.sleep(0.1)
if (mcp.input(14) < 2):
Days_Total = Days_Total - 1
time.sleep(0.1)
if Days_Total>80:
Days_Total = 80
if Days_Total<5:
Days_Total = 5
while ((mcp.input(15) < 2) & (mcp.input(14) < 2)):
time.sleep(0)
# Create Data File Which Records the Desired Temperature Each Day of the Brew Cycle
try:
with open('/home/pi/Fridge_Cycle.dat'):
os.remove('/home/pi/Fridge_Cycle.dat')
except IOError:
print "No File to Delete"
Fridge_Cycle = open('/home/pi/Fridge_Cycle.dat', 'a')
print >> Fridge_Cycle, "Ferm_Day", "Tgt_Wort_Temp"
Fridge_Cycle.flush()
Day = 1
Tgt_Ferm_Temp=20
while (Day<(Days_Total+1)):
lcd_init()
while ((mcp.input(15) > 2) | (mcp.input(14) > 2)):
time.sleep(0.15)
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("Set Ferm Temp")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = (" Day " + str(int(Day)) + " " + str(int(Tgt_Ferm_Temp)) + chr(223) + "C")
lcd_string(Line2_String)
if (mcp.input(15) < 2):
Tgt_Ferm_Temp = Tgt_Ferm_Temp + 1
if (mcp.input(14) < 2):
Tgt_Ferm_Temp = Tgt_Ferm_Temp - 1
if Tgt_Ferm_Temp>30:
Tgt_Ferm_Temp = 30
if Tgt_Ferm_Temp<-2:
Tgt_Ferm_Temp = -2
while ((mcp.input(15) < 2) & (mcp.input(14) < 2)):
time.sleep(0)
print >> Fridge_Cycle, str(Day), Tgt_Ferm_Temp
Fridge_Cycle.flush()
Day = Day + 1
# Create Data File Which Records the Date and Time Which the Fridge Controller Starts
try:
with open('/home/pi/Fridge_Start_Time.dat'):
os.remove('/home/pi/Fridge_Start_Time.dat')
except IOError:
print "No File to Delete"
Fridge_Start_Time = open('/home/pi/Fridge_Start_Time.dat', 'a')
print >> Fridge_Start_Time, "Start_Date_and_Time", "Fermentation_Duration"
Fridge_Start_Time.flush()
print >> Fridge_Start_Time, str(datetime.datetime.now()), Days_Total
Fridge_Start_Time.flush()
Fridge_Run(Power_Interrupt, Power_Interrupt_Time)
############################################################################################
############################################################################################
#------------------------------------------------------------------------------
# Fridge Cycle Function
#------------------------------------------------------------------------------
############################################################################################
############################################################################################
def Fridge_Run(Power_Interrupt, Power_Interrupt_Time):
#------------------------------------------------------------------------------
# SETUP THE ONE WIRE THERMOMETER SYSTEM
#------------------------------------------------------------------------------
base_dir = '/sys/bus/w1/devices/'
# Setup Thermometer 1 Location
device1_folder = glob.glob(base_dir + Thermometer3_Address)[0]
device1_file = device1_folder + '/w1_slave'
# setup Thermomenter 2 Location
device2_folder = glob.glob(base_dir + Thermometer4_Address)[0]
device2_file = device2_folder + '/w1_slave'
dateString = '%Y-%m-%d %H:%M:%S'
global Target_Wort_Temp
global Current_Day_No
global Fridge_Cycle_Day
global Remaining_Days
global Remaining_Hours_str
global Remaining_Mins_str
try:
with open('/home/pi/Fridge_Start_Time.dat'):
Ferm_Start_Time = open('/home/pi/Fridge_Start_Time.dat', 'r')
# Create a data list from Fridge_Start_Time.dat row 1 (2nd row)
Ferm_Start_Data = [i.strip().split() for i in Ferm_Start_Time.readlines()][1]
# Join up the first and second parameters from the list to create a single string (date time)
Ferm_Start_Date_Time_Str = (str(Ferm_Start_Data[0]) + " " + str(Ferm_Start_Data[1]))
# Convert the date time string into a datetime parameter
Ferm_Start_Date_Time = datetime.datetime.strptime(Ferm_Start_Date_Time_Str, '%Y-%m-%d %H:%M:%S.%f')
# Use the third parameter from the list and save it as int Ferm_Duration
Ferm_Duration = int(Ferm_Start_Data[2])
# Convert Ferm_Duration to seconds
Ferm_Duration_Secs = Ferm_Duration*60*60*24
# Work out the difference between the Fermenation start date and time the current date and time
Time_Delta = datetime.datetime.now() - Ferm_Start_Date_Time
# Convert the time difference into seconds to then compare with the Ferm_Duration_Secs parameter
Time_Delta_seconds = Time_Delta.total_seconds()
except IOError:
buzzer_count = 0
while (buzzer_count < 12):
mcp.output(7, 1)
time.sleep(0.1)
mcp.output(7, 0)
time.sleep(0.1)
buzzer_count = buzzer_count + 1
while(mcp.input(14) > 2):
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("FILE READ ERROR")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = (" REBOOT REQ'D")
lcd_string(Line2_String)
time.sleep(2)
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("HOLD TEMP DOWN")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = (" TO REBOOT")
lcd_string(Line2_String)
time.sleep(2)
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("***REBOOTING***")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("Please Wait...")
lcd_string(Line2_String)
os.system("sudo shutdown -r now")
Logging_Time = datetime.datetime.now()
global Fridge_Last_Run
Fridge_Last_Run = datetime.datetime.now()
global Compressor_Protection
Compressor_Protection = 0
global Heater_Status
Heater_Status = 0
global Fridge_Status
Fridge_Status = 0
global Display_Ready
Display_Ready = 0
# Start Fridge_Display Thread
Fridge_Display_thread = Thread(target = Fridge_Display, args = (Power_Interrupt, Power_Interrupt_Time, ))
Fridge_Display_thread.start()
# Temperature regulation code goes here:
global Wort_Temperature
Wort_Temperature = 10
global Fridge_Temperature
Fridge_Temperature = 10
global Wort_Temp_Error
global Fridge_Temp_Error
Heater_Hyst = 0
Fridge_Hyst = 0
Lock_Out = 0
while(True):
try:
# Work out the difference between the Fermenation start date and time the current date and time
Time_Delta = datetime.datetime.now() - Ferm_Start_Date_Time
# Convert the time difference into seconds to then compare with the Ferm_Duration_Secs parameter
Time_Delta_seconds = Time_Delta.total_seconds()
Current_Day_No = int(Time_Delta_seconds/60/60/24) + 1
Remaining_Days = Ferm_Duration - Current_Day_No
if ((Ferm_Duration*24*60*60) > Time_Delta_seconds):
Remaining_Time_hh_mm = ((Ferm_Duration*24*60*60)-Time_Delta_seconds-(Remaining_Days*24*60*60))
Remaining_Hours = int(Remaining_Time_hh_mm/60/60)
Remaining_Mins = ((Remaining_Time_hh_mm/60) - (Remaining_Hours*60))
Remaining_Hours_str = str(int(Remaining_Hours))
if Remaining_Hours < 10:
Remaining_Hours_str = ("0" + str(int(Remaining_Hours)))
Remaining_Mins_str = str(int(Remaining_Mins))
if Remaining_Mins < 10:
Remaining_Mins_str = ("0" + str(int(Remaining_Mins)))
Fridge_Cycle_Day = open('/home/pi/Fridge_Cycle.dat', 'r')
Fridge_Cycle_Day = [i.strip().split() for i in Fridge_Cycle_Day.readlines()][Current_Day_No]
Target_Wort_Temp = int(Fridge_Cycle_Day[1])
if ((Ferm_Duration*24*60*60) < Time_Delta_seconds):
Remaining_Days = 0
Fridge_Cycle_Day = open('/home/pi/Fridge_Cycle.dat', 'r')
Fridge_Cycle_Day = [i.strip().split() for i in Fridge_Cycle_Day.readlines()][Ferm_Duration]
Target_Wort_Temp = int(Fridge_Cycle_Day[1])
Remaining_Days = 0
Remaining_Hours_str = "00"
Remaining_Mins_str = "00"
Wort_Temperature_Last = Wort_Temperature
Wort_Temperature = read_temp_1(device1_file)
if Wort_Temperature == -100:
Wort_Temperature = Wort_Temperature_Last
Wort_Therm_Error = 1
if Wort_Temperature != -100:
Wort_Temp_Error = 0
Fridge_Temperature_Last = Fridge_Temperature
Fridge_Temperature = read_temp_2(device2_file)
if Fridge_Temperature == -100:
Fridge_Temperature = Fridge_Temperature_Last
Fridge_Temp_Error = 1
if Fridge_Temperature != -100:
Fridge_Temp_Error = 0
Display_Ready = 1
# Temperature regulation script
Wort_Temp_Delta = Target_Wort_Temp - Wort_Temperature
if Wort_Temp_Delta > 3:
Air_Temp_Delta = Wort_Temp_Delta * 2
if ((Wort_Temp_Delta < 3) & (Wort_Temp_Delta > 1)):
Air_Temp_Delta = Wort_Temp_Delta * 2.5
if ((Wort_Temp_Delta <=1) & (Wort_Temp_Delta > 0.3)):
Air_Temp_Delta = Wort_Temp_Delta * 3 #Vary this value to get tighter or looser temperature control
if ((Wort_Temp_Delta <=0.3) & (Wort_Temp_Delta > 0)):
Air_Temp_Delta = Wort_Temp_Delta * 4 #Vary this value to get tighter or looser temperature control
if Wort_Temp_Delta < -3:
Air_Temp_Delta = Wort_Temp_Delta * 2
if ((Wort_Temp_Delta > -3) & (Wort_Temp_Delta < -1)):
Air_Temp_Delta = Wort_Temp_Delta * 2.5
if ((Wort_Temp_Delta >=-1) & (Wort_Temp_Delta < -0.3)):
Air_Temp_Delta = Wort_Temp_Delta * 3 #Vary this value to get tighter or looser temperature control
if ((Wort_Temp_Delta >= -0.3) & (Wort_Temp_Delta < 0)):
Air_Temp_Delta = Wort_Temp_Delta * 4 #Vary this value to get tighter or looser temperature control
if Air_Temp_Delta > 8:
Air_Temp_Delta = 8
if Air_Temp_Delta < -15:
Air_Temp_Delta = -15
Target_Fridge_Air_Temp = Wort_Temperature + Air_Temp_Delta
#Turn Heater ON
if ((Fridge_Temperature < (Target_Fridge_Air_Temp-0.5)) & (Heater_Hyst == 0) & (Lock_Out == 0)):
if Fridge_Status == 1:
Fridge_Last_Run = datetime.datetime.now()
Compressor_Protection = 0
Heater_Status = 1
Fridge_Status = 0
mcp.output(12, 0) #Heater ON
mcp.output(13, 1) #Fridge OFF
if (Fridge_Temperature > (Target_Fridge_Air_Temp - 0.5)):
Heater_Hyst = 1
Heater_Status = 0
mcp.output(12, 1) #Heater OFF
if (Fridge_Temperature < (Target_Fridge_Air_Temp - 1)):
Heater_Hyst = 0
#Turn Fridge ON
if ((Fridge_Temperature > (Target_Fridge_Air_Temp+0.5)) & (Fridge_Hyst == 0) & (Lock_Out == 0)):
if ((datetime.datetime.now() - Fridge_Last_Run).total_seconds()) > 180:
Compressor_Protection = 0
Fridge_Status = 1
Heater_Status = 0
mcp.output(13, 0) #Fridge ON
mcp.output(12, 1) #Heater OFF
else:
Compressor_Protection = 1
if (Fridge_Temperature < (Target_Fridge_Air_Temp + 0.5)):
Fridge_Hyst = 1
Fridge_Status = 0
mcp.output(13, 1) #Fridge OFF
if (Fridge_Temperature > (Target_Fridge_Air_Temp + 1)):
Fridge_Hyst = 0
if ((Fridge_Temperature < (Target_Fridge_Air_Temp + 0.3)) & (Fridge_Temperature > (Target_Fridge_Air_Temp - 0.3))):
Lock_Out = 1
Fridge_Status = 0
Heater_Status = 0
mcp.output(13, 1) #Fridge OFF
mcp.output(12, 1) #Heater OFF
else:
Lock_Out = 0
Logging_Time_Counter = (datetime.datetime.now() - Logging_Time)
Logging_Time_Counter_Secs = Logging_Time_Counter.total_seconds()
# Write the data to the log file
if Logging_Time_Counter_Secs > 300:
try:
Fridge_Log = open('/var/www/Fridge_Log.csv', 'a')
print >> Fridge_Log, datetime.datetime.now().strftime(dateString), ',', Fridge_Temperature, ',', Wort_Temperature, ',', Target_Wort_Temp, ',', Target_Fridge_Air_Temp, ',', Fridge_Status, ',', Heater_Status
Fridge_Log.flush()
Logging_Time = datetime.datetime.now()
except IOerror, e:
scriptdebug(e)
except Exception, e:
scriptdebug(e)
############################################################################################
############################################################################################
#------------------------------------------------------------------------------
# FRIDGE DISPLAY FUNCTION
#------------------------------------------------------------------------------
############################################################################################
############################################################################################
def Fridge_Display(Power_Interrupt, Power_Interrupt_Time):
Last_Cycle_Time = datetime.datetime.now()
Display_Sequence = 1
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = (" Waiting for")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("Temperature Data")
lcd_string(Line2_String)
while(True):
if (Display_Ready == 1):
if (mcp.input(15) < 2):
lcd_init()
Current_Time = datetime.datetime.now()
if ((int((Current_Time - Last_Cycle_Time).total_seconds())) > 8):
lcd_init()
Display_Sequence = Display_Sequence+1
Last_Cycle_Time = Current_Time
if Display_Sequence > 7:
Display_Sequence = 1
if (mcp.input(14) < 2):
Display_Sequence = Display_Sequence - 1
while (mcp.input(14) < 2):
Last_Cycle_Time = datetime.datetime.now()
if (mcp.input(15) < 2):
Display_Sequence = Display_Sequence + 1
while (mcp.input(15) < 2):
Last_Cycle_Time = datetime.datetime.now()
if Display_Sequence < 1:
Display_Sequence = 7
if Wort_Temp_Error == 1:
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("WORT THERMOMETER")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = (" ERROR")
lcd_string(Line2_String)
if Fridge_Temp_Error == 1:
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("FRDG THERMOMETER")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = (" ERROR")
lcd_string(Line2_String)
if ((Fridge_Temp_Error == 0) & (Wort_Temp_Error == 0)):
if Display_Sequence == 1:
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("Target Wort Temp")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = (" " + (str(Target_Wort_Temp)) + chr(223) + "C")
lcd_string(Line2_String)
if Display_Sequence == 2:
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("Wort Temperature")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = (" " + (str(Wort_Temperature)) + chr(223) + "C")
lcd_string(Line2_String)
if Display_Sequence == 3:
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("Fridge Air Temp")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = (" " + (str(Fridge_Temperature)) + chr(223) + "C")
lcd_string(Line2_String)
if Display_Sequence == 4:
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("Fermentation Day")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = (" " + str(Current_Day_No))
lcd_string(Line2_String)
if Display_Sequence == 5:
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("Remaining Time")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = (" " + str(Remaining_Days) + " Days " + Remaining_Hours_str + ":" + Remaining_Mins_str)
lcd_string(Line2_String)
if Display_Sequence == 6:
if (Fridge_Status == 0) & (Compressor_Protection == 0):
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("Fridge = OFF")
lcd_string(Line1_String)
if ((Fridge_Status == 1) & (Compressor_Protection == 0)):
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("Fridge = ON")
lcd_string(Line1_String)
if ((Fridge_Status == 0) & (Compressor_Protection == 1)):
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("Fridge = PM " + str(int(180-(datetime.datetime.now() - Fridge_Last_Run).total_seconds())))
lcd_string(Line1_String)
if Heater_Status == 0:
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("Heater = OFF")
lcd_string(Line2_String)
if Heater_Status == 1:
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("Heater = ON")
lcd_string(Line2_String)
if ((Display_Sequence == 7) & (Power_Interrupt == 0)):
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = (" Power Status")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = (" OK ")
lcd_string(Line2_String)
if ((Display_Sequence == 7) & (Power_Interrupt == 1)):
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("Power Interrupt")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = (str(Power_Interrupt_Time))
lcd_string(Line2_String)
if ((mcp.input(15) < 2) & (mcp.input(14) < 2)):
while ((mcp.input(15) < 2) & (mcp.input(14) < 2)):
time.sleep(0)
Menu_Sequence = 1
Timeout_Counter_Start = datetime.datetime.now()
while (int((datetime.datetime.now() - Timeout_Counter_Start).total_seconds())) < 7:
if (mcp.input(14) < 2):
Menu_Sequence = Menu_Sequence - 1
while (mcp.input(14) < 2):
Timeout_Counter_Start = datetime.datetime.now()
if (mcp.input(15) < 2):
Menu_Sequence = Menu_Sequence + 1
while (mcp.input(15) < 2):
Timeout_Counter_Start = datetime.datetime.now()
if Menu_Sequence > 4:
Menu_Sequence = 4
if Menu_Sequence < 1:
Menu_Sequence = 1
if Menu_Sequence == 1:
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("Increase Day +")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("Temperature")
lcd_string(Line2_String)
if Menu_Sequence == 2:
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("Decrease Day +")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("Temperature -")
lcd_string(Line2_String)
if Menu_Sequence == 3:
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("New Ferm +")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("Schedule -")
lcd_string(Line2_String)
if (((mcp.input(15) < 2) & (mcp.input(14) < 2)) & Menu_Sequence == 3):
while ((mcp.input(15) < 2) & (mcp.input(14) < 2)):
Timeout_Counter_Start = datetime.datetime.now()
while (int((datetime.datetime.now() - Timeout_Counter_Start).total_seconds())) < 7:
Yes_No = 1
if (mcp.input(15) < 2):
Timeout_Counter_Start = datetime.datetime.now()
Yes_No = Yes_No + 1
if (mcp.input(14) < 2):
Timeout_Counter_Start = datetime.datetime.now()
Yes_No = Yes_No - 1
if Yes_No < 0:
Yes_No = 1
if Yes_No > 1:
Yes_No = 0
if Yes_No == 1:
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("Erase Current")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("Schedule? YES")
if Yes_No == 0:
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("Erase Current")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("Schedule? NO")
if Menu_Sequence == 4:
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("Backup")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("One Day -")
lcd_string(Line2_String)
############################################################################################
############################################################################################
#------------------------------------------------------------------------------
# MAIN FUNCTION
#------------------------------------------------------------------------------
############################################################################################
############################################################################################
print "Starting Program (CTRL+Z to quit)"
dateString = '%Y-%m-%d %H:%M:%S'
try:
with open('/home/pi/error1.log'):
os.remove('/home/pi/error1.log')
except IOError:
print "No File to Delete"
try:
with open('/home/pi/error.log'):
os.rename('/home/pi/error.log', '/home/pi/error1.log')
except IOError:
print "No File to Rename"
try:
with open('/home/pi/RPi_Brewery_Controller.config'):
########################### FRIDGE THERM 1 #############################
Brewery_Config = open('/home/pi/RPi_Brewery_Controller.config', 'r')
# Create a data list from Brewery_Controller.config row 1 (2nd row)
Fridge_Therm1 = [i.strip().split() for i in Brewery_Config.readlines()][1]
# Show the second item in the row (the thermometer address)
Thermometer3_Address = str(Fridge_Therm1[1])
########################### FRIDGE THERM 2 #############################
Brewery_Config = open('/home/pi/RPi_Brewery_Controller.config', 'r')
# Create a data list from Brewery_Controller.config row 1 (2nd row)
Fridge_Therm2 = [i.strip().split() for i in Brewery_Config.readlines()][2]
# Show the second item in the row (the thermometer address)
Thermometer4_Address = str(Fridge_Therm2[1])
########################### BOILER THERM 1 #############################
Brewery_Config = open('/home/pi/RPi_Brewery_Controller.config', 'r')
# Create a data list from Brewery_Controller.config row 1 (2nd row)
Boiler_Therm1 = [i.strip().split() for i in Brewery_Config.readlines()][3]
# Show the second item in the row (the thermometer address)
Thermometer1_Address = str(Boiler_Therm1[1])
########################### BOILER THERM 2 #############################
Brewery_Config = open('/home/pi/RPi_Brewery_Controller.config', 'r')
# Create a data list from Brewery_Controller.config row 1 (2nd row)
Boiler_Therm2 = [i.strip().split() for i in Brewery_Config.readlines()][4]
# Show the second item in the row (the thermometer address)
Thermometer2_Address = str(Boiler_Therm2[1])
except IOError:
try:
with open('/home/pi/RPi_Brewery_Controller.config'):
os.remove('/home/pi/RPi_Brewery_Controller.config')
except IOError:
print "No File to Delete"
RPi_Brewery_Controller.config = open('/home/pi/RPi_Brewery_Controller.config', 'a')
print >> RPi_Brewery_Controller.config, "Raspberry Pi Brewery Controller Config File"
Boiler_Log.flush()
print >> RPi_Brewery_Controller.config, "Fridge_Thermometer_Wort="
Boiler_Log.flush()
print >> RPi_Brewery_Controller.config, "Fridge_Thermometer_Fridge_Air="
Boiler_Log.flush()
print >> RPi_Brewery_Controller.config, "Boiler/HLT_Thermometer_1="
Boiler_Log.flush()
print >> RPi_Brewery_Controller.config, "Boiler/HLT_Thermometer_2="
Boiler_Log.flush()
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("**CONFIG FILE**")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("**ERROR**")
lcd_string(Line2_String)
time.sleep(2)
buzzer_count = 0
while (buzzer_count < 12):
mcp.output(7, 1)
time.sleep(0.1)
mcp.output(7, 0)
time.sleep(0.1)
buzzer_count = buzzer_count + 1
while(mcp.input(14) > 2):
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("EDIT CONFIG FILE")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("WITH THERM DATA")
lcd_string(Line2_String)
time.sleep(2)
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("THEN HOLD TEMP")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("DOWN TO REBOOT")
lcd_string(Line2_String)
time.sleep(2)
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("***REBOOTING***")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("Please Wait...")
lcd_string(Line2_String)
os.system("sudo shutdown -r now")
# Startup Display
GPIO.setmode(GPIO.BCM) # Use BCM GPIO numbers
GPIO.setup(LCD_E, GPIO.OUT) # E
GPIO.setup(LCD_RS, GPIO.OUT) # RS
GPIO.setup(LCD_D4, GPIO.OUT) # DB4
GPIO.setup(LCD_D5, GPIO.OUT) # DB5
GPIO.setup(LCD_D6, GPIO.OUT) # DB6
GPIO.setup(LCD_D7, GPIO.OUT) # DB7
# Initialise display
lcd_init()
# Initialise the program parameters
temp_reached = 0
global Temperature
Temperature = 99
tens = 0
units = 0
target_temperature = 72
Line1_String = ""
Line2_String = ""
# Wait for User to start boiler
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("ROBBO'S BREWERY")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("BOILER CONTROL")
lcd_string(Line2_String)
print ""
print ""
print ""
print ""
print ""
print ""
print ""
print ""
print ""
print ""
print ""
print " Average Temperature = "
print " Target Temperature = "
print " ____________________________________"
print " ", Line1_String
print " ", Line2_String
print " ____________________________________"
time.sleep(5)
try:
with open('/sys/bus/w1/devices/' + Thermometer1_Address + '/w1_slave'):
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("***BOILER/HLT***")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("*MODE DETECTED*")
lcd_string(Line2_String)
time.sleep(2)
Boiler_HLT_Mode(temp_reached, tens, units, target_temperature, dateString, Line1_String, Line2_String)
except IOError:
try:
with open('/sys/bus/w1/devices/' + Thermometer3_Address + '/w1_slave'):
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("***FV FRIDGE***")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("*MODE DETECTED*")
lcd_string(Line2_String)
time.sleep(2)
FV_Fridge_Mode()
except IOError:
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("**THERMOMETER**")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("**SENSOR ERROR**")
lcd_string(Line2_String)
time.sleep(2)
buzzer_count = 0
while (buzzer_count < 12):
mcp.output(7, 1)
time.sleep(0.1)
mcp.output(7, 0)
time.sleep(0.1)
buzzer_count = buzzer_count + 1
while(mcp.input(14) > 2):
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("CONNECT DEVICE")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("TO THERMOMETERS")
lcd_string(Line2_String)
time.sleep(2)
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("THEN HOLD TEMP")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("DOWN TO REBOOT")
lcd_string(Line2_String)
time.sleep(2)
lcd_byte(LCD_LINE_1, LCD_CMD)
Line1_String = ("***REBOOTING***")
lcd_string(Line1_String)
lcd_byte(LCD_LINE_2, LCD_CMD)
Line2_String = ("Please Wait...")
lcd_string(Line2_String)
os.system("sudo shutdown -r now")