diff --git a/ProgramChooser.py b/ProgramChooser.py new file mode 100644 index 0000000..00c8fdc --- /dev/null +++ b/ProgramChooser.py @@ -0,0 +1,80 @@ +from machine import Pin, I2C +from PCF8574 import I2C_LCD +import time + +class ProgramChooser: + def __init__(self, programs: list, next_btn: int, ok_btn: int, debug=False, run_directly=False): + self.next_btn = Pin(next_btn, Pin.IN, Pin.PULL_DOWN) + self.ok_btn = Pin(ok_btn, Pin.IN, Pin.PULL_DOWN) + self._i2c = I2C(0, sda=Pin(0), scl=Pin(1), freq=400000) + self.lcd = I2C_LCD(self._i2c, 0x27, 2, 16) + self.lcd.custom_char(0, bytearray([0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x00])) # three dots in one, chr(0) + + self.lcd.move_to(0,0) + self.lcd.putstr("[ProgramChooser]< >") + + self.current_selection = None # no selection + self.programs = programs # a dictionary of programs and it's callbacks e.g. {"lora_test": some_callback} + + self.show_selection() + + if run_directly: self.run() + + def log(self, msg, is_debug=False): + print(f"[ProgramChooser] {msg}") + + + def show_selection(self): + self.lcd.move_to(1,1) + + if len(self.programs) == 0: + self.lcd.putstr(" No programs!") + return True + if self.current_selection == None: # set it initially + self.current_selection = 0 + + # the actual displaying process + to_show = list(self.programs.keys())[self.current_selection] + if len(to_show) > 14: + to_show = to_show[:13] + chr(0) + else: + to_show = to_show[:14] + to_show = to_show.center(14) + self.lcd.putstr(to_show) + return True + + + def run(self): + while True: + if self.next_btn.value() == 1: + former_program_name = list(self.programs.keys())[self.current_selection] + self.current_selection = (self.current_selection+1)%len(list(self.programs.keys())) + self.show_selection() + now_program_name = list(self.programs.keys())[self.current_selection] + self.log(f"Selected next program (\"{former_program_name}\" -> \"{now_program_name}\")") + while self.next_btn.value() == 1: time.sleep(0.01) # wait till release + if self.ok_btn.value() == 1: + program_name = list(self.programs.keys())[self.current_selection] + self.log(f"Running selected program! (\"{program_name}\")") + # shorten the name for displaying (if too long) + if len(program_name) > 14: + program_name = program_name[:13] + chr(0) + else: + program_name = program_name[:14] + program_name = program_name.center(14) + self.lcd.move_to(0,0) + self.lcd.putstr(f" {program_name} Executing... ") + self.execute_selection() + while self.ok_btn.value() == 1: time.sleep(0.01) # wait till release (e.g. if the "program" is a simple send action) + self.lcd.putstr(f" {program_name} Closing... ") + time.sleep(1) + self.lcd.move_to(0,0) + self.lcd.putstr("[ProgramChooser]< >") + self.show_selection() + + time.sleep(0.01) + + + def execute_selection(self): # execute the current selected program's callback + self.programs[list(self.programs.keys())[self.current_selection]]() +