from machine import Pin, I2C
import time
from time import sleep
from ssd1306 import SSD1306_I2C
#SSD DISPLAY
import ssd1306
# ESP32 Pin assignment
i2c = I2C(0, scl=Pin(21), sda=Pin(5))
# Screen Variables
width = 128
height = 64
line = 1
highlight = 1
shift = 0
list_length = 0
total_lines = 6
# create the display
oled = SSD1306_I2C(width, height, i2c)
oled.init_display()
# Setup the Rotary Encoder
button_pin = Pin(32, Pin.IN, Pin.PULL_UP)
direction_pin = Pin(34, Pin.IN, Pin.PULL_UP)
step_pin = Pin(35, Pin.IN, Pin.PULL_UP)
#splash screen
oled.text('Lub Control', 1, 1)
oled.show()
sleep(1)
#splash screen end
#set lub class
class Lub:
def __init__(self, lub_type, relayPin, prSwitchPin, timeDelay, lastRun, timeOut, fault, startTime, isRunning, savePos1, savePos2, savePos3):
self.lub_type = lub_type
self.relayPin = Pin(relayPin, Pin.OUT) #solenoid which starts the air supply to particular pump
self.prSwitchPin = Pin(prSwitchPin, Pin.IN, Pin.PULL_DOWN) #switch which trips the above solenoid
self.timeDelay = timeDelay #time gap between successive run of a particular pump
self.lastRun = lastRun #last time the pump ran
self.timeOut = timeOut #maximum time for which the pump can run
self.fault = fault #flag: if the pump runs till the time out time, a fault will be generated
self.startTime = startTime
self.isRunning = isRunning
self.savePos1 = savePos1
self.savePos2 = savePos2
self.savePos3 = savePos3
#updates the variables and
def update_timings(self):
if changeTI:
self.timeDelay = currentTI
if changeTO:
self.timeOut = currentTO
file = open("timings.txt","r")
data = file.readlines()
file.close()
file = open("timings.txt","w")
if self.lub_type == "lfl" and not dig.value() and changeTI: #for saving propel timing
data[self.savePos3] = str(currentTI)+'\n'
else:
data[self.savePos1] = str(currentTI)+'\n'
data[self.savePos2] = str(currentTO)+'\n'
for line in data:
file.write(line)
file.close()
file = open("timings.txt","r")
data = file.readlines()
for lines in data:
print(lines)
file.close()
# read settings from timings file
#settings are as follows: lfl ti_dig, to, ufl ti, to, ogl ti, to, lfl ti_propel
file = open("timings.txt","r")
data = file.readlines()
for x in range(0, len(data)):
data[x] = int(data[x])
file.close()
# set lub params after reading data from timing file
lfl = Lub("lfl", 22, 33, data[0], 0, data[1], "n", 0, "", 0, 1, 6)
ufl = Lub("ufl", 23, 4, data[2], 0, data[3], "n", 0, "", 2, 3, None)
ogl = Lub("ogl", 18, 13, data[4], 0, data[5], "n", 0, "", 4, 5, None)
#set the dig and proper mode pins
dig = Pin(12, Pin.IN, Pin.PULL_DOWN) #check for dig mode
propel = Pin(14, Pin.IN, Pin.PULL_DOWN) #check for propel mode
time_delay_dig = time_delay_propel = 0
#check for dig or propel mode
if dig.value() == 1:
print("DIG Mode")
print(propel.value())
lfl.timeDelay = data[0]
time_delay_dig = data[0]
elif propel.value() == 1:
print("PROPEL Mode")
time_delay_propel = data[6]
lfl.timeDelay = data[6]
#set current time in milliseconds
def current_milli_time():
return round(time.time() * 1000)
#set lubrication queue....add to this queue to run a pump
queue = ""
def show_save_message():
oled.fill(0)
oled.text("Saving....", 1, 1)
oled.show()
sleep(2)
#save to memory
oled.fill(0)
oled.text("Saved", 1, 1)
oled.show()
sleep(2)
def show_menu(menu):
""" Shows the menu on the screen"""
# bring in the global variables
global line, highlight, shift, list_length
# menu variables
item = 1
line = 1
line_height = 10
# clear the display
oled.fill_rect(0,0,width,height,0)
# Shift the list of files so that it shows on the display
list_length = len(menu)
short_list = menu[shift:shift+total_lines]
for item in short_list:
if highlight == line:
oled.fill_rect(0,(line-1)*line_height, width,line_height,1)
oled.text(">",0, (line-1)*line_height,0)
oled.text(item, 10, (line-1)*line_height,0)
oled.show()
else:
oled.text(item, 10, (line-1)*line_height,1)
oled.show()
line += 1
oled.show()
#variable for encoder menu
pumps = [lfl, ufl, ogl]
menu_for_level_1 = [f"LFL {lfl.isRunning}", f"UFL {ufl.isRunning}", f"OGL {ogl.isRunning}"]
menu = menu_for_level_1
level = 0
whichPump_index = 0
def createSubMenu(counter):
submenu = []
submenu.append("Change "+pumps[counter].lub_type+" TI")
submenu.append("Change "+pumps[counter].lub_type+" TO")
submenu.append("Manual")
submenu.append("Back")
return submenu
show_menu(menu) #show intial menu
c = 0 #bug to remove: when clicked on a particular pump in level 0, when level 1 is opened, change TI opens automatically
changeTI = False
changeTO = False
currentTI = 0
currentTO = 0
# for tracking the direction and button state
previous_value = True
button_down = False
showUFLfault = True
showLFLfault = True
showOGLfault = True
manualRun = False
x1 = 0
y1 = 0
# Repeat forever
while True:
#print(lfl.timeDelay, " ", lfl.timeOut)
#print(highlight, shift)
#print(ufl.fault, lfl.fault, ogl.fault, ufl.prSwitchPin.value(), lfl.prSwitchPin.value(), ogl.prSwitchPin.value())
#only when direct of the encoder is changed
if dig.value() == 1 and x1 == 0:
file = open("timings.txt","r")
data = file.readlines()
for x in range(0, len(data)):
data[x] = int(data[x])
file.close()
currentTI = lfl.timeDelay = data[0]
x1 += 1
y1 = 0
print("DIG")
if not dig.value() == 1 and y1 == 0:
file = open("timings.txt","r")
data = file.readlines()
for x in range(0, len(data)):
data[x] = int(data[x])
file.close()
currentTI = lfl.timeDelay = data[6]
y1 += 1
x1 = 0
print("PROPEL")
if previous_value != step_pin.value() and not manualRun:
if step_pin.value() == False:
# Turned Left
if direction_pin.value() == False:
if changeTI:
currentTI += 1
oled.fill(0)
oled.text(str(currentTI)+" secs", 1, 1)
oled.show()
if changeTO:
currentTO += 1
oled.fill(0)
oled.text(str(currentTO)+" secs", 1, 1)
oled.show()
if highlight > 1:
highlight -= 1
else:
if shift > 0:
shift -= 1
# Turned Right
else:
if changeTI:
currentTI -= 1
oled.fill(0)
oled.text(str(currentTI)+" secs", 1, 1)
oled.show()
if changeTO:
currentTO -= 1
oled.fill(0)
oled.text(str(currentTO)+" secs", 1, 1)
oled.show()
if highlight < total_lines:
highlight += 1
else:
if shift+total_lines < list_length:
shift += 1
if not changeTI and not changeTO:
if level == 0:
show_menu([f"LFL {lfl.isRunning}", f"UFL {ufl.isRunning}", f"OGL {ogl.isRunning}"])
else:
show_menu(createSubMenu(whichPump_index))
previous_value = step_pin.value()
# Check for button pressed
if button_pin.value() == False and not button_down:
print("button pressed")
button_down = True
c=c+1
if level == 0: #click on a pump
whichPump_index = highlight-1 + shift
currentTI = pumps[whichPump_index].timeDelay
currentTO = pumps[whichPump_index].timeOut
level +=1
highlight = 1
shift = 0
show_menu(createSubMenu(whichPump_index))
if level == 1 and not changeTI and not changeTO:
if highlight-1 + shift == 3: #back button for level 1
level -=1
highlight = 1
shift = 0
show_menu([f"LFL {lfl.isRunning}", f"UFL {ufl.isRunning}", f"OGL {ogl.isRunning}"])
#showFORlevel0(level, whichPump_index)
c=0
elif highlight-1 + shift == 2: #manual button for level 1
oled.fill(0)
oled.text("Running Manual",1,1)
oled.text(pumps[whichPump_index].lub_type, 1, 10)
oled.show()
#stop all the pump running at the moment
for p in pumps:
p.relayPin.value(0) #signal to x's solenoid
if p.fault != 'y':
p.isRunning = ""
#Run the pump and after that display the menu
queue = pumps[whichPump_index]
manualRun = True
#highlight = 1
#shift = 0
#menu = createSubMenu(whichPump_index)
#show_menu(menu)
elif highlight-1 + shift == 0 and c!=1: #change time interval
oled.fill(0)
oled.text(str(currentTI)+" secs", 1, 1)
oled.show()
changeTI = True
elif highlight-1 + shift == 1: #change timeout
oled.fill(0)
oled.text(str(currentTO)+" secs", 1, 1)
oled.show()
changeTO = True
elif changeTI and not changeTO:
#show_save_message()
pumps[whichPump_index].update_timings()
changeTI = False
highlight = 1
shift = 0
show_menu(createSubMenu(whichPump_index))
elif changeTO and not changeTI:
#show_save_message()
pumps[whichPump_index].update_timings()
#pumps[whichPump_index].timeOut = currentTO
changeTO = False
highlight = 1
shift = 0
show_menu(createSubMenu(whichPump_index))
#print("Returned from launch")
# Decbounce button
if button_pin.value() == True and button_down:
button_down = False
for p in pumps:
if(time.time() - p.lastRun > p.timeDelay) and queue == "" and not manualRun:
if p.fault == "n": #if ufl not in queue and ufl.fault == 'n':
queue = p
#start the pump
if queue!="" and queue.relayPin.value() == 0 and queue.prSwitchPin.value() == 0:
queue.startTime = time.time()
queue.relayPin.value(1) #signal to x's solenoid
queue.isRunning = "Now Rng"
if level == 0:
show_menu([f"LFL {lfl.isRunning}", f"UFL {ufl.isRunning}", f"OGL {ogl.isRunning}"])
#stop the pump
if queue!="":
if queue.prSwitchPin.value() == 1 or time.time() - queue.startTime >= queue.timeOut:
queue.relayPin.value(0) #signal to x's solenoid
queue.lastRun = time.time()
queue.isRunning = ""
if time.time() - queue.startTime >= queue.timeOut: #if the pump has stopped because it ran till its timout time indicates there a problem and set the flag to fault
queue.fault = "y"
queue.isRunning = "fault"
queue = "" #pump has stopped running and is now ready for next pump
if manualRun:
manualRun = False
oled.text("Fault" if pumps[whichPump_index].fault == 'y' else "OK",1,20)
oled.show()
sleep(2)
show_menu(createSubMenu(whichPump_index))
if level == 0:
show_menu([f"LFL {lfl.isRunning}", f"UFL {ufl.isRunning}", f"OGL {ogl.isRunning}"])