histeresis = 2 rele = Pin(16, Pin.OUT, value=1) f = open("setpoint.dat", "r") setpoint = int(f.read()) f.close() #gpio12 == D6 NodeMCU #gpio14 == D5 NodeMCU r = RotaryIRQ(pin_num_clk=12, pin_num_dt=14, min_val=0, max_val=50, reverse=False, range_mode=RotaryIRQ.RANGE_WRAP) r.set(value=setpoint) disp_SP = setpoint y_SP = 28 y_vent = 39 y_wifi = 51 oled.text("Set Point:", 0, y_SP) oled.text(str(setpoint), 112, y_SP) oled.text("Ventilador: NO", 0, y_vent) if wlan.isconnected(): oled.text("WiFi: " + wlan.config('essid'), 0, y_wifi) nic = wlan.config('mac') mac = "" for ot in list(nic): h = hex(ot) mac += h[2] + h[3]
class CoffeeGrinder: """CoffeeGrinder Class""" CPS_DEFAULT = 167 def __init__(self): """Init""" machine.WDT(True) self.tft = self.initDisplay() self.tft.clear() self.encoder_state_machine = RotaryIRQ(25, 26, min_val=0, max_val=2, reverse=True, range_mode=Rotary.RANGE_WRAP) self.encoder_grinder_time = None self.run = True self.update_display = True self.print_s = 0.0 self.encoder_value = 0 self.state = 0 self.state_old = 0 self.edit_state = False self.cup = Cup() self.single_sec = machine.nvs_getint("single_sec") self.double_sec = machine.nvs_getint("double_sec") self.cps = machine.nvs_getint("cps") self.seconds = 0.1 self.edit_cps = False self.pin_start = machine.Pin(33, mode=machine.Pin.IN, pull=machine.Pin.PULL_DOWN, handler=self.__startGrinding, trigger=machine.Pin.IRQ_HILEVEL, acttime=0, debounce=500000) self.pin_menu = machine.Pin(27, mode=machine.Pin.IN, pull=machine.Pin.PULL_DOWN, handler=self.setCPS, trigger=machine.Pin.IRQ_FALLING, acttime=0, debounce=500000) self.pin_out = machine.Pin(32, mode=machine.Pin.INOUT) self.pin_out.value(False) @staticmethod def initDisplay(): """initialize the display""" tft = display.TFT() tft.init(tft.ST7789, rst_pin=23, backl_pin=4, miso=0, mosi=19, clk=18, cs=5, dc=16, width=235, height=340, backl_on=1) tft.font(tft.FONT_DejaVu18) # invert colors tft.tft_writecmd(0x21) # set orientation (optional) tft.orient(tft.PORTRAIT_FLIP) # set window size tft.setwin(52, 40, 188, 280) # x, y -> x2, y2 tft.rect(0, 0, 135, 240, 0xFFFFFF) return tft def __textWrapper(self, x, y, text, color=0xFFFFFF): """Function to warp text""" self.tft.text(x - self.__textCenterOffset(text), y - self.__textFontSizeOffset(), text, color=color) def __initText(self): """Init Text""" text = "Initialize" self.__textWrapper(67, 110, text) text = "Coffegrinder" self.__textWrapper(67, 130, text) time.sleep(4) def __textCenterOffset(self, text): """Center offset""" return int(self.tft.textWidth(text) / 2) def __textFontSizeOffset(self): """Fontsize offset""" return int(self.tft.fontSize()[1] / 2) def __showCoffeData(self): """Show Display Data""" self.update_display = True color = 0xFFFFFF if self.edit_state: color = 0xFF0000 text_s = "Timer: {} \r".format(round(self.print_s, 2)) if self.print_s < 10: text_s = "Timer: {} \r".format(round(self.print_s, 2)) qty = round(self.print_s * self.cps, 1) text_g = "QTY: {} g\r".format(qty) if qty < 10: text_g = "QTY: {} g\r".format(qty) self.tft.textClear(67, 200, text_s, color) if self.state != 2: self.__textWrapper(67, 200, text_s, color) self.__textWrapper(67, 225, text_g, color) def __stateSingeleShot(self): """Single shot""" self.pin_start = machine.Pin(33, mode=machine.Pin.IN, pull=machine.Pin.PULL_DOWN, handler=self.__startGrinding, trigger=machine.Pin.IRQ_HILEVEL, acttime=0, debounce=500000) self.update_display = True self.tft.clear() self.cup.oneCup(self.tft, 57, 90) text = "Single Shot!" self.__textWrapper(67, 30, text) self.print_s = self.single_sec self.run = False def __stateDoubleShot(self): """Double Shot""" self.pin_start = machine.Pin(33, mode=machine.Pin.IN, pull=machine.Pin.PULL_DOWN, handler=self.__startGrinding, trigger=machine.Pin.IRQ_HILEVEL, acttime=0, debounce=500000) self.update_display = True self.tft.clear() self.cup.oneCup(self.tft, 27, 90) self.cup.oneCup(self.tft, 87, 90) text = "Double Shot!" self.__textWrapper(67, 30, text) self.print_s = self.double_sec self.run = False def __stateEndlessShot(self): """Endless""" self.pin_start = machine.Pin(33, mode=machine.Pin.IN, pull=machine.Pin.PULL_DOWN, handler=self.__startGrinding, trigger=machine.Pin.IRQ_HILEVEL, acttime=0, debounce=500000) self.update_display = True self.tft.clear() self.cup.endLess(self.tft, 68, 110, 20) text = "Endless!" self.__textWrapper(67, 30, text) self.run = False def __startGrinding(self, pin): """Interrupt routine for grinder start""" if self.edit_state: return self.pin_start.init(trigger=machine.Pin.IRQ_DISABLE) self.pin_menu.init(trigger=machine.Pin.IRQ_DISABLE) time.sleep(0.1) if not self.pin_start.value(): self.pin_menu.init(trigger=machine.Pin.IRQ_FALLING) self.pin_start.init(trigger=machine.Pin.IRQ_HILEVEL) return self.pin_out.value(True) if self.state != 2: sleep = self.print_s while sleep > 0: text = "Seconds: {}".format(round(sleep, 2)) self.__textWrapper(67, 200, text, 0xec7d15) sleep -= 0.1 time.sleep(0.1) else: text = "Grind!" self.__textWrapper(67, 200, text) count = 0.2 time.sleep(0.2) while self.pin_start.value(): qty = round(count * self.cps, 1) text_g = "QTY: {} g".format(qty) if qty < 10: text_g = "QTY: {} g\r".format(qty) self.__textWrapper(67, 225, text_g) count += 0.1 time.sleep(0.1) self.__textWrapper(67, 200, "\r ") self.pin_out.value(False) print(self.pin_out.value()) self.update_display = True time.sleep(1) self.pin_menu.init(trigger=machine.Pin.IRQ_FALLING) self.pin_start.init(trigger=machine.Pin.IRQ_HILEVEL) def __setCoffeGrindTime(self, pin): """Interrupt routine for set timer""" self.update_display = True if self.state == 0: self.single_sec = self.seconds / 10 self.print_s = self.single_sec machine.nvs_setint("single_sec", int(self.seconds)) elif self.state == 1: self.double_sec = self.seconds / 10 self.print_s = self.double_sec machine.nvs_setint("double_sec", int(self.seconds)) def switchState(self, pin): """Switch state on button press""" self.pin_menu.init(trigger=machine.Pin.IRQ_DISABLE) self.update_display = True if self.state == 2: self.edit_state = False self.pin_menu.init(trigger=machine.Pin.IRQ_FALLING) return if self.edit_state: self.edit_state = False elif not self.edit_state: self.edit_state = True if self.edit_state: value = 0.1 if self.state_old == 0: value = self.single_sec elif self.state_old == 1: value = self.double_sec value *= 10 self.encoder_state_machine.set(value=value, min_val=1, max_val=120, range_mode=Rotary.RANGE_WRAP) else: self.encoder_state_machine.set(value=self.state_old, min_val=0, max_val=2, range_mode=Rotary.RANGE_WRAP) self.pin_menu.init(trigger=machine.Pin.IRQ_FALLING) def setCPS(self, pin): self.pin_menu.init(trigger=machine.Pin.IRQ_DISABLE) self.edit_cps = True def editCPS(self): self.encoder_state_machine.set(value=self.cps * 10, min_val=100, max_val=200, range_mode=Rotary.RANGE_WRAP) self.tft.clear() text = "Set CPS" self.__textWrapper(67, 110, text) time.sleep(1.0) while True: self.cps = self.encoder_value / 100 text = "CPS: {}\r".format(round(self.cps, 2)) self.__textWrapper(67, 130, text, 0xec7d15) if not self.pin_menu.value(): print(self.pin_menu.value()) break time.sleep(0.1) machine.nvs_setint("cps", int(self.cps * 100)) self.encoder_state_machine.set(value=0, min_val=0, max_val=2, range_mode=Rotary.RANGE_WRAP) self.tft.clear() self.edit_cps = False self.pin_menu.init(trigger=machine.Pin.IRQ_FALLING, handler=self.switchState) def __getEncoderValue(self): """Thread for fast polling encoder value""" while True: ntf = _thread.wait(0) if ntf == _thread.EXIT: # Terminate the thread return self.encoder_value = self.encoder_state_machine.value() time.sleep(0.001) def __shotState(self): """Thread for checking states""" self.state_old = self.encoder_value while True: ntf = _thread.wait(50) if ntf == _thread.EXIT: # Terminate the thread return if not self.edit_state: self.state = self.encoder_value if self.state_old != self.state: self.run = True self.state_old = self.state else: self.seconds = self.encoder_value def runProgram(self): """Run Main Program""" if not self.single_sec: self.single_sec = 1 self.single_sec /= 10 if not self.double_sec: self.double_sec = 1 self.double_sec /= 10 if not self.cps: self.cps = self.CPS_DEFAULT self.cps /= 100 self.tft.set_fg(0x000000) self.shot_state_th = _thread.start_new_thread("Shot_state", self.__shotState, ()) _thread.start_new_thread("t", self.__getEncoderValue, ()) self.__initText() if self.edit_cps: self.editCPS() self.pin_menu.init(trigger=machine.Pin.IRQ_FALLING, handler=self.switchState) # self.__stateSingeleShot() self.state = 0 self.run = True while True: if self.state == 0 and self.run: self.__stateSingeleShot() elif self.state == 1 and self.run: self.__stateDoubleShot() elif self.state == 2 and self.run: self.__stateEndlessShot() if self.edit_state: self.__setCoffeGrindTime(1) if self.update_display: self.__showCoffeData() self.update_display = False time.sleep(0.1)