'''//////////////////////////////////////////////////////////////////////////////////////////////
OLDfivePipelineGui.py

A python implemented Human Machine Interface(HMI) for connecting to 5 simulated PLC nodes using Modbus/TCP.

author: Zach Thornton
May 2015
Version 1.0
    
Copyright (C) 2015  Zach Thornton,Tommy Morris, Mississippi State University
Primary Contact: Tommy Morris: tommy.morris@uah.edu

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

  See <http://www.gnu.org/licenses/>.

////////////////////////////////////////////////////////////////////////////////////////////'''

import modbus_tk
import modbus_tk.defines as cst
import modbus_tk.modbus_tcp as modbus_tcp
#for the MODBUS float conversion
from struct import *
#GUI
from Tkinter import * #had to install python-tk
#for sleeping
import time
import csv
import datetime 
import string
#from pylab import * #had to install 
import atexit

VIRTUAL_PLC_IP = "10.128.0.6"
VIRTUAL_PLC2_IP = "10.128.0.7"
VIRTUAL_PLC3_IP = "10.128.0.8"
VIRTUAL_PLC4_IP = "10.128.0.9"
VIRTUAL_PLC5_IP = "10.128.0.10"
VIRTUAL_PLC_PORT = 502
MAX_PRESSURE = 1000

def guiInit(valuesArray,newValuesArray):
#graphics initialization code. This function creates the static elements, and dynamic ones and returns the guiObjects class for the dynamic objects	
	
	#temp variables so I don't have to refer to the indicie of the array all the time	
	values = valuesArray[0]
	values2 = valuesArray[1]
	values3 = valuesArray[2]
	values4 = valuesArray[3]
	values5 = valuesArray[4]
	newValues = newValuesArray[0]
	newValues2 = newValuesArray[1]
	newValues3 = newValuesArray[2]
	newValues4 = newValuesArray[3]
	newValues5 = newValuesArray[4]
	
	#turning reset, and rate into rounded floats and turning the mode and control values into strings
	resetRound = round(float(values.PIDResetRate[0]),2)
	resetString = float(resetRound)
	rateRound = round(float(values.PIDRate[0]),2)
	rateString = float(rateRound)
	pressureRound = round(float(values.PIDPressureScaled[0]),2)
	pressureString = float(pressureRound)
	spRound = round(float(values.PIDSetpoint[0]),2)
	spString = float(spRound)
	gainRound = round(float(values.PIDGain[0]),2)
	gainString = float(gainRound)

	if(values.MstrWSystemMode == 0):
		modeString = "OFF"
	elif(values.MstrWSystemMode == 1):
		modeString = "MAN"
	elif(values.MstrWSystemMode == 2):
		modeString = "AUTO"
	else:
		modeString = "?"
	if(values2.MstrWControlPumpSol == 0):
		controlmodeString = "PUMP"
	elif(values2.MstrWControlPumpSol == 1):
		controlmodeString = "SOL"
	else:
		controlmodeString = "?"
	
	#Second set for plc#2
	#turning reset, and rate into rounded floats and turning the mode and control values into strings
	resetRound2 = round(float(values2.PIDResetRate[0]),2)
	resetString2 = float(resetRound2)
	rateRound2 = round(float(values2.PIDRate[0]),2)
	rateString2 = float(rateRound2)
	pressureRound2 = round(float(values2.PIDPressureScaled[0]),2)
	pressureString2 = float(pressureRound2)
	spRound2 = round(float(values2.PIDSetpoint[0]),2)
	spString2 = float(spRound2)
	gainRound2 = round(float(values2.PIDGain[0]),2)
	gainString2 = float(gainRound2)

	if(values2.MstrWSystemMode == 0):
		modeString2 = "OFF"
	elif(values2.MstrWSystemMode == 1):
		modeString2 = "MAN"
	elif(values2.MstrWSystemMode == 2):
		modeString2 = "AUTO"
	else:
		modeString2 = "?"
	if(values2.MstrWControlPumpSol == 0):
		controlmodeString2 = "PUMP"
	elif(values2.MstrWControlPumpSol == 1):
		controlmodeString2 = "SOL"
	else:
		controlmodeString2 = "?"

	#Third set for plc#3
	#turning reset, and rate into rounded floats and turning the mode and control values into strings
	resetRound3 = round(float(values3.PIDResetRate[0]),2)
	resetString3 = float(resetRound3)
	rateRound3 = round(float(values3.PIDRate[0]),2)
	rateString3 = float(rateRound3)
	pressureRound3 = round(float(values3.PIDPressureScaled[0]),2)
	pressureString3 = float(pressureRound3)
	spRound3 = round(float(values3.PIDSetpoint[0]),2)
	spString3 = float(spRound3)
	gainRound3 = round(float(values3.PIDGain[0]),2)
	gainString3 = float(gainRound3)

	if(values3.MstrWSystemMode == 0):
		modeString3 = "OFF"
	elif(values3.MstrWSystemMode == 1):
		modeString3 = "MAN"
	elif(values3.MstrWSystemMode == 2):
		modeString3 = "AUTO"
	else:
		modeString3 = "?"
	if(values3.MstrWControlPumpSol == 0):
		controlmodeString3 = "PUMP"
	elif(values3.MstrWControlPumpSol == 1):
		controlmodeString3 = "SOL"
	else:
		controlmodeString3 = "?"

	#Fourth set for plc#4
	#turning reset, and rate into rounded floats and turning the mode and control values into strings
	resetRound4 = round(float(values4.PIDResetRate[0]),2)
	resetString4 = float(resetRound4)
	rateRound4 = round(float(values4.PIDRate[0]),2)
	rateString4 = float(rateRound4)
	pressureRound4 = round(float(values4.PIDPressureScaled[0]),2)
	pressureString4 = float(pressureRound4)
	spRound4 = round(float(values4.PIDSetpoint[0]),2)
	spString4 = float(spRound4)
	gainRound4 = round(float(values4.PIDGain[0]),2)
	gainString4 = float(gainRound4)

	if(values4.MstrWSystemMode == 0):
		modeString4 = "OFF"
	elif(values4.MstrWSystemMode == 1):
		modeString4 = "MAN"
	elif(values4.MstrWSystemMode == 2):
		modeString4 = "AUTO"
	else:
		modeString4 = "?"
	if(values4.MstrWControlPumpSol == 0):
		controlmodeString4 = "PUMP"
	elif(values4.MstrWControlPumpSol == 1):
		controlmodeString4 = "SOL"
	else:
		controlmodeString4 = "?"

	#Fifth set for plc#5
	#turning reset, and rate into rounded floats and turning the mode and control values into strings
	resetRound5 = round(float(values5.PIDResetRate[0]),2)
	resetString5 = float(resetRound5)
	rateRound5 = round(float(values5.PIDRate[0]),2)
	rateString5 = float(rateRound5)
	pressureRound5 = round(float(values5.PIDPressureScaled[0]),2)
	pressureString5 = float(pressureRound5)
	spRound5 = round(float(values5.PIDSetpoint[0]),2)
	spString5 = float(spRound5)
	gainRound5 = round(float(values5.PIDGain[0]),2)
	gainString5 = float(gainRound5)

	if(values5.MstrWSystemMode == 0):
		modeString5 = "OFF"
	elif(values5.MstrWSystemMode == 1):
		modeString5 = "MAN"
	elif(values5.MstrWSystemMode == 2):
		modeString5 = "AUTO"
	else:
		modeString5 = "?"
	if(values5.MstrWControlPumpSol == 0):
		controlmodeString5 = "PUMP"
	elif(values5.MstrWControlPumpSol == 1):
		controlmodeString5 = "SOL"
	else:
		controlmodeString5 = "?"

	#dynamic elements to be used elsewhere
	class guiObjects:
		master = Tk()
		w = Canvas(master, width=2000, height=2000, background="white")	
		#xStart,yStart,xStop,yStart		
		w.create_rectangle(5,310, 95, 325, fill="grey")		#into pump1
		w.create_rectangle(220,300,340,320,fill="grey")		#into pump2
		w.create_rectangle(485,290,585,310,fill="grey")		#into pump3
		w.create_rectangle(700,285,800,300,fill="grey")		#into pump4
		w.create_rectangle(960,280,1060,295,fill="grey")	#into pump5	
		#PLC#1 Values
		pumpOval =w.create_oval(85,295, 135, 345, fill="red", outline = "red")
		pumpRect = w.create_rectangle(125,300,150,320, fill="red",outline = "red")
		#xPoint1,yPoint1,xPoint2,yPoint2,xPoint3,yPoint3
		valve1 = w.create_polygon(190,400,210,420,230,400,fill="red",outline="black")
		valve2 = w.create_polygon(190,440,210,420,230,440,fill="red",outline="black")
		valve3 = w.create_rectangle(210,419,240,421,fill="red",outline ="black")
		valve4 = w.create_rectangle(240,405,250,435,fill="red",outline ="black")
		#xCenter,yCenter		
		psi = w.create_text(100,50,text=pressureString)
		setpoint = w.create_text(100,70,text=spString)
		gain = w.create_text(100,90,text=gainString)
		reset = w.create_text(100,110,text=resetString)	
		rate = w.create_text(100,130,text=rateString)
		mode = w.create_text(100,150,text=modeString)
		control = w.create_text(100,180,text=controlmodeString)
		setpointEntry = Entry(master, width=5)
		gainEntry = Entry(master, width=5)
		resetEntry = Entry(master, width=5)
		rateEntry = Entry(master, width=5)
		offButton = Button(master, text="OFF", command=lambda:modeOff(newValues))
		manButton = Button(master, text="MAN", command=lambda:modeMan(newValues))
		autoButton = Button(master, text="AUTO", command=lambda:modeAuto(newValues))
		pumpButton = Button(master, text="PUMP", command=lambda:controlPump(newValues))
		solButton = Button(master, text="SOL", command=lambda:controlSol(newValues))
		pumpOffButton = Button(master, text="OFF", command=lambda:pumpOff(newValues))
		pumpOnButton = Button(master, text="ON", command=lambda:pumpOn(newValues))
		solCloseButton = Button(master, text="CLOSE", command=lambda:solClose(newValues))
		solOpenButton = Button(master, text="OPEN", command=lambda:solOpen(newValues))
		w.pack()
		#PLC2 VALUES
		pumpOval2 =w.create_oval(320,290,370,330,fill="red",outline="red")
		pumpRect2 = w.create_rectangle(350,290,385,310,fill="red",outline="red")
		valve2_1 = w.create_polygon(455,410,475,430,495,410,fill="red",outline="black") 
		valve2_2 = w.create_polygon(455,450,475,430,495,450,fill="red",outline="black")
		valve2_3 = w.create_rectangle(475,429,500,431,fill="red",outline="black")
		valve2_4 = w.create_rectangle(500,415,510,445,fill="red",outline="black")
		psi2 = w.create_text(320,50,text=pressureString2)
		setpoint2 = w.create_text(320,70,text=spString2)
		gain2 = w.create_text(320,90,text=gainString2)
		reset2 = w.create_text(320,110,text=resetString2)	
		rate2 = w.create_text(320,130,text=rateString2)
		mode2 = w.create_text(320,150,text=modeString2)
		control2 = w.create_text(320,180,text=controlmodeString2)
		setpointEntry2 = Entry(master, width=5)
		gainEntry2 = Entry(master, width=5)
		resetEntry2 = Entry(master, width=5)
		rateEntry2 = Entry(master, width=5)
		offButton2 = Button(master, text="OFF", command=lambda:modeOff(newValues2))
		manButton2 = Button(master, text="MAN", command=lambda:modeMan(newValues2))
		autoButton2 = Button(master, text="AUTO", command=lambda:modeAuto(newValues2))
		pumpButton2 = Button(master, text="PUMP", command=lambda:controlPump(newValues2))
		solButton2 = Button(master, text="SOL", command=lambda:controlSol(newValues2))
		pumpOffButton2 = Button(master, text="OFF", command=lambda:pumpOff(newValues2))
		pumpOnButton2 = Button(master, text="ON", command=lambda:pumpOn(newValues2))
		solCloseButton2 = Button(master, text="CLOSE", command=lambda:solClose(newValues2))
		solOpenButton2 = Button(master, text="OPEN", command=lambda:solOpen(newValues2))
		w.pack()
		#PLC3 VALUES
		pumpOval3 =w.create_oval(570,285,610,325,fill="red",outline="red") 
		pumpRect3 = w.create_rectangle(590,285,620,300,fill="red",outline="red")
		valve3_1 = w.create_polygon(670,400,690,420,710,400,fill="red",outline="black") 
		valve3_2 = w.create_polygon(670,440,690,420,710,440,fill="red",outline="black")	
		valve3_3 = w.create_rectangle(690,419,720,421,fill="red",outline="black")
		valve3_4 = w.create_rectangle(720,405,730,435,fill="red",outline="black")
		psi3 = w.create_text(570,50,text=pressureString3)
		setpoint3 = w.create_text(570,70,text=spString3)
		gain3 = w.create_text(570,90,text=gainString3)
		reset3 = w.create_text(570,110,text=resetString3)	
		rate3 = w.create_text(570,130,text=rateString3)
		mode3 = w.create_text(570,150,text=modeString3)
		control3 = w.create_text(570,180,text=controlmodeString3)
		setpointEntry3 = Entry(master, width=5)
		gainEntry3 = Entry(master, width=5)
		resetEntry3 = Entry(master, width=5)
		rateEntry3 = Entry(master, width=5)
		offButton3 = Button(master, text="OFF", command=lambda:modeOff(newValues3))
		manButton3 = Button(master, text="MAN", command=lambda:modeMan(newValues3))
		autoButton3 = Button(master, text="AUTO", command=lambda:modeAuto(newValues3))
		pumpButton3 = Button(master, text="PUMP", command=lambda:controlPump(newValues3))
		solButton3 = Button(master, text="SOL", command=lambda:controlSol(newValues3))
		pumpOffButton3 = Button(master, text="OFF", command=lambda:pumpOff(newValues3))
		pumpOnButton3 = Button(master, text="ON", command=lambda:pumpOn(newValues3))
		solCloseButton3 = Button(master, text="CLOSE", command=lambda:solClose(newValues3))
		solOpenButton3 = Button(master, text="OPEN", command=lambda:solOpen(newValues3))
		w.pack()
		#PLC4 VALUES
		pumpOval4 =w.create_oval(790,280,830,320,fill="red",outline="red") 
		pumpRect4 = w.create_rectangle(810,280,840,295,fill="red",outline="red")
		valve4_1 = w.create_polygon(930,400,950,420,970,400,fill="red",outline="black") 
		valve4_2 = w.create_polygon(930,440,950,420,970,440,fill="red",outline="black")	
		valve4_3 = w.create_rectangle(950,419,980,421,fill="red",outline="black")
		valve4_4 = w.create_rectangle(980,405,990,435,fill="red",outline="black")
		psi4 = w.create_text(790,50,text=pressureString4)
		setpoint4 = w.create_text(790,70,text=spString4)
		gain4 = w.create_text(790,90,text=gainString4)
		reset4 = w.create_text(790,110,text=resetString4)	
		rate4 = w.create_text(790,130,text=rateString4)
		mode4 = w.create_text(790,150,text=modeString4)
		control4 = w.create_text(790,180,text=controlmodeString4)
		setpointEntry4 = Entry(master, width=5)
		gainEntry4 = Entry(master, width=5)
		resetEntry4 = Entry(master, width=5)
		rateEntry4 = Entry(master, width=5)
		offButton4 = Button(master, text="OFF", command=lambda:modeOff(newValues4))
		manButton4 = Button(master, text="MAN", command=lambda:modeMan(newValues4))
		autoButton4 = Button(master, text="AUTO", command=lambda:modeAuto(newValues4))
		pumpButton4 = Button(master, text="PUMP", command=lambda:controlPump(newValues4))
		solButton4 = Button(master, text="SOL", command=lambda:controlSol(newValues4))
		pumpOffButton4 = Button(master, text="OFF", command=lambda:pumpOff(newValues4))
		pumpOnButton4 = Button(master, text="ON", command=lambda:pumpOn(newValues4))
		solCloseButton4 = Button(master, text="CLOSE", command=lambda:solClose(newValues4))
		solOpenButton4 = Button(master, text="OPEN", command=lambda:solOpen(newValues4))
		w.pack()
		#PLC5 VALUES
		pumpOval5 =w.create_oval(1040,280,1080,320,fill="red",outline="red") 
		pumpRect5 = w.create_rectangle(1060,280,1090,295,fill="red",outline="red")
		valve5_1 = w.create_polygon(1150,400,1170,420,1190,400,fill="red",outline="black") #(1161,295,1179,400,
		valve5_2 = w.create_polygon(1150,440,1170,420,1190,440,fill="red",outline="black")	
		valve5_3 = w.create_rectangle(1170,419,1200,421,fill="red",outline="black")
		valve5_4 = w.create_rectangle(1200,405,1210,435,fill="red",outline="black")
		psi5 = w.create_text(1040,50,text=pressureString5)
		setpoint5 = w.create_text(1040,70,text=spString5)
		gain5 = w.create_text(1040,90,text=gainString5)
		reset5 = w.create_text(1040,110,text=resetString5)	
		rate5 = w.create_text(1040,130,text=rateString5)
		mode5 = w.create_text(1040,150,text=modeString5)
		control5 = w.create_text(1040,180,text=controlmodeString5)
		setpointEntry5 = Entry(master, width=5)
		gainEntry5 = Entry(master, width=5)
		resetEntry5 = Entry(master, width=5)
		rateEntry5 = Entry(master, width=5)
		offButton5 = Button(master, text="OFF", command=lambda:modeOff(newValues5))
		manButton5 = Button(master, text="MAN", command=lambda:modeMan(newValues5))
		autoButton5 = Button(master, text="AUTO", command=lambda:modeAuto(newValues5))
		pumpButton5 = Button(master, text="PUMP", command=lambda:controlPump(newValues5))
		solButton5 = Button(master, text="SOL", command=lambda:controlSol(newValues5))
		pumpOffButton5 = Button(master, text="OFF", command=lambda:pumpOff(newValues5))
		pumpOnButton5 = Button(master, text="ON", command=lambda:pumpOn(newValues5))
		solCloseButton5 = Button(master, text="CLOSE", command=lambda:solClose(newValues5))
		solOpenButton5 = Button(master, text="OPEN", command=lambda:solOpen(newValues5))
		w.pack()
		#high pressure images
		caution = w.create_polygon(1000,50,1100,50,1200,150,1200,250,1100,350,1000,350,900,250,900,150,1000,50, fill="white",outline = "white")
		highPressure1 = w.create_text(1050,150,text="",font = ("Times",24))
		highPressure2 = w.create_text(1050,200,text="",font = ("Times",24))

	guiObjects.w.pack()
	#static elements
	#xStart,yStart,xStop,yStart
	guiObjects.w.create_rectangle(150,300,200,320,fill="grey")			#pipe out of pump1
	guiObjects.w.create_rectangle(200,300,220,301,fill="black")			#thin black line above valve1
	guiObjects.w.create_rectangle(200,320,200,400,fill="black")			#thin black line down to valve1, left side
	guiObjects.w.create_rectangle(220,320,220,400,fill="black")			#thin black line down to valve1, right side
	guiObjects.w.create_rectangle(200,301,225,319,fill="grey",outline="grey")	#grey box above valve1
	guiObjects.w.create_rectangle(201,320,219,400,fill="grey",outline="grey")	#grey pipe internals down to valve1
	guiObjects.w.create_rectangle(200,440,220,550,fill="grey") 			#grey pipe out of valve1
	guiObjects.w.create_rectangle(385,290,465,310,fill="grey")			#pipe out of pump 2
	guiObjects.w.create_rectangle(465,310,465,410,fill="black")			#thin black line down to valve2, left side
	guiObjects.w.create_rectangle(465,290,485,290,fill="black")			#thin black line above valve2
	guiObjects.w.create_rectangle(466,309,484,410,fill="grey",outline="grey")	#grey pipe internals down to valve2
	guiObjects.w.create_rectangle(485,310,485,410,fill="black")			#thin black line down to valve2, right side
	guiObjects.w.create_rectangle(465,291,485,309,fill="grey",outline="grey")	#grey box into pump3
	guiObjects.w.create_rectangle(465,450,485,550,fill="grey")			#grey pipe out of valve2
	guiObjects.w.create_rectangle(620,285,680,300,fill="grey")			#pipe out of pump3 
	guiObjects.w.create_rectangle(680,285,700,285,fill="black")			#thin black line above valve3
	guiObjects.w.create_rectangle(680,300,680,400,fill="black")			#thin black line down to valve3, left side
	guiObjects.w.create_rectangle(681,300,699,400,fill="grey",outline="grey")	#grey pipe internals down to valve3
	guiObjects.w.create_rectangle(700,300,700,400,fill="black")			#thin black line down to valve3, right side
	guiObjects.w.create_rectangle(680,286,700,299,fill="grey",outline="grey")	#grey box into pump3 
	guiObjects.w.create_rectangle(680,440,700,550,fill="grey") 			#grey pipe out of valve3 
	guiObjects.w.create_rectangle(840,280,940,295,fill="grey")			#pipe out of pump4 
	guiObjects.w.create_rectangle(940,280,960,280,fill="black")			#thin black line above valve4
	guiObjects.w.create_rectangle(940,295,940,400,fill="black")			#thin black line down to valve4, left side
	guiObjects.w.create_rectangle(960,295,960,400,fill="black")			#thin black line down to valve4, right side
	guiObjects.w.create_rectangle(941,295,959,400,fill="grey",outline="grey")	#grey pipe internals down to valve4
	guiObjects.w.create_rectangle(940,281,960,294,fill="grey",outline="grey")	#grey box above valve4
	guiObjects.w.create_rectangle(940,440,960,550,fill="grey") 			#grey pipe out of valve4 
	guiObjects.w.create_rectangle(1090,280,1160,295,fill="grey")			#pipe out of pump5 
	guiObjects.w.create_rectangle(1160,280,1180,280,fill="black")			#thin black line above valve5
	guiObjects.w.create_rectangle(1160,295,1160,400,fill="black")			#thin black line down to valve5, left side
	guiObjects.w.create_rectangle(1180,280,1180,400,fill="black")			#thin black line down to valve5, right side
	guiObjects.w.create_rectangle(1160,281,1180,294,fill="grey",outline="grey")	#grey box above valve5
	guiObjects.w.create_rectangle(1161,295,1179,400,fill="grey",outline="grey")	#grey pipe internals down to valve5
	guiObjects.w.create_rectangle(1160,440,1180,550,fill="grey") 			#grey pipe out of valve5 
	guiObjects.w.create_text(105,310,text="gas")
	guiObjects.w.create_text(105,320,text="pump")
	guiObjects.w.create_text(210,405,text="valve")  
	guiObjects.w.create_text(345,300,text="gas")	
	guiObjects.w.create_text(345,310,text="pump2")
	guiObjects.w.create_text(475,415,text="valve2")
	guiObjects.w.create_text(595,300,text="gas")	
	guiObjects.w.create_text(595,310,text="pump3")
	guiObjects.w.create_text(690,405,text="valve3")
	guiObjects.w.create_text(810,290,text="gas")		
	guiObjects.w.create_text(810,300,text="pump4")
	guiObjects.w.create_text(950,405,text="valve4")
	guiObjects.w.create_text(1060,290,text="gas")		
	guiObjects.w.create_text(1060,300,text="pump5")	
	guiObjects.w.create_text(1170,405,text="valve5")	
	guiObjects.w.create_text(30,50,text="PSI:")
	guiObjects.w.create_text(30,70,text="Setpoint:")
	guiObjects.w.create_text(30,90,text="Gain:")
	guiObjects.w.create_text(30,110,text="Reset:")
	guiObjects.w.create_text(30,130,text="Rate:")
	guiObjects.w.create_text(40,150,text="SystemMode")
	guiObjects.w.create_text(40,180,text="ControlMode")
	guiObjects.w.create_text(40,210,text="Pump")
	guiObjects.w.create_text(40,240,text="Solenoid")
	guiObjects.w.pack()	
	#PLC1 Buttons
	guiObjects.w.create_window(120, 60, anchor=NW, window=guiObjects.setpointEntry)
	guiObjects.w.create_window(120, 80, anchor=NW, window=guiObjects.gainEntry)
	guiObjects.w.create_window(120, 100, anchor=NW, window=guiObjects.resetEntry)
	guiObjects.w.create_window(120, 120, anchor=NW, window=guiObjects.rateEntry)
	guiObjects.w.create_window(120, 140, anchor=NW, window=guiObjects.offButton)
	guiObjects.w.create_window(170, 140, anchor=NW, window=guiObjects.manButton)
	guiObjects.w.create_window(225, 140, anchor=NW, window=guiObjects.autoButton)
	guiObjects.w.create_window(120, 170, anchor=NW, window=guiObjects.pumpButton)
	guiObjects.w.create_window(170, 170, anchor=NW, window=guiObjects.solButton)
	guiObjects.w.create_window(120, 200, anchor=NW, window=guiObjects.pumpOffButton)
	guiObjects.w.create_window(170, 200, anchor=NW, window=guiObjects.pumpOnButton)
	guiObjects.w.create_window(120, 230, anchor=NW, window=guiObjects.solCloseButton)
	guiObjects.w.create_window(180, 230, anchor=NW, window=guiObjects.solOpenButton)
	guiObjects.w.pack()
	#PLC2 Buttons	
	guiObjects.w.create_window(340, 60, anchor=NW, window=guiObjects.setpointEntry2)
	guiObjects.w.create_window(340, 80, anchor=NW, window=guiObjects.gainEntry2)
	guiObjects.w.create_window(340, 100, anchor=NW, window=guiObjects.resetEntry2)
	guiObjects.w.create_window(340, 120, anchor=NW, window=guiObjects.rateEntry2)
	guiObjects.w.create_window(340, 140, anchor=NW, window=guiObjects.offButton2)
	guiObjects.w.create_window(390, 140, anchor=NW, window=guiObjects.manButton2)
	guiObjects.w.create_window(445, 140, anchor=NW, window=guiObjects.autoButton2)
	guiObjects.w.create_window(340, 170, anchor=NW, window=guiObjects.pumpButton2)
	guiObjects.w.create_window(390, 170, anchor=NW, window=guiObjects.solButton2)
	guiObjects.w.create_window(340, 200, anchor=NW, window=guiObjects.pumpOffButton2)
	guiObjects.w.create_window(390, 200, anchor=NW, window=guiObjects.pumpOnButton2)
	guiObjects.w.create_window(340, 230, anchor=NW, window=guiObjects.solCloseButton2)
	guiObjects.w.create_window(400, 230, anchor=NW, window=guiObjects.solOpenButton2)
	guiObjects.w.pack()
	#PLC3 Buttons
	guiObjects.w.create_window(590, 60, anchor=NW, window=guiObjects.setpointEntry3)
	guiObjects.w.create_window(590, 80, anchor=NW, window=guiObjects.gainEntry3)
	guiObjects.w.create_window(590, 100, anchor=NW, window=guiObjects.resetEntry3)
	guiObjects.w.create_window(590, 120, anchor=NW, window=guiObjects.rateEntry3)
	guiObjects.w.create_window(590, 140, anchor=NW, window=guiObjects.offButton3)
	guiObjects.w.create_window(640, 140, anchor=NW, window=guiObjects.manButton3)
	guiObjects.w.create_window(695, 140, anchor=NW, window=guiObjects.autoButton3)
	guiObjects.w.create_window(590, 170, anchor=NW, window=guiObjects.pumpButton3)
	guiObjects.w.create_window(640, 170, anchor=NW, window=guiObjects.solButton3)
	guiObjects.w.create_window(590, 200, anchor=NW, window=guiObjects.pumpOffButton3)
	guiObjects.w.create_window(640, 200, anchor=NW, window=guiObjects.pumpOnButton3)
	guiObjects.w.create_window(590, 230, anchor=NW, window=guiObjects.solCloseButton3)
	guiObjects.w.create_window(650, 230, anchor=NW, window=guiObjects.solOpenButton3)
	guiObjects.w.pack()
	#PLC4 Buttons
	guiObjects.w.create_window(810, 60, anchor=NW, window=guiObjects.setpointEntry4)
	guiObjects.w.create_window(810, 80, anchor=NW, window=guiObjects.gainEntry4)
	guiObjects.w.create_window(810, 100, anchor=NW, window=guiObjects.resetEntry4)
	guiObjects.w.create_window(810, 120, anchor=NW, window=guiObjects.rateEntry4)
	guiObjects.w.create_window(810, 140, anchor=NW, window=guiObjects.offButton4)
	guiObjects.w.create_window(860, 140, anchor=NW, window=guiObjects.manButton4)
	guiObjects.w.create_window(915, 140, anchor=NW, window=guiObjects.autoButton4)
	guiObjects.w.create_window(810, 170, anchor=NW, window=guiObjects.pumpButton4)
	guiObjects.w.create_window(860, 170, anchor=NW, window=guiObjects.solButton4)
	guiObjects.w.create_window(810, 200, anchor=NW, window=guiObjects.pumpOffButton4)
	guiObjects.w.create_window(860, 200, anchor=NW, window=guiObjects.pumpOnButton4)
	guiObjects.w.create_window(810, 230, anchor=NW, window=guiObjects.solCloseButton4)
	guiObjects.w.create_window(870, 230, anchor=NW, window=guiObjects.solOpenButton4)
	#PLC5 Buttons
	guiObjects.w.create_window(1060, 60, anchor=NW, window=guiObjects.setpointEntry5)
	guiObjects.w.create_window(1060, 80, anchor=NW, window=guiObjects.gainEntry5)
	guiObjects.w.create_window(1060, 100, anchor=NW, window=guiObjects.resetEntry5)
	guiObjects.w.create_window(1060, 120, anchor=NW, window=guiObjects.rateEntry5)
	guiObjects.w.create_window(1060, 140, anchor=NW, window=guiObjects.offButton5)
	guiObjects.w.create_window(1110, 140, anchor=NW, window=guiObjects.manButton5)
	guiObjects.w.create_window(1165, 140, anchor=NW, window=guiObjects.autoButton5)
	guiObjects.w.create_window(1060, 170, anchor=NW, window=guiObjects.pumpButton5)
	guiObjects.w.create_window(1110, 170, anchor=NW, window=guiObjects.solButton5)
	guiObjects.w.create_window(1060, 200, anchor=NW, window=guiObjects.pumpOffButton5)
	guiObjects.w.create_window(1110, 200, anchor=NW, window=guiObjects.pumpOnButton5)
	guiObjects.w.create_window(1060, 230, anchor=NW, window=guiObjects.solCloseButton5)
	guiObjects.w.create_window(1120, 230, anchor=NW, window=guiObjects.solOpenButton5)
	guiObjects.w.pack()
	
	return guiObjects

def newValuesInit(values):
#a function to initialize the values of the newValues class, used for storing new values from the GUI
	class newValues:
		setpoint = float(values.PIDSetpoint[0])
		gain = float(values.PIDGain[0])
		reset = float(values.PIDResetRate[0])
		rate = float(values.PIDRate[0])
		mode = float(values.MstrWSystemMode)
		control = float(values.MstrWControlPumpSol)
		pump = float(values.PumpRunCmd)
		solenoid = float(values.SolOpenCmd)
	return newValues

def modbusRead(master):
#this function reads in all my MODBUS registers and coils, stores them in a class called "Variables".It returns "Variables"

	#unitID, functionCode,StartingRegister,#ofRegisters
	coils1 = master.execute(4, cst.READ_COILS, 5, 2)
	coils2 = master.execute(4, cst.READ_COILS, 100, 9)    
	regs1 = master.execute(4, cst.READ_HOLDING_REGISTERS, 43000, 8)
	regs2 = master.execute(4, cst.READ_HOLDING_REGISTERS, 43050,17)
	regs3 = master.execute(4, cst.READ_HOLDING_REGISTERS,44000,34)

	class Values:
		PumpRunCmd = coils1[0]
		SolOpenCmd = coils1[1]
		ControlPumpSol = coils2[0]
		SystemInMAN = coils2[1]
		SystemInAUTO = coils2[2]
		MANPumpRunCmd = coils2[3]
		MANSolOpenCmd = coils2[4]
		PIDIncrease = coils2[5]
		PIDDecrease = coils2[6]
		AUTOPumpRunCmd = coils2[7]
		AUTOSolOpenCmd = coils2[8]
		MstrRDigIn = regs1[1]
 		MstrRPressureInRaw = regs1[2]
		MstrRAnalogIn1 = regs1[3]
		MstrRAnalogIn2 = regs1[4]
	 	MstrRAnalogIn3 = regs1[5]
	 	MstrRAnalogIn4 = regs1[6]
		MstrRPressureScaled = regs1[7]
		MstrWControlPumpSol = regs2[0]
		MstrWSystemMode = regs2[1] 
		MstrWMANPumpCmd = regs2[2]
		MstrWMANSolCmd = regs2[3]
		MstrWNothing1 = regs2[4]
		MstrWNothing2 = regs2[5]
		MstrWPIDSetpoint = unpack('f',pack('<HH',regs2[7],regs2[6]))
		MstrWPIDGain = unpack('f',pack('<HH',regs2[9],regs2[8]))
		MstrWPIDResetRate = unpack('f',pack('<HH',regs2[11],regs2[10]))
		MstrWPIDRate = unpack('f',pack('<HH',regs2[13],regs2[12]))
		MstrWPIDDeadband = unpack('f',pack('<HH',regs2[14],regs2[13]))
		MstrWPIDCycleTime = unpack('f',pack('<HH',regs2[16],regs2[15]))	
		PIDPressureScaled = unpack('f',pack('<HH',regs3[1],regs3[0]))
		PIDSetpoint = unpack('f',pack('<HH',regs3[3],regs3[2]))
		PIDGain = unpack('f',pack('<HH',regs3[5],regs3[4]))
		PIDResetRate = unpack('f',pack('<HH',regs3[7],regs3[6]))
		PIDRate = unpack('f',pack('<HH',regs3[9],regs3[8]))
		PIDDeadband = unpack('f',pack('<HH',regs3[11],regs3[10]))
		dPIDFullPercent = unpack('f',pack('<HH',regs3[13],regs3[12]))
		PIDZeroPercent = unpack('f',pack('<HH',regs3[15],regs3[14]))
		PIDCycleTime = unpack('f',pack('<HH',regs3[17],regs3[16]))
		PIDManualModeOutput = unpack('f',pack('<HH',regs3[19],regs3[18]))
		MotorOutputEnabled = unpack('f',pack('<HH',regs3[21],regs3[20]))
		PIDOutputPercent = unpack('f',pack('<HH',regs3[23],regs3[22]))
		PIDOldProcessValue = unpack('f',pack('<HH',regs3[25],regs3[24]))
		PIDOlderProcessValue = unpack('f',pack('<HH',regs3[27],regs3[26]))
		PIDOldErrorValue = unpack('f',pack('<HH',regs3[29],regs3[28]))
		PIDLastScanTime = unpack('f',pack('<HH',regs3[31],regs3[30]))
		PIDOnTime = unpack('f',pack('<HH',regs3[33],regs3[32]))
	return Values

def modbusWrite(master,newValues,oldValues):
#this function does my MODBUS writing. It should only write PID setpoint, gain, reset, rate, system mode, control mode, pump, and solenoid	
#it converts floats into two 16bit hex values for MODBUS transmission
#it also checks and only writes when the user changes the value
			
	newSP = newValues.setpoint	
	i1, i2 = unpack('<HH',pack('f',newSP))	
	if(newValues.setpoint != oldValues.setpoint):
		master.execute(4, cst.WRITE_MULTIPLE_REGISTERS, 43056, output_value=(i2,i1)) 
		oldValues.setpoint = newValues.setpoint
	
	newGain = newValues.gain
	i1, i2 = unpack('<HH',pack('f',newGain))
	if(newValues.gain != oldValues.gain):
		master.execute(4, cst.WRITE_MULTIPLE_REGISTERS, 43058, output_value=(i2,i1)) 
		oldValues.gain = newValues.gain

	newReset = newValues.reset
	i1, i2 = unpack('<HH',pack('f',newReset))
	if(newValues.reset != oldValues.reset):
		master.execute(4, cst.WRITE_MULTIPLE_REGISTERS, 43060, output_value=(i2,i1)) 
		oldValues.reset = newValues.reset

	newRate = newValues.rate
	i1, i2 = unpack('<HH',pack('f',newRate))
	if(newValues.rate != oldValues.rate):
		master.execute(4, cst.WRITE_MULTIPLE_REGISTERS, 43062, output_value=(i2,i1)) 
		oldValues.rate = newValues.rate		
			
	newControl = newValues.control
	newMode = newValues.mode	
	if(newValues.control != oldValues.control or newValues.mode != oldValues.mode):
		master.execute(4, cst.WRITE_MULTIPLE_REGISTERS, 43050, output_value=(newControl,newMode)) 
		oldValues.control = newValues.control
		oldValues.mode = newValues.mode	

	newPump = newValues.pump
	newSol = newValues.solenoid	
	if(newValues.pump != oldValues.pump or newValues.solenoid != oldValues.solenoid):
		master.execute(4, cst.WRITE_MULTIPLE_REGISTERS, 43052, output_value=(newPump,newSol)) 
		oldValues.pump = newValues.pump
		oldValues.solenoid = newValues.solenoid

def redrawGui(valuesArray,guiObjects):
#this function redraws the variable elements of the gui
	
	#temp variables so I don't have to refer to the indicie	
	values = valuesArray[0]
	values2 = valuesArray[1]
	values3 = valuesArray[2]
	values4 = valuesArray[3]
	values5 = valuesArray[4]

	#turning reset, and rate into rounded floats and turning the mode and control values into strings
	round1 = round(float(values.PIDResetRate[0]),2)
	resetString = float(round1)
	round2 = round(float(values.PIDRate[0]),2)
	rateString = float(round2)
	round3 = round(float(values.PIDPressureScaled[0]),2)
	pressureString = float(round3)
	round4 = round(float(values.PIDSetpoint[0]),2)
	spString = float(round4)
	round5 = round(float(values.PIDGain[0]),2)
	gainString = float(round5)

	if(values.MstrWSystemMode == 0):
		modeString = "OFF"
	elif(values.MstrWSystemMode == 1):
		modeString = "MAN"
	elif(values.MstrWSystemMode == 2):
		modeString = "AUTO"
	else:
		modeString = "?"
	if(values.MstrWControlPumpSol == 0):
		controlmodeString = "PUMP"
	elif(values.MstrWControlPumpSol == 1):
		controlmodeString = "SOL"
	else:
		controlmodeString = "?"
	
	#Second set for plc#2
	#turning reset, and rate into rounded floats and turning the mode and control values into strings
	resetRound2 = round(float(values2.PIDResetRate[0]),2)
	resetString2 = float(resetRound2)
	rateRound2 = round(float(values2.PIDRate[0]),2)
	rateString2 = float(rateRound2)
	pressureRound2 = round(float(values2.PIDPressureScaled[0]),2)
	pressureString2 = float(pressureRound2)
	spRound2 = round(float(values2.PIDSetpoint[0]),2)
	spString2 = float(spRound2)
	gainRound2 = round(float(values2.PIDGain[0]),2)
	gainString2 = float(gainRound2)
	if(values2.MstrWSystemMode == 0):
		modeString2 = "OFF"
	elif(values2.MstrWSystemMode == 1):
		modeString2 = "MAN"
	elif(values2.MstrWSystemMode == 2):
		modeString2 = "AUTO"
	else:
		modeString2 = "?"
	if(values2.MstrWControlPumpSol == 0):
		controlmodeString2 = "PUMP"
	elif(values2.MstrWControlPumpSol == 1):
		controlmodeString2 = "SOL"
	else:
		controlmodeString2 = "?"

	#third set for plc#3
	#turning reset, and rate into rounded floats and turning the mode and control values into strings
	resetRound3 = round(float(values3.PIDResetRate[0]),2)
	resetString3 = float(resetRound3)
	rateRound3 = round(float(values3.PIDRate[0]),2)
	rateString3 = float(rateRound3)
	pressureRound3 = round(float(values3.PIDPressureScaled[0]),2)
	pressureString3 = float(pressureRound3)
	spRound3 = round(float(values3.PIDSetpoint[0]),2)
	spString3 = float(spRound3)
	gainRound3 = round(float(values3.PIDGain[0]),2)
	gainString3 = float(gainRound3)
	if(values3.MstrWSystemMode == 0):
		modeString3 = "OFF"
	elif(values3.MstrWSystemMode == 1):
		modeString3 = "MAN"
	elif(values3.MstrWSystemMode == 2):
		modeString3 = "AUTO"
	else:
		modeString3 = "?"
	if(values3.MstrWControlPumpSol == 0):
		controlmodeString3 = "PUMP"
	elif(values3.MstrWControlPumpSol == 1):
		controlmodeString3 = "SOL"
	else:
		controlmodeString3 = "?"

	#Fourth set for plc#4
	#turning reset, and rate into rounded floats and turning the mode and control values into strings
	resetRound4 = round(float(values4.PIDResetRate[0]),2)
	resetString4 = float(resetRound4)
	rateRound4 = round(float(values4.PIDRate[0]),2)
	rateString4 = float(rateRound4)
	pressureRound4 = round(float(values4.PIDPressureScaled[0]),2)
	pressureString4 = float(pressureRound4)
	spRound4 = round(float(values4.PIDSetpoint[0]),2)
	spString4 = float(spRound4)
	gainRound4 = round(float(values4.PIDGain[0]),2)
	gainString4 = float(gainRound4)

	if(values4.MstrWSystemMode == 0):
		modeString4 = "OFF"
	elif(values4.MstrWSystemMode == 1):
		modeString4 = "MAN"
	elif(values4.MstrWSystemMode == 2):
		modeString4 = "AUTO"
	else:
		modeString4 = "?"
	if(values4.MstrWControlPumpSol == 0):
		controlmodeString4 = "PUMP"
	elif(values4.MstrWControlPumpSol == 1):
		controlmodeString4 = "SOL"
	else:
		controlmodeString4 = "?"

	#Fourth set for plc#5
	#turning reset, and rate into rounded floats and turning the mode and control values into strings
	resetRound5 = round(float(values5.PIDResetRate[0]),2)
	resetString5 = float(resetRound5)
	rateRound5 = round(float(values5.PIDRate[0]),2)
	rateString5 = float(rateRound5)
	pressureRound5 = round(float(values5.PIDPressureScaled[0]),2)
	pressureString5 = float(pressureRound5)
	spRound5 = round(float(values5.PIDSetpoint[0]),2)
	spString5 = float(spRound5)
	gainRound5 = round(float(values5.PIDGain[0]),2)
	gainString5 = float(gainRound5)

	if(values5.MstrWSystemMode == 0):
		modeString5 = "OFF"
	elif(values5.MstrWSystemMode == 1):
		modeString5 = "MAN"
	elif(values5.MstrWSystemMode == 2):
		modeString5 = "AUTO"
	else:
		modeString5 = "?"
	if(values5.MstrWControlPumpSol == 0):
		controlmodeString5 = "PUMP"
	elif(values5.MstrWControlPumpSol == 1):
		controlmodeString5 = "SOL"
	else:
		controlmodeString5 = "?"

	#deleting the old objects
	guiObjects.w.delete(guiObjects.psi)
	guiObjects.w.delete(guiObjects.setpoint)
	guiObjects.w.delete(guiObjects.gain)
	guiObjects.w.delete(guiObjects.reset)
	guiObjects.w.delete(guiObjects.rate)
	guiObjects.w.delete(guiObjects.mode)
	guiObjects.w.delete(guiObjects.control)
	guiObjects.w.delete(guiObjects.pumpOval)
	guiObjects.w.delete(guiObjects.pumpRect)
	guiObjects.w.delete(guiObjects.valve1)
	guiObjects.w.delete(guiObjects.valve2)
	guiObjects.w.delete(guiObjects.valve3)
	guiObjects.w.delete(guiObjects.valve4)
	guiObjects.w.delete(guiObjects.highPressure1)
	guiObjects.w.delete(guiObjects.highPressure2)
	guiObjects.w.delete(guiObjects.caution)
	#values for PLC2
	guiObjects.w.delete(guiObjects.psi2)
	guiObjects.w.delete(guiObjects.setpoint2)
	guiObjects.w.delete(guiObjects.gain2)
	guiObjects.w.delete(guiObjects.reset2)
	guiObjects.w.delete(guiObjects.rate2)
	guiObjects.w.delete(guiObjects.mode2)
	guiObjects.w.delete(guiObjects.control2)
	guiObjects.w.delete(guiObjects.pumpOval2)
	guiObjects.w.delete(guiObjects.pumpRect2)
	guiObjects.w.delete(guiObjects.valve2_1)
	guiObjects.w.delete(guiObjects.valve2_2)
	guiObjects.w.delete(guiObjects.valve2_3)
	guiObjects.w.delete(guiObjects.valve2_4)
	#values for PLC3
	guiObjects.w.delete(guiObjects.psi3)
	guiObjects.w.delete(guiObjects.setpoint3)
	guiObjects.w.delete(guiObjects.gain3)
	guiObjects.w.delete(guiObjects.reset3)
	guiObjects.w.delete(guiObjects.rate3)
	guiObjects.w.delete(guiObjects.mode3)
	guiObjects.w.delete(guiObjects.control3)
	guiObjects.w.delete(guiObjects.pumpOval3)
	guiObjects.w.delete(guiObjects.pumpRect3)
	guiObjects.w.delete(guiObjects.valve3_1)
	guiObjects.w.delete(guiObjects.valve3_2)
	guiObjects.w.delete(guiObjects.valve3_3)
	guiObjects.w.delete(guiObjects.valve3_4)
	#values for PLC4
	guiObjects.w.delete(guiObjects.psi4)
	guiObjects.w.delete(guiObjects.setpoint4)
	guiObjects.w.delete(guiObjects.gain4)
	guiObjects.w.delete(guiObjects.reset4)
	guiObjects.w.delete(guiObjects.rate4)
	guiObjects.w.delete(guiObjects.mode4)
	guiObjects.w.delete(guiObjects.control4)
	guiObjects.w.delete(guiObjects.pumpOval4)
	guiObjects.w.delete(guiObjects.pumpRect4)
	guiObjects.w.delete(guiObjects.valve4_1)
	guiObjects.w.delete(guiObjects.valve4_2)
	guiObjects.w.delete(guiObjects.valve4_3)
	guiObjects.w.delete(guiObjects.valve4_4)
	#values for PLC5
	guiObjects.w.delete(guiObjects.psi5)
	guiObjects.w.delete(guiObjects.setpoint5)
	guiObjects.w.delete(guiObjects.gain5)
	guiObjects.w.delete(guiObjects.reset5)
	guiObjects.w.delete(guiObjects.rate5)
	guiObjects.w.delete(guiObjects.mode5)
	guiObjects.w.delete(guiObjects.control5)
	guiObjects.w.delete(guiObjects.pumpOval5)
	guiObjects.w.delete(guiObjects.pumpRect5)
	guiObjects.w.delete(guiObjects.valve5_1)
	guiObjects.w.delete(guiObjects.valve5_2)
	guiObjects.w.delete(guiObjects.valve5_3)
	guiObjects.w.delete(guiObjects.valve5_4)
	
	#creating new objects to draw
	guiObjects.psi = guiObjects.w.create_text(100,50,text=pressureString)
	guiObjects.setpoint = guiObjects.w.create_text(100,70,text=spString)
	guiObjects.gain = guiObjects.w.create_text(100,90,text=gainString)
	guiObjects.reset = guiObjects.w.create_text(100,110,text=resetString)
	guiObjects.rate = guiObjects.w.create_text(100,130,text=rateString)
	guiObjects.mode = guiObjects.w.create_text(100,150,text=modeString)
	guiObjects.control = guiObjects.w.create_text(100,180,text=controlmodeString)
	#Values for PLC2
	guiObjects.psi2 = guiObjects.w.create_text(320,50,text=pressureString2)
	guiObjects.setpoint2 = guiObjects.w.create_text(320,70,text=spString2)
	guiObjects.gain2 = guiObjects.w.create_text(320,90,text=gainString2)
	guiObjects.reset2 = guiObjects.w.create_text(320,110,text=resetString2)	
	guiObjects.rate2 = guiObjects.w.create_text(320,130,text=rateString2)
	guiObjects.mode2 = guiObjects.w.create_text(320,150,text=modeString2)
	guiObjects.control2 = guiObjects.w.create_text(320,180,text=controlmodeString2)
	#Values for PLC3
	guiObjects.psi3 = guiObjects.w.create_text(570,50,text=pressureString3)
	guiObjects.setpoint3 = guiObjects.w.create_text(570,70,text=spString3)
	guiObjects.gain3 = guiObjects.w.create_text(570,90,text=gainString3)
	guiObjects.reset3 = guiObjects.w.create_text(570,110,text=resetString3)
	guiObjects.rate3 = guiObjects.w.create_text(570,130,text=rateString3)
	guiObjects.mode3 = guiObjects.w.create_text(570,150,text=modeString3)
	guiObjects.control3 = guiObjects.w.create_text(570,180,text=controlmodeString3)
	#Values for PLC4
	guiObjects.psi4 = guiObjects.w.create_text(790,50,text=pressureString4)
	guiObjects.setpoint4 = guiObjects.w.create_text(790,70,text=spString4)
	guiObjects.gain4 = guiObjects.w.create_text(790,90,text=gainString4)
	guiObjects.reset4 = guiObjects.w.create_text(790,110,text=resetString4)	
	guiObjects.rate4 = guiObjects.w.create_text(790,130,text=rateString4)
	guiObjects.mode4 = guiObjects.w.create_text(790,150,text=modeString4)
	guiObjects.control4 = guiObjects.w.create_text(790,180,text=controlmodeString4)
	#Values for PLC5
	guiObjects.psi5 = guiObjects.w.create_text(1040,50,text=pressureString5)
	guiObjects.setpoint5 = guiObjects.w.create_text(1040,70,text=spString5)
	guiObjects.gain5 = guiObjects.w.create_text(1040,90,text=gainString5)
	guiObjects.reset5 = guiObjects.w.create_text(1040,110,text=resetString5)	
	guiObjects.rate5 = guiObjects.w.create_text(1040,130,text=rateString5)
	guiObjects.mode5 = guiObjects.w.create_text(1040,150,text=modeString5)
	guiObjects.control5 = guiObjects.w.create_text(1040,180,text=controlmodeString5)

	#checking if the pump is on or off. The color of the pump changes, depending on state
	if(values.PumpRunCmd == 1):
		guiObjects.pumpOval =guiObjects.w.create_oval(85,295, 135, 345, fill="green", outline = "green")
		guiObjects.pumpRect = guiObjects.w.create_rectangle(125,300,150,320, fill="green",outline = "green")
	elif(values.PumpRunCmd == 0):
		guiObjects.pumpOval =guiObjects.w.create_oval(85,295, 135, 345, fill="red", outline = "red")
		guiObjects.pumpRect = guiObjects.w.create_rectangle(125,300,150,320, fill="red",outline = "red")
	else:
		guiObjects.pumpOval =guiObjects.w.create_oval(85,295, 135, 345, fill="blue", outline = "blue")
		guiObjects.pumpRect = guiObjects.w.create_rectangle(125,300,150,320, fill="blue",outline = "blue")

	#PUMP#2	
	#checking if the pump is on or off. The color of the pump changes, depending on state
	if(values2.PumpRunCmd == 1):
		guiObjects.pumpOval2 =guiObjects.w.create_oval(320,290,370,330,fill="green",outline="green")
		guiObjects.pumpRect2 = guiObjects.w.create_rectangle(350,290,385,310,fill="green",outline="green")
	elif(values2.PumpRunCmd == 0):
		guiObjects.pumpOval2 =guiObjects.w.create_oval(320,290,370,330,fill="red",outline="red")
		guiObjects.pumpRect2 = guiObjects.w.create_rectangle(350,290,385,310,fill="red",outline="red")
	else:
		guiObjects.pumpOval2 =guiObjects.w.create_oval(320,290,370,330,fill="blue",outline="blue")
		guiObjects.pumpRect2 = guiObjects.w.create_rectangle(350,290,385,310,fill="blue",outline="blue")

	#checking if the valve is open or closed. The color of the valve changes, depending on state

	if(values.SolOpenCmd == 1):
		guiObjects.valve1 = guiObjects.w.create_polygon(190,400,210,420,230,400,fill="green",outline="black")
		guiObjects.valve2 = guiObjects.w.create_polygon(190,440,210,420,230,440,fill="green",outline = "black")
		guiObjects.valve3 = guiObjects.w.create_rectangle(210,419,240,421,fill="green",outline="black")
		guiObjects.valve4 = guiObjects.w.create_rectangle(240,405,250,435,fill="green",outline="black")
	elif(values.SolOpenCmd == 0):
		guiObjects.valve1 = guiObjects.w.create_polygon(190,400,210,420,230,400,fill="red",outline="black")
		guiObjects.valve2 = guiObjects.w.create_polygon(190,440,210,420,230,440,fill="red",outline="black")
		guiObjects.valve3 = guiObjects.w.create_rectangle(210,419,240,421,fill="red",outline="black")
		guiObjects.valve4 = guiObjects.w.create_rectangle(240,405,250,435,fill="red",outline = "black")
	else:
		guiObjects.valve1 = guiObjects.w.create_polygon(190,400,210,420,230,400,fill="blue",outline="black")
		guiObjects.valve2 = guiObjects.w.create_polygon(190,440,210,420,230,440,fill="blue",outline="black")
		guiObjects.valve3 = guiObjects.w.create_rectangle(210,419,240,421,fill="blue",outline="black")
		guiObjects.valve4 = guiObjects.w.create_rectangle(240,405,250,435,fill="blue",outline="black")
	if(round3 > MAX_PRESSURE):
		guiObjects.caution = guiObjects.w.create_polygon(1000,50,1100,50,1200,150,1200,250,1100,350,1000,350,900,250,900,150,1000,50, fill="red",outline = "black")
		guiObjects.highPressure1 = guiObjects.w.create_text(1050,150,text="High",font = ("Times",24))
		guiObjects.highPressure2 = guiObjects.w.create_text(1050,200,text="Pressure",font = ("Times",24))
	
	#SOLENOID VALVE 2	
	#checking if the valve is open or closed. The color of the valve changes, depending on state
	if(values2.SolOpenCmd == 1):
		guiObjects.valve2_1 = guiObjects.w.create_polygon(455,410,475,430,495,410,fill="green",outline="black")
		guiObjects.valve2_2 = guiObjects.w.create_polygon(455,450,475,430,495,450,fill="green",outline="black")
		guiObjects.valve2_3 = guiObjects.w.create_rectangle(475,429,500,431,fill="green",outline = "black")
		guiObjects.valve2_4 = guiObjects.w.create_rectangle(500,415,510,445,fill="green",outline="black")
	elif(values2.SolOpenCmd == 0):
		guiObjects.valve2_1 = guiObjects.w.create_polygon(455,410,475,430,495,410,fill="red",outline="black")
		guiObjects.valve2_2 = guiObjects.w.create_polygon(455,450,475,430,495,450,fill="red",outline="black")
		guiObjects.valve2_3 = guiObjects.w.create_rectangle(475,429,500,431,fill="red",outline="black")
		guiObjects.valve2_4 = guiObjects.w.create_rectangle(500,415,510,445,fill="red",outline="black")
	else:
		guiObjects.valve2_1 = guiObjects.w.create_polygon(455,410,475,430,495,410,fill="blue",outline="black")
		guiObjects.valve2_2 = guiObjects.w.create_polygon(455,450,475,430,495,450,fill="blue",outline="black")
		guiObjects.valve2_3 = guiObjects.w.create_rectangle(475,429,500,431,fill="blue",outline="black")
		guiObjects.valve2_4 = guiObjects.w.create_rectangle(500,415,510,445,fill="blue", outline="black")
	
	#PUMP#3	
	#checking if the pump is on or off. The color of the pump changes, depending on state
	if(values3.PumpRunCmd == 1):
		guiObjects.pumpOval3 =guiObjects.w.create_oval(570,285,610,325,fill="green",outline="green")
		guiObjects.pumpRect3 = guiObjects.w.create_rectangle(590,285,620,300,fill="green",outline="green")
	elif(values3.PumpRunCmd == 0):
		guiObjects.pumpOval3 =guiObjects.w.create_oval(570,285,610,325,fill="red",outline="red")
		guiObjects.pumpRect3 = guiObjects.w.create_rectangle(590,285,620,300,fill="red",outline="red")
	else:
		guiObjects.pumpOval3 =guiObjects.w.create_oval(570,285,610,325,fill="blue",outline="blue")
		guiObjects.pumpRect3 = guiObjects.w.create_rectangle(590,285,620,300,fill="blue",outline="blue")

	#SOLENOID VALVE 3	
	#checking if the valve is open or closed. The color of the valve changes, depending on state
	if(values3.SolOpenCmd == 1):
		guiObjects.valve3_1 = guiObjects.w.create_polygon(670,400,690,420,710,400,fill="green",outline="black")
		guiObjects.valve3_2 = guiObjects.w.create_polygon(670,440,690,420,710,440,fill="green",outline="black")
		guiObjects.valve3_3 = guiObjects.w.create_rectangle(690,419,720,421,fill="green",outline = "black")
		guiObjects.valve3_4 = guiObjects.w.create_rectangle(720,405,730,435,fill="green",outline="black")
	elif(values3.SolOpenCmd == 0):
		guiObjects.valve3_1 = guiObjects.w.create_polygon(670,400,690,420,710,400,fill="red",outline="black")
		guiObjects.valve3_2 = guiObjects.w.create_polygon(670,440,690,420,710,440,fill="red",outline="black")
		guiObjects.valve3_3 = guiObjects.w.create_rectangle(690,419,720,421,fill="red",outline="black")
		guiObjects.valve3_4 = guiObjects.w.create_rectangle(720,405,730,435,fill="red",outline="black")
	else:
		guiObjects.valve3_1 = guiObjects.w.create_polygon(670,400,690,420,710,400,fill="blue",outline="black")
		guiObjects.valve3_2 = guiObjects.w.create_polygon(670,440,690,420,710,440,fill="blue",outline="black")
		guiObjects.valve3_3 = guiObjects.w.create_rectangle(690,419,720,421,fill="blue",outline="black")
		guiObjects.valve3_4 = guiObjects.w.create_rectangle(720,405,730,435,fill="blue", outline="black")

	#PUMP#4	
	#checking if the pump is on or off. The color of the pump changes, depending on state
	if(values4.PumpRunCmd == 1):
		guiObjects.pumpOval4 =guiObjects.w.create_oval(790,280,830,320,fill="green",outline="green")
		guiObjects.pumpRect4 = guiObjects.w.create_rectangle(810,280,840,295,fill="green",outline="green")
	elif(values4.PumpRunCmd == 0):
		guiObjects.pumpOval4 =guiObjects.w.create_oval(790,280,830,320,fill="red",outline="red")
		guiObjects.pumpRect4 = guiObjects.w.create_rectangle(810,280,840,295,fill="red",outline="red")
	else:
		guiObjects.pumpOval4 =guiObjects.w.create_oval(790,280,830,320,fill="blue",outline="blue")
		guiObjects.pumpRect4 = guiObjects.w.create_rectangle(810,280,840,295,fill="blue",outline="blue")

	#SOLENOID VALVE 4	
	#checking if the valve is open or closed. The color of the valve changes, depending on state
	if(values4.SolOpenCmd == 1):
		guiObjects.valve4_1 = guiObjects.w.create_polygon(930,400,950,420,970,400,fill="green",outline="black")
		guiObjects.valve4_2 = guiObjects.w.create_polygon(930,440,950,420,970,440,fill="green",outline="black")
		guiObjects.valve4_3 = guiObjects.w.create_rectangle(950,419,980,421,fill="green",outline = "black")
		guiObjects.valve4_4 = guiObjects.w.create_rectangle(980,405,990,435,fill="green",outline="black")
	elif(values4.SolOpenCmd == 0):
		guiObjects.valve4_1 = guiObjects.w.create_polygon(930,400,950,420,970,400,fill="red",outline="black")
		guiObjects.valve4_2 = guiObjects.w.create_polygon(930,440,950,420,970,440,fill="red",outline="black")
		guiObjects.valve4_3 = guiObjects.w.create_rectangle(950,419,980,421,fill="red",outline="black")
		guiObjects.valve4_4 = guiObjects.w.create_rectangle(980,405,990,435,fill="red",outline="black")
	else:
		guiObjects.valve4_1 = guiObjects.w.create_polygon(930,400,950,420,970,400,fill="blue",outline="black")
		guiObjects.valve4_2 = guiObjects.w.create_polygon(930,440,950,420,970,440,fill="blue",outline="black")
		guiObjects.valve4_3 = guiObjects.w.create_rectangle(950,419,980,421,fill="blue",outline="black")
		guiObjects.valve4_4 = guiObjects.w.create_rectangle(980,405,990,435,fill="blue", outline="black")

	#PUMP#5	
	#checking if the pump is on or off. The color of the pump changes, depending on state
	if(values5.PumpRunCmd == 1):
		guiObjects.pumpOval5 =guiObjects.w.create_oval(1040,280,1080,320,fill="green",outline="green")
		guiObjects.pumpRect5 = guiObjects.w.create_rectangle(1060,280,1090,295,fill="green",outline="green")
	elif(values5.PumpRunCmd == 0):
		guiObjects.pumpOval5 =guiObjects.w.create_oval(1040,280,1080,320,fill="red",outline="red")
		guiObjects.pumpRect5 = guiObjects.w.create_rectangle(1060,280,1090,295,fill="red",outline="red")
	else:
		guiObjects.pumpOval5 =guiObjects.w.create_oval(1040,280,1080,320,fill="blue",outline="blue")
		guiObjects.pumpRect5 = guiObjects.w.create_rectangle(1060,280,1090,295,fill="blue",outline="blue")

	#SOLENOID VALVE 5	
	#checking if the valve is open or closed. The color of the valve changes, depending on state
	if(values5.SolOpenCmd == 1):
		guiObjects.valve5_1 = guiObjects.w.create_polygon(1150,400,1170,420,1190,400,fill="green",outline="black")
		guiObjects.valve5_2 = guiObjects.w.create_polygon(1150,440,1170,420,1190,440,fill="green",outline="black")
		guiObjects.valve5_3 = guiObjects.w.create_rectangle(1170,419,1200,421,fill="green",outline = "black")
		guiObjects.valve5_4 = guiObjects.w.create_rectangle(1200,405,1210,435,fill="green",outline="black")
	elif(values5.SolOpenCmd == 0):
		guiObjects.valve5_1 = guiObjects.w.create_polygon(1150,400,1170,420,1190,400,fill="red",outline="black")
		guiObjects.valve5_2 = guiObjects.w.create_polygon(1150,440,1170,420,1190,440,fill="red",outline="black")
		guiObjects.valve5_3 = guiObjects.w.create_rectangle(1170,419,1200,421,fill="red",outline="black")
		guiObjects.valve5_4 = guiObjects.w.create_rectangle(1200,405,1210,435,fill="red",outline="black")
	else:
		guiObjects.valve5_1 = guiObjects.w.create_polygon(1150,400,1170,420,1190,400,fill="blue",outline="black")
		guiObjects.valve5_2 = guiObjects.w.create_polygon(1150,440,1170,420,1190,440,fill="blue",outline="black")
		guiObjects.valve5_3 = guiObjects.w.create_rectangle(1170,419,1200,421,fill="blue",outline="black")
		guiObjects.valve5_4 = guiObjects.w.create_rectangle(1200,405,1210,435,fill="blue", outline="black")			

	#finally, redraw text on top of shapes and pack	
	guiObjects.w.create_text(105,310,text="gas")
	guiObjects.w.create_text(105,320,text="pump")
	guiObjects.w.create_text(210,405,text="valve")
	guiObjects.w.create_text(345,300,text="gas")	
	guiObjects.w.create_text(345,310,text="pump2")
	guiObjects.w.create_text(475,415,text="valve2")
	guiObjects.w.create_text(595,300,text="gas")	
	guiObjects.w.create_text(595,310,text="pump3")
	guiObjects.w.create_text(690,405,text="valve3")
	guiObjects.w.create_text(810,290,text="gas")		
	guiObjects.w.create_text(810,300,text="pump4")
	guiObjects.w.create_text(950,405,text="valve4")
	guiObjects.w.create_text(1060,290,text="gas")		
	guiObjects.w.create_text(1060,300,text="pump5")	
	guiObjects.w.create_text(1170,405,text="valve5")
	guiObjects.w.pack()

def modeOff(values):
#a setter function so the OFF button will turn the mode to OFF	
	values.mode = 0
		
def modeMan(values):
#a setter function so the MAN button will turn the mode to MAN		
	values.mode = 1	

def modeAuto(values):
#a setter function so the AUTO button will turn the mode to AUTO		
	values.mode = 2

def controlPump(values):
#a setter function so the PUMP button will turn the control mode to PUMP			
	values.control = 0

def controlSol(values):
#a setter function so the SOL button will turn the control mode to SOL		
	values.control = 1

def pumpOff(values):
# a setter function so the OFF button will turn the pump OFF in MAN mode
	values.pump = 0		

def pumpOn(values):
# a setter function so the OFF button will turn the pump OFF in MAN mode	
	values.pump = 1

def solClose(values):
# a setter function so the CLOSE button will close the solenoid in MAN mode	
	values.solenoid = 0	

def solOpen(values):
# a setter function so the OPEN button will open the solenoid in MAN mode
	values.solenoid = 1

def getNewValues(valuesArray,newValuesArray,guiObjects):
#a function for gettingsthe new values from the HMI. 
	
	values = valuesArray[0]
	values2 = valuesArray[1]
	values3 = valuesArray[2]
	values4 = valuesArray[3]
	values5 = valuesArray[4]
	newValues = newValuesArray[0]
	newValues2 = newValuesArray[1]
	newValues3 = newValuesArray[2]	
	newValues4 = newValuesArray[3]	
	newValues5 = newValuesArray[4]	
	
	#PLC1 Values. First, make sure the box isn't empty. Then make sure it isn't less than zero, and catch non integer exceptions. Either set it to the old value for error, or new one
	#PLC1 Setpoint
	temp = guiObjects.setpointEntry.get()
	if not temp:
		newValues.setpoint = float(values.PIDSetpoint[0])
	else:
		try:
			temp = float(temp)
			if (temp < 0):
				newValues.setpoint = float(values.PIDSetpoint[0])
			else:
				newValues.setpoint = temp
		except ValueError:
			newValues.setpoint = float(values.PIDSetpoint[0])
	#PLC1 Gain
	temp = guiObjects.gainEntry.get()
	if not temp:
		newValues.gain = float(values.PIDGain[0])
	else:
		try:
			temp = float(temp)
			if (temp < 0):
				newValues.gain = float(values.PIDGain[0])
			else:
				newValues.gain = temp
		except ValueError:	
			newValues.gain = float(values.PIDGain[0])
	#PLC1 Reset
	temp = guiObjects.resetEntry.get()
	if not temp:
		newValues.reset = float(values.PIDResetRate[0])
	else:
		try:
			temp = float(temp)
			if (temp < 0):
				newValues.reset = float(values.PIDResetRate[0])
			else:
				newValues.reset = temp
		except ValueError:
			newValues.reset = float(values.PIDResetRate[0])
	#PLC1 Rate	
	temp = guiObjects.rateEntry.get()
	if not temp:
		newValues.rate = float(values.PIDRate[0])
	else:
		try:
			temp = float(temp)
			if (temp < 0):
				newValues.rate = float(values.PIDRate[0])
			else:
				newValues.rate = temp
		except ValueError:
			newValues.rate = float(values.PIDRate[0])
	#PLC2 Values. First, make sure the box isn't empty. Then make sure it isn't less than zero, and catch non integer exceptions. Either set it to the old value for error, or new one
	#PLC2 Setpoint
	temp = guiObjects.setpointEntry2.get()
	if not temp:
		newValues2.setpoint = float(values2.PIDSetpoint[0])
	else:
		try:
			temp = float(temp)
			if (temp < 0):
				newValues2.setpoint = float(values2.PIDSetpoint[0])
			else:
				newValues2.setpoint = temp
		except ValueError:
			newValues2.setpoint = float(values2.PIDSetpoint[0])
	#PLC2 Gain	
	temp = guiObjects.gainEntry2.get()
	if not temp:
		newValues2.gain = float(values2.PIDGain[0])
	else:
		try:
			temp = float(temp)
			if (temp < 0):
				newValues2.gain = float(values2.PIDGain[0])
			else:
				newValues2.gain = temp
		except ValueError:	
			newValues2.gain = float(values2.PIDGain[0])
	#PLC2 Reset
	temp = guiObjects.resetEntry2.get()
	if not temp:
		newValues2.reset = float(values2.PIDResetRate[0])
	else:
		try:
			temp = float(temp)
			if (temp < 0):
				newValues2.reset = float(values2.PIDResetRate[0])
			else:
				newValues2.reset = temp
		except ValueError:
			newValues2.reset = float(values2.PIDResetRate[0])
	#PLC2 Rate
	temp = guiObjects.rateEntry2.get()
	if not temp:
		newValues2.rate = float(values2.PIDRate[0])
	else:
		try:
			temp = float(temp)
			if (temp < 0):
				newValues2.rate = float(values2.PIDRate[0])
			else:
				newValues2.rate = temp
		except ValueError:	
			newValues2.rate = float(values2.PIDRate[0])
	#PLC3 Values. First, make sure the box isn't empty. Then make sure it isn't less than zero, and catch non integer exceptions. Either set it to the old value for error, or new one
	#PLC3 Setpoint
	temp = guiObjects.setpointEntry3.get()
	if not temp:
		newValues3.setpoint = float(values3.PIDSetpoint[0])
	else:
		try:
			temp = float(temp)
			if (temp < 0):
				newValues3.setpoint = float(values3.PIDSetpoint[0])
			else:
				newValues3.setpoint = temp
		except ValueError:
			newValues3.setpoint = float(values3.PIDSetpoint[0])
	#PLC3 Gain
	temp = guiObjects.gainEntry3.get()
	if not temp:
		newValues3.gain = float(values3.PIDGain[0])
	else:
		try:
			temp = float(temp)
			if (temp < 0):
				newValues3.gain = float(values3.PIDGain[0])
			else:
				newValues3.gain = temp
		except ValueError:	
			newValues3.gain2 = float(values3.PIDGain[0])
	#PLC3 Reset
	temp = guiObjects.resetEntry3.get()
	if not temp:
		newValues3.reset = float(values3.PIDResetRate[0])
	else:
		try:
			temp = float(temp)
			if (temp < 0):
				newValues3.reset = float(values3.PIDResetRate[0])
			else:
				newValues3.reset = temp

		except ValueError:
			newValues3.reset = float(values3.PIDResetRate[0])
	#PLC3 Rate
	temp = guiObjects.rateEntry3.get()
	if not temp:
		newValues3.rate = float(values3.PIDRate[0])
	else:
		try:
			temp = float(temp)
			if (temp < 0):
				newValues3.rate = float(values3.PIDRate[0])
			else:
				newValues3.rate = temp
		except ValueError:	
			newValues3.rate = float(values3.PIDRate[0])

	#PLC4 Values. First, make sure the box isn't empty. Then make sure it isn't less than zero, and catch non integer exceptions. Either set it to the old value for error, or new one
	#PLC4 Setpoint
	temp = guiObjects.setpointEntry4.get()
	if not temp:
		newValues4.setpoint = float(values4.PIDSetpoint[0])
	else:
		try:
			temp = float(temp)
			if (temp < 0):
				newValues4.setpoint = float(values4.PIDSetpoint[0])
			else:
				newValues4.setpoint = temp
		except ValueError:
			newValues4.setpoint = float(values4.PIDSetpoint[0])
	#PLC4 Gain
	temp = guiObjects.gainEntry4.get()
	if not temp:
		newValues4.gain = float(values4.PIDGain[0])
	else:
		try:
			temp = float(temp)
			if (temp < 0):
				newValues4.gain = float(values4.PIDGain[0])
			else:
				newValues4.gain = temp
		except ValueError:	
			newValues4.gain = float(values4.PIDGain[0])
	#PLC4 Reset
	temp = guiObjects.resetEntry4.get()
	if not temp:
		newValues4.reset = float(values4.PIDResetRate[0])
	else:
		try:
			temp = float(temp)
			if (temp < 0):
				newValues4.reset = float(values4.PIDResetRate[0])
			else:
				newValues4.reset = temp

		except ValueError:
			newValues4.reset = float(values4.PIDResetRate[0])
	#PLC4 Rate
	temp = guiObjects.rateEntry4.get()
	if not temp:
		newValues4.rate = float(values4.PIDRate[0])
	else:
		try:
			temp = float(temp)
			if (temp < 0):
				newValues4.rate = float(values4.PIDRate[0])
			else:
				newValues4.rate = temp
		except ValueError:	
			newValues4.rate = float(values4.PIDRate[0])

	#PLC5 Values. First, make sure the box isn't empty. Then make sure it isn't less than zero, and catch non integer exceptions. Either set it to the old value for error, or new one
	#PLC5 Setpoint
	temp = guiObjects.setpointEntry5.get()
	if not temp:
		newValues5.setpoint = float(values5.PIDSetpoint[0])
	else:
		try:
			temp = float(temp)
			if (temp < 0):
				newValues5.setpoint = float(values5.PIDSetpoint[0])
			else:
				newValues5.setpoint = temp
		except ValueError:
			newValues5.setpoint = float(values5.PIDSetpoint[0])
	#PLC5 Gain
	temp = guiObjects.gainEntry5.get()
	if not temp:
		newValues5.gain = float(values5.PIDGain[0])
	else:
		try:
			temp = float(temp)
			if (temp < 0):
				newValues5.gain = float(values5.PIDGain[0])
			else:
				newValues5.gain = temp
		except ValueError:	
			newValues5.gain = float(values5.PIDGain[0])
	#PLC5 Reset
	temp = guiObjects.resetEntry5.get()
	if not temp:
		newValues5.reset = float(values5.PIDResetRate[0])
	else:
		try:
			temp = float(temp)
			if (temp < 0):
				newValues5.reset = float(values5.PIDResetRate[0])
			else:
				newValues5.reset = temp

		except ValueError:
			newValues5.reset = float(values5.PIDResetRate[0])
	#PLC5 Rate
	temp = guiObjects.rateEntry5.get()
	if not temp:
		newValues5.rate = float(values5.PIDRate[0])
	else:
		try:
			temp = float(temp)
			if (temp < 0):
				newValues5.rate = float(values5.PIDRate[0])
			else:
				newValues5.rate = temp
		except ValueError:	
			newValues5rate = float(values5.PIDRate[0])
def infiniteLoop():
#since the GUI mainloop takes up all the processor time, the redraw and communicate functions go here. The GUI mainloop will call this function.
	theValues[0] = modbusRead(modbusMaster)
	theValues[1] = modbusRead(modbusMaster2)
	theValues[2] = modbusRead(modbusMaster3)
	theValues[3] = modbusRead(modbusMaster4)
	theValues[4] = modbusRead(modbusMaster5)
	redrawGui(theValues,TheGuiObjects)
	getNewValues(theValues,theNewValues,TheGuiObjects)
	time.sleep(0.5)
	modbusWrite(modbusMaster,theNewValues[0],theOldValues[0])
	modbusWrite(modbusMaster2,theNewValues[1],theOldValues[1])
	modbusWrite(modbusMaster3,theNewValues[2],theOldValues[2])
	modbusWrite(modbusMaster4,theNewValues[3],theOldValues[3])
	modbusWrite(modbusMaster5,theNewValues[4],theOldValues[4])	
	TheGuiObjects.w.after(200,infiniteLoop)

def closeSlaveConnection(master):
	master.close()

if __name__ == "__main__":
	#create slave PLC #1
	global modbusMaster
    	try:
       	 #Connect to slave PLC #1
		modbusMaster = modbus_tcp.TcpMaster(host=VIRTUAL_PLC_IP, port=VIRTUAL_PLC_PORT, timeout_in_sec=5.0)
		modbusMaster.close()
		modbusMaster.open()
	except modbus_tk.modbus.ModbusError, e:
        	print "Modbus error ", e.get_exception_code()
 	except Exception, e2:
        	print "Error ", str(e2)
	except:
		print "error"

	#create slave PLC #2
	global modbusMaster2
    	try:
       	 #Connect to slave PLC #2
		modbusMaster2 = modbus_tcp.TcpMaster(host=VIRTUAL_PLC2_IP, port=VIRTUAL_PLC_PORT, timeout_in_sec=5.0)
		modbusMaster2.close()
		modbusMaster2.open()
	except modbus_tk.modbus.ModbusError, e:
        	print "Modbus error ", e.get_exception_code()
 	except Exception, e2:
        	print "Error ", str(e2)
	except:
		print "error"

	#create slave PLC #3
	global modbusMaster3
    	try:
       	 #Connect to slave PLC #3
		modbusMaster3 = modbus_tcp.TcpMaster(host=VIRTUAL_PLC3_IP, port=VIRTUAL_PLC_PORT, timeout_in_sec=5.0)
		modbusMaster3.close()
		modbusMaster3.open()
	except modbus_tk.modbus.ModbusError, e:
        	print "Modbus error ", e.get_exception_code()
 	except Exception, e2:
        	print "Error ", str(e2)
	except:
		print "error"

	#create slave PLC #4
	global modbusMaster4
    	try:
       	 #Connect to slave PLC #4
		modbusMaster4 = modbus_tcp.TcpMaster(host=VIRTUAL_PLC4_IP, port=VIRTUAL_PLC_PORT, timeout_in_sec=5.0)
		modbusMaster4.close()
		modbusMaster4.open()
	except modbus_tk.modbus.ModbusError, e:
        	print "Modbus error ", e.get_exception_code()
 	except Exception, e2:
        	print "Error ", str(e2)
	except:
		print "error"
	
	#create slave PLC #5
	global modbusMaster5
    	try:
       	 #Connect to slave PLC #5
		modbusMaster5 = modbus_tcp.TcpMaster(host=VIRTUAL_PLC5_IP, port=VIRTUAL_PLC_PORT, timeout_in_sec=5.0)
		modbusMaster5.close()
		modbusMaster5.open()
	except modbus_tk.modbus.ModbusError, e:
        	print "Modbus error ", e.get_exception_code()
 	except Exception, e2:
        	print "Error ", str(e2)
	except:
		print "error"

	#initializations. These are global because the gui function that calls functions within mainloop doesn't accept arguements
	global theValues,theNewValues,theOldValues,TheGuiObjects
	tempValues = modbusRead(modbusMaster)
	tempValues2 = modbusRead(modbusMaster2)
	tempValues3 = modbusRead(modbusMaster3)
	tempValues4 = modbusRead(modbusMaster4)
	tempValues5 = modbusRead(modbusMaster5)
	theValues = [tempValues,tempValues2,tempValues3,tempValues4,tempValues5]
	tempNewValues = newValuesInit(theValues[0])
	tempNewValues2 = newValuesInit(theValues[1])
	tempNewValues3 = newValuesInit(theValues[2])
	tempNewValues4 = newValuesInit(theValues[3])
	tempNewValues5 = newValuesInit(theValues[4])	
	theNewValues = [tempNewValues,tempNewValues2,tempNewValues3,tempNewValues4,tempNewValues5]
	tempOldValues = newValuesInit(theValues[0])
	tempOldValues2 = newValuesInit(theValues[1])
	tempOldValues3 = newValuesInit(theValues[2])
	tempOldValues4 = newValuesInit(theValues[3])
	tempOldValues5 = newValuesInit(theValues[4])
	theOldValues = [tempOldValues,tempOldValues2,tempOldValues3,tempOldValues4,tempOldValues5]
	TheGuiObjects = guiInit(theValues,theNewValues)

	#since the main GUI loop takes up ALL the processor time, this schedules an event for 2000 miliseconds from now
	TheGuiObjects.w.after(2000,infiniteLoop)

	#register to close the connection3 at exit, in case of an emergency exit
	atexit.register(closeSlaveConnection, modbusMaster)	
	atexit.register(closeSlaveConnection, modbusMaster2)	
	atexit.register(closeSlaveConnection, modbusMaster3)	
	atexit.register(closeSlaveConnection, modbusMaster4)
	atexit.register(closeSlaveConnection, modbusMaster5)	
	#start the main GUI loop 
	mainloop()
	
		
        	
    
    

   

