class LCD(object): def __init__(self): self.lcd = CharLCD(i2c_expander='MCP23008', address=0x20, cols=16, rows=2, backlight_enabled=False) def write(self, msg, reset=True): if reset: self.clear() self.lcd.write_string(msg) self.on() def quick_write(self, msg, cursor_pos=(1,0)): self.lcd.cursor_pos = cursor_pos self.lcd.write_string(msg) def clear(self): self.lcd.clear() def on(self): self.lcd.backlight_enabled = True def off(self): self.clear() self.lcd.backlight_enabled = False
def lcd_print(value,show=5): board.digital[lcd_switch].write(1) lcd = CharLCD('PCF8574', 0x27) lcd.write_string("Moist:"+ str(value)+ "\r\n" +"Len DF: " + str(len(value_set))) time.sleep(show) lcd.clear() board.digital[lcd_switch].write(0)
def initDisplay(self, address): display = self.getConnectedDisplayData(address, self._settings.displays2) # print("initDisplay") # print(display) # print(type(display)) if (display and display['type'] == 'OLED'): # if OLED serial = i2c(port=1, address=display['address']) # substitute ssd1331(...) or sh1106(...) below if using that device # device = ssd1306(serial) device = sh1106(serial) device.clear() return device if (display and display['type'] == 'LCD'): # if LCD device = CharLCD(i2c_expander='PCF8574', address=int(display['address'], 0), port=1, cols=display['width'], rows=display['height'], dotsize=8, charmap='A02', auto_linebreaks=True, backlight_enabled=True) # substitute ssd1331(...) or sh1106(...) below if using that device # device = ssd1306(serial) device.clear() return device return False
class dbusService(dbus.service.Object): lcd = None framebuffer = ['', ''] num_cols = 16 #threads = [] t = None def __init__(self, bus_name): #ehm? super(dbusService, self).__init__(bus_name, "/com/arctura/2606a") self.lcd = CharLCD(i2c_expander='PCF8574', address=0x27, port=1, cols=16, rows=2, dotsize=8, charmap='A00', auto_linebreaks=True, backlight_enabled=True) self.framebuffer[0] = ' ' self.framebuffer[1] = ' ' self.lcd.clear() self.charset()
class Display: def __init__(self, lcd=None): if lcd is None: self.lcd = CharLCD(i2c_expander='PCF8574', address=0x27, port=1, cols=COLS, rows=2, dotsize=8, charmap='A02', auto_linebreaks=True, backlight_enabled=True) else: self.lcd = lcd self.zeile_1 = None self.zeile_2 = None def display_schreiben(self, text): delay = 1.3 buffer = text_zerlegen(text) while buffer: self.lcd.clear() try: self.lcd.write_string("{zeile1}\n\r{zeile2}".format( zeile1=buffer[0], zeile2=buffer[1])) except IndexError: self.lcd.write_string("{zeile1}\n\r{zeile2}".format( zeile1=buffer[0], zeile2="")) time.sleep(delay) if len(buffer) <= 2: break buffer.pop(0)
class Display: def __init__(self): self.lcd = CharLCD(i2c_expander='PCF8574', address=0x27, port=1, cols=16, rows=2, dotsize=8, charmap='A02', auto_linebreaks=True, backlight_enabled=True) self.displayinhalt = None self.displayhistory = [] def display_schreiben(self, zeile1, zeile2=None): self.__set_displayinhalt(zeile1, zeile2) zeile1 = str(zeile1) self.lcd.clear() if zeile2 is None: self.lcd.write_string(zeile1) else: zeile2 = str(zeile2) if len(zeile1) > 16 or len(zeile2) > 16: self.lcd.write_string(zeile1) time.sleep(2) self.lcd.clear() self.lcd.write_string(zeile2) time.sleep(2) else: self.lcd.write_string(zeile1 + "\n\r" + zeile2) def __set_displayinhalt(self, zeile1, zeile2): self.__set_displayhistory() self.displayinhalt = [zeile1, zeile2] def __set_displayhistory(self): self.displayhistory.append(self.displayinhalt) if len(self.displayhistory) > 10: del self.displayhistory[0]
def WriteDisplay(self, string=None): if string is None: return print("LCDClass: WriteDisplay {}".format(string)) lcd = CharLCD(0x27) lcd.clear() lcd.write_string(str(string)) return
def LCD_init(addr=0x27): import sys import smbus2 from RPLCD.i2c import CharLCD sys.modules['smbus'] = smbus2 global lcd lcd = CharLCD('PCF8574', address=addr, port=1, backlight_enabled=True) lcd.clear()
class LCDController: def __init__(self): self.lcd = CharLCD('PCF8574', address=0x27, port=1, backlight_enabled=True) GPIO.setmode(GPIO.BCM) sys.modules['smbus'] = smbus def writeLcd(self, firstStr, secondStr=""): self.lcd.clear() self.lcd.cursor_pos = (0, 0) self.lcd.write_string(firstStr) self.lcd.cursor_pos = (1, 0) self.lcd.write_string(secondStr)
def main(): sensor = Sensor(sensor_type, sensor_channel) lcd = CharLCD("PCF8574", 0x27) # add custom chars lcd.create_char(0, degrees) menu = { 1: sensor_data(sensor, lcd), 2: clock(), 3: ip() } for i in menu.keys(): show(lcd, menu[i]) time.sleep(3) lcd.clear()
def get_lcd(backlight_on, clear_screen=True): GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) GPIO.setup(22, GPIO.IN, pull_up_down=GPIO.PUD_UP) lcd = CharLCD(i2c_expander='PCF8574', address=0x27, port=1, cols=20, rows=4, dotsize=8, charmap='A00', auto_linebreaks=True, #backlight_enabled=backlight_on) backlight_enabled=True) if clear_screen: lcd.clear() lcd.write_string("********************") lcd.cursor_pos = (1, 0) lcd.cursor_pos = (3, 0) lcd.write_string("********************") return lcd
def main(): lcd = CharLCD(i2c_expander='PCF8574', address=0x3F, port=1, cols=15, rows=2, dotsize=8, charmap='A02', auto_linebreaks=True, backlight_enabled=True) while True: ip = get_ip() lcd.clear() print("IP Address: %s" % (ip)) lcd.write_string(ip) if ip != '127.0.0.1': break time.sleep(3)
def lcd_display(): global flate if flate: lcd = CharLCD('PCF8574', address=ADDRESS, port=1, backlight_enabled=True) lcd.clear() lcd.cursor_pos = (0, 5) lcd.write_string("Welcome!") lcd.cursor_pos = (1, 5) global txt lcd.write_string(txt) flate = False os.system("cat /dev/null > plate.txt") else: lcd = CharLCD('PCF8574', address=ADDRESS, port=1, backlight_enabled=False) os.system("cat /dev/null > plate.txt")
def lcd_print_main(): sys.modules['smbus'] = smbus2 from RPLCD.i2c import CharLCD lcd = CharLCD('PCF8574', address=0x27, port=1, backlight_enabled=True) try: print('lcd printing') lcd.clear() while 1: lcd.cursor_pos = (0, 0) lcd.write_string("Whiskey") lcd.cursor_pos = (1, 0) lcd.write_string("is coming......") time.sleep(5) break # main() # lcd.clear() except KeyboardInterrupt: print('closing') finally: lcd.clear()
class EcranLCD: """ Cette classe permet de simplifier l'utilisation des écrans LCD """ def __init__(self, adr): """ adr : adresse : 0x27 ou 0x26 """ self.lcd = CharLCD('PCF8574', adr) self.lcd.clear() def printString(self, char): if (isinstance(char, str)): self.lcd.clear() self.lcd.write_string(char) def clear(self): self.lcd.clear()
class CharacterLCD(): def __init__(self, chip, i2cbus, i2caddress, col, row): self.__lcd = CharLCD(i2c_expander=chip, address=i2caddress, port=i2cbus, cols=col, rows=row) def WriteString(self, text): self.__lcd.clear() self.__lcd.write_string(text) def WriteLines(self, textArray, numberOfLines): self.__lcd.clear() self.__lcd.write_string(textArray[0]) for i in range(1, numberOfLines): # self.__lcd.crlf() self.__lcd.write_string("\n\r") self.__lcd.write_string(textArray[i]) def Clean(self): self.__lcd.clear()
class TwolineDisplay: __lcd = None __animIdx = -1 __animChars = [] __screenMode = "" __port = 1 __logger = None def __init__(self, logger): self.__logger = logger return None def open(self): addr = self.__find_device(self.__port) if (addr < 1): raise exception self.__lcd = CharLCD(i2c_expander='PCF8574', address=addr, port=self.__port, cols=16, rows=2, dotsize=8, #charmap='A02', auto_linebreaks=True, backlight_enabled=True) self.__lcd.clear() self.__create_custom_chars() return True def close(self): self.__lcd.clear() self.__lcd.close() self.__lcd = None return True def __find_device(self,port): bus = smbus.SMBus(port) # 1 indicates /dev/i2c-1 for device in range(128): try: bus.read_byte(device) #print(hex(device)) return device except: # exception if read_byte fails pass return -1 def clear(self): self.__lcd.clear() self.__screenMode = "" def show_centered(self,line,text): self.__setScreenModeToText() self.__logger.debug("Display: " + text) self.__lcd.cursor_pos = (line, 0) self.__lcd.write_string(text.center(16)) def show_centered(self,line0,line1): self.__setScreenModeToText() self.__logger.debug("Display: " + (line0 if line0 is not None else "") + " || " + (line1 if line1 is not None else "")) if (line0 is not None): self.__lcd.cursor_pos = (0, 0) self.__lcd.write_string(line0.center(16)) if (line1 is not None): self.__lcd.cursor_pos = (1, 0) self.__lcd.write_string(line1.center(16)) def update_value_time_trend(self,value,mins,trend): self.__setScreenModeToEgv() valStr = "--" trendChars = " " if (value > 0): valStr = str(value) trendChars = self.__get_trend_chars(trend) print(valStr + " " + str(mins)) valStr = valStr.replace("0","O") valStr = valStr.rjust(6) self.__lcd.cursor_pos = (0, 0) self.__lcd.write_string(valStr) self.__lcd.cursor_pos = (1, 4) self.__lcd.write_string(trendChars) ageStr = self.update_age(mins) def update_age(self, mins): self.__setScreenModeToEgv() ageStr = "now" if (mins > 50): ageStr = "50+" elif (mins > 0): ageStr = str(mins) + "m" ageStr = ageStr.replace("0","O") ageStr = ageStr.rjust(3) self.__lcd.cursor_pos = (1, 13) self.__lcd.write_string(ageStr) def updateAnimation(self): self.__setScreenModeToEgv() self.__animIdx += 1 if (self.__animIdx >= len(self.__animChars)): self.__animIdx = 0 char = self.__animChars[self.__animIdx] self.__lcd.cursor_pos = (0, 15) self.__lcd.write_string(char) def __setScreenModeToEgv(self): if (not self.__screenMode == "egv"): self.__logger.debug("Display mode EGV") self.__screenMode = "egv" self.__lcd.clear() def __setScreenModeToText(self): if (not self.__screenMode == "text"): self.__logger.debug("Display mode Text") self.__screenMode = "text" self.__lcd.clear() def __get_trend_chars(self,trend): if(trend == Trend.NONE): return "**" if(trend == Trend.DoubleUp): return "\x01\x01" if(trend == Trend.SingleUp): return "\x01 " if(trend == Trend.FortyFiveUp): return "\x02 " if(trend == Trend.Flat): return "-\x7e" if(trend == Trend.FortyFiveDown): return "\x03 " if(trend == Trend.SingleDown): return "\x04 " if(trend == Trend.DoubleDown): return "\x04\x04" if(trend == Trend.NotComputable): return "NC" if(trend == Trend.RateOutOfRange): return "HI" return "??" #self.__lcd.write_string('\x02\x02 \x02 \x03 -\x7e \x05 \x06 \x06\x06') def __create_custom_chars(self): upArrow = ( 0b00000, 0b00100, 0b01110, 0b10101, 0b00100, 0b00100, 0b00100, 0b00100 ) self.__lcd.create_char(1, upArrow) upSlight = ( 0b00000, 0b00000, 0b00111, 0b00011, 0b00101, 0b01000, 0b10000, 0b00000 ) self.__lcd.create_char(2, upSlight) dnSlight = ( 0b00000, 0b00000, 0b10000, 0b01000, 0b00101, 0b00011, 0b00111, 0b00000 ) self.__lcd.create_char(3, dnSlight) dnArrow = ( 0b00000, 0b00100, 0b00100, 0b00100, 0b00100, 0b10101, 0b01110, 0b00100 ) self.__lcd.create_char(4, dnArrow) self.__animChars = [ '\x05', '\x06', '\x07' ] anim1 = ( 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00010, 0b00000 ) self.__lcd.create_char(5, anim1) anim2 = ( 0b00000, 0b00000, 0b00000, 0b00100, 0b01010, 0b00100, 0b00000, 0b00000 ) self.__lcd.create_char(6, anim2) anim3 = ( 0b01100, 0b10010, 0b10010, 0b01100, 0b00000, 0b00000, 0b00000, 0b00000 ) self.__lcd.create_char(7, anim3)
class DisplayDriver(object): def __init__(self, rows, cols, debug_mode=False): self.row_count = rows self.col_count = cols self.debug_mode = debug_mode self.native_mode = False # logging.debug('DisplayDriver.__init__: native_mode {}'.format(self.native_mode)) self.change_set = [] self.frame_buffer = None self.update_buffer = None self.lcd = None self.cursor_data = [0, 0, False] self.cursor_update = [0, 0, False] self.setup() def setup(self): self.frame_buffer = [] self.update_buffer = [] for index in range(0, self.row_count): self.frame_buffer.append(bytearray(' ' * self.col_count, 'ascii')) self.update_buffer.append(bytearray(' ' * self.col_count, 'ascii')) if self.debug_mode is False: if self.native_mode is True: self.init_lcd() # else: # term.clear() def init_lcd(self): self.lcd = CharLCD('PCF8574', 0x27) self.lcd.clear() self.lcd.backlight_enabled = False def get_rows(self): return self.row_count def get_cols(self): return self.col_count def clear(self, row=None): if row is None: for index in range(0, self.row_count): self.write('', index, clear_row=True) else: if row < self.row_count: self.write('', row, clear_row=True) def write(self, text, row, left_adjust=True, clear_row=True, commit=True): if row < self.row_count: if clear_row is True: self.update_buffer[row] = bytearray(' ' * self.col_count, 'ascii') else: self.update_buffer[row] = bytearray(self.frame_buffer[row]) text = text.encode('ascii', 'replace') if len(text) > self.col_count: text = text[:self.col_count] if left_adjust is True: start = 0 else: start = self.col_count - len(text) stop = start + len(text) pos = 0 for index in range(start, stop): self.update_buffer[row][index] = text[pos] pos += 1 if commit is True: self.update_display() def set_cursor(self, row, col, visible): self.cursor_update = [] self.cursor_update.append(row) self.cursor_update.append(col) self.cursor_update.append(visible) self.update_cursor() def is_cell_changed(self, row, col): is_changed = False for item in self.change_set: if (item[0] == row) and (item[1] == col): is_changed = True break return is_changed def create_change_set(self): self.change_set = [] for row in range(0, self.row_count): for col in range(0, self.col_count): if (self.frame_buffer is None) or (self.update_buffer[row][col] != self.frame_buffer[row][col]): item = (row, col) self.change_set.append(item) def is_cursor_update(self): update = False if (self.cursor_data[0] != self.cursor_update[0]) or \ (self.cursor_data[1] != self.cursor_update[1]) or \ (self.cursor_data[2] != self.cursor_update[2]): update = True return update def update_cursor(self): if self.debug_mode is True: self.show_debug_display() else: self.show_normal_display() def update_display(self): self.create_change_set() if self.debug_mode is True: self.show_debug_display() else: self.show_normal_display() def show_normal_display(self): if len(self.change_set) > 0: for row in range(0, self.row_count): for col in range(0, self.col_count): if self.is_cell_changed(row, col) is True: self.frame_buffer[row][col] = self.update_buffer[row][ col] self.lcd.backlight_enabled = True # term.pos(row + 1, 1) self.lcd.cursor_pos = (row, 0) line_str = str(self.update_buffer[row], 'utf8') # logging.debug('line_str: {}'.format(line_str)) # term.write(line_str) self.lcd.write_string(line_str) if self.is_cursor_update() is True: cursor_text = ' - r:{}, c:{}, v:{}'.format(self.cursor_update[0], self.cursor_update[1], self.cursor_update[2]) self.cursor_data = self.cursor_update term.write(cursor_text) def show_debug_display(self): print('{}'.format('-' * self.col_count)) for row in range(0, self.row_count): change_str = '' for col in range(0, self.col_count): if self.is_cell_changed(row, col) is True: self.frame_buffer[row][col] = self.update_buffer[row][col] change_str += '*' else: change_str += ' ' print('{}'.format(change_str)) line_str = str(self.update_buffer[row]) print('{}'.format(line_str)) print('{}'.format('-' * self.col_count))
class Plugin(plugin.PluginProto): PLUGIN_ID = 12 PLUGIN_NAME = "Display - LCD2004 I2C" PLUGIN_VALUENAME1 = "LCD" P12_Nlines = 4 def __init__(self, taskindex): # general init plugin.PluginProto.__init__(self, taskindex) self.dtype = rpieGlobals.DEVICE_TYPE_I2C self.vtype = rpieGlobals.SENSOR_TYPE_NONE self.ports = 0 self.valuecount = 0 self.senddataoption = False self.timeroption = True self.timeroptional = True self.formulaoption = False self.device = None self.width = None self.height = None self.lines = [] self.linelens = [0, 0, 0, 0] def plugin_init(self, enableplugin=None): plugin.PluginProto.plugin_init(self, enableplugin) if self.enabled == False or enableplugin == False: self.__del__() return False if self.enabled: if int(self.taskdevicepin[0]) > 0: try: gpios.HWPorts.remove_event_detect( int(self.taskdevicepin[0])) except: pass try: gpios.HWPorts.add_event_detect(int(self.taskdevicepin[0]), gpios.BOTH, self.p012_handler) self.timer100ms = False except Exception as e: misc.addLog( rpieGlobals.LOG_LEVEL_ERROR, "Event can not be added, register backup timer " + str(e)) self.timer100ms = True else: self.timer100ms = False i2cport = -1 try: for i in range(0, 2): if gpios.HWPorts.is_i2c_usable( i) and gpios.HWPorts.is_i2c_enabled(i): i2cport = i break except: i2cport = -1 if i2cport > -1: if self.interval > 2: nextr = self.interval - 2 else: nextr = self.interval self.initialized = False self.device = None try: if "x" in str(self.taskdevicepluginconfig[2]): resstr = str(self.taskdevicepluginconfig[2]).split('x') self.width = int(resstr[0]) self.height = int(resstr[1]) else: self.width = None self.height = None except: self.width = None self.height = None if str(self.taskdevicepluginconfig[0]) != "0" and str( self.taskdevicepluginconfig[0]).strip( ) != "" and self.taskdevicepluginconfig[ 1] > 0 and self.height is not None: devtype = str(self.taskdevicepluginconfig[0]) devparam = None if "23017" in devtype: if "/B" in devtype: devparam = {'gpio_bank': 'B'} else: devparam = {'gpio_bank': 'A'} devtype = "MCP23017" try: self.device = CharLCD( i2c_expander=devtype, expander_params=devparam, address=int(self.taskdevicepluginconfig[1]), port=i2cport, cols=self.width, rows=self.height, auto_linebreaks=(str( self.taskdevicepluginconfig[3]) == "1"), backlight_enabled=(str( self.taskdevicepluginconfig[4]) == "1")) self.uservar[0] = 1 self.initialized = True except Exception as e: misc.addLog(rpieGlobals.LOG_LEVEL_ERROR, "LCD can not be initialized! " + str(e)) self.device = None return False if self.device is not None: self._lastdataservetime = rpieTime.millis() - (nextr * 1000) else: self.initialized = False else: misc.addLog(rpieGlobals.LOG_LEVEL_ERROR, "LCD I2C error! ") def webform_load(self): # create html page for settings choice1 = str(self.taskdevicepluginconfig[0]) # store display type options = ["PCF8574", "MCP23008", "MCP23017", "MCP23017/B"] webserver.addHtml("<tr><td>I2C chip type:<td>") webserver.addSelector_Head("p012_type", True) for d in range(len(options)): webserver.addSelector_Item(options[d], options[d], (choice1 == options[d]), False) webserver.addSelector_Foot() choice2 = int(float( self.taskdevicepluginconfig[1])) # store i2c address optionvalues = [] for i in range(0x20, 0x28): optionvalues.append(i) for i in range(0x38, 0x40): optionvalues.append(i) options = [] for i in range(len(optionvalues)): options.append(str(hex(optionvalues[i]))) webserver.addFormSelector("Address", "p012_adr", len(options), options, optionvalues, None, choice2) webserver.addFormNote( "Enable <a href='pinout'>I2C bus</a> first, than <a href='i2cscanner'>search for the used address</a>!" ) choice3 = self.taskdevicepluginconfig[2] # store resolution webserver.addHtml("<tr><td>Resolution:<td>") webserver.addSelector_Head("p012_res", False) options = ["16x2", "20x4"] for d in range(len(options)): webserver.addSelector_Item(options[d], options[d], (choice3 == options[d]), False) webserver.addSelector_Foot() choice4 = int(float( self.taskdevicepluginconfig[3])) # store linewrap state options = ["Auto", "None"] optionvalues = [1, 0] webserver.addFormSelector("Linebreak", "p012_break", len(optionvalues), options, optionvalues, None, choice4) choice5 = int(float( self.taskdevicepluginconfig[4])) # store backlight state options = ["Enabled", "Disabled"] optionvalues = [1, 0] webserver.addFormSelector("Backlight", "p012_blight", len(optionvalues), options, optionvalues, None, choice5) if "x2" in str(self.taskdevicepluginconfig[2]): lc = 2 else: lc = 4 for l in range(lc): try: linestr = self.lines[l] except: linestr = "" webserver.addFormTextBox("Line" + str(l + 1), "p012_template" + str(l), linestr, 128) webserver.addFormPinSelect("Display button", "taskdevicepin0", self.taskdevicepin[0]) return True def __del__(self): try: if self.device is not None: self.device.clear() self.device._set_backlight_enabled(False) except: pass if self.enabled and self.timer100ms == False and (self.taskdevicepin[0] > -1): try: gpios.HWPorts.remove_event_detect(int(self.taskdevicepin[0])) except: pass def plugin_exit(self): self.__del__() def webform_save(self, params): # process settings post reply par = webserver.arg("p012_type", params) if par == "": par = "PCF8574" self.taskdevicepluginconfig[0] = str(par) par = webserver.arg("p012_adr", params) if par == "": par = 0x27 self.taskdevicepluginconfig[1] = int(par) par = webserver.arg("p012_res", params) self.taskdevicepluginconfig[2] = str(par) par = webserver.arg("p012_break", params) self.taskdevicepluginconfig[3] = str(par) par = webserver.arg("p012_blight", params) self.taskdevicepluginconfig[4] = str(par) for l in range(self.P12_Nlines): linestr = webserver.arg("p012_template" + str(l), params).strip() try: self.lines[l] = linestr except: self.lines.append(linestr) try: self.taskdevicepin[0] = int(webserver.arg("taskdevicepin0", params)) except: self.taskdevicepin[0] = -1 self.plugin_init() return True def plugin_read( self): # deal with data processing at specified time interval if self.initialized and self.enabled and self.device and self.height: try: for l in range(int(self.height)): resstr = "" try: linestr = str(self.lines[l]) resstr = self.lcdparse(linestr) except Exception as e: resstr = "" misc.addLog(rpieGlobals.LOG_LEVEL_ERROR, "LCD parse error: " + str(e)) if resstr != "": if self.linelens[l] > len(resstr): clrstr = "" clrstr += ' ' * self.linelens[l] self.device.cursor_pos = (l, 0) self.device.write_string(clrstr) self.device.cursor_pos = (l, 0) # (row, col) self.device.write_string(resstr) self.linelens[l] = len(resstr) except Exception as e: misc.addLog(rpieGlobals.LOG_LEVEL_ERROR, "LCD write error! " + str(e)) self._lastdataservetime = rpieTime.millis() return True def plugin_write(self, cmd): res = False cmdarr = cmd.split(",") cmdarr[0] = cmdarr[0].strip().lower() if cmdarr[0] == "lcdcmd": try: cmd = cmdarr[1].strip() except: cmd = "" try: if self.device is not None: if cmd == "on": self.device._set_backlight_enabled(True) res = True elif cmd == "off": self.device._set_backlight_enabled(False) res = True elif cmd == "clear": self.device.clear() res = True elif cmd == "clearline": try: l = int(cmdarr[2].strip()) except Exception as e: misc.addLog(rpieGlobals.LOG_LEVEL_ERROR, "Parameter error: " + str(e)) return False if self.device is not None and self.height is not None: if l > 0: l -= 1 clrstr = "" clrstr += ' ' * self.width self.device.cursor_pos = (l, 0) self.device.write_string(clrstr) res = True except Exception as e: misc.addLog(rpieGlobals.LOG_LEVEL_ERROR, "LCD command error! " + str(e)) res = False elif cmdarr[0] == "lcd": sepp = len(cmdarr[0]) + len(cmdarr[1]) + len(cmdarr[2]) + 1 sepp = cmd.find(',', sepp) try: y = int(cmdarr[1].strip()) x = int(cmdarr[2].strip()) text = cmd[sepp + 1:] except Exception as e: misc.addLog(rpieGlobals.LOG_LEVEL_ERROR, "Parameter error: " + str(e)) return False if x > 0 and y > 0: x -= 1 y -= 1 try: if self.device is not None: self.device.cursor_pos = (y, x) resstr = self.lcdparse(text) self.device.write_string(resstr) res = True except Exception as e: misc.addLog(rpieGlobals.LOG_LEVEL_ERROR, "LCD command error! " + str(e)) res = False return res def lcdparse(self, ostr): cl, st = commands.parseruleline(ostr) if st == "CMD": resstr = str(cl) else: resstr = str(ostr) return resstr def p012_handler(self, channel): self.timer_ten_per_second() def timer_ten_per_second(self): if self.initialized and self.enabled: val = gpios.HWPorts.input(int(self.taskdevicepin[0])) if int(val) != int(float(self.uservar[0])): self.uservar[0] = int(val) if int(val) == 0: if self.device._get_backlight_enabled(): self.device._set_backlight_enabled(False) else: self.device._set_backlight_enabled(True)
class ScreenManager: """Manages Screens Creates the arborescence needed for a LedPanel and manages it Please call cleanup() once you have finished. """ def __init__(self, panel): self.panel = panel self.lcd_lock = threading.RLock() self.gpio_lock = threading.Lock() home = StartScreen('HOME', 'LedPanel 289', self, 'Made by N.V.Zuijlen') main_menu = MenuScreen('MAIN_MENU', 'Menu', self) manual_menu = MenuScreen('MANUAL_MENU', 'Manuel', self) universe_selector = ValueScreen('UNIVERSE_SELECTOR', 'Choix Univers', self, self.panel.start_universe, 0, math.inf) channel_selector = ValueScreen('CHANNEL_SELECTOR', 'Choix Adresse', self, self.panel.start_channel+1, 1, DMX_UNIVERSE_SIZE) blackout = ToggleScreen('BLACKOUT', 'Blackout', self) test_pattern = MacroScreen('TEST_PATTERN', 'Test leds', self, macros.TestPixels(panel.columns, panel.rows)) ip_info = InformationScreen('IP_INFO', 'Adresse IP', self, get_ip_address()) universe_selector.setCallback(lambda uni: self.panel.setAddress(universe=uni)) channel_selector.setCallback(lambda chan: self.panel.setAddress(channel=chan)) blackout.setCallback(lambda off: self.panel.setOnOff(not off)) home.addChild(main_menu) main_menu.addChild(universe_selector) main_menu.addChild(channel_selector) main_menu.addChild(manual_menu) main_menu.addChild(ip_info) manual_menu.addChild(blackout) manual_menu.addChild(test_pattern) self.current = home with self.lcd_lock: self.lcd = CharLCD(i2c_expander='PCF8574', address=0x3F, cols=20, rows=4, auto_linebreaks=False, backlight_enabled=False) self.lcd.cursor_mode = 'hide' # UP/DOWN arrow. Use as char \x00 self.lcd.create_char(0, ( 0b00100, 0b01110, 0b11111, 0b00000, 0b00000, 0b11111, 0b01110, 0b00100 )) self.updateScreen() #self.backlightOn() def listenToGPIO(self): for pin in [UP_BUTTON, DOWN_BUTTON, OK_BUTTON, BACK_BUTTON]: GPIO.setup(pin, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.add_event_detect( pin, GPIO.RISING, callback=self.getGPIOCallback(), bouncetime=200 ) def getGPIOCallback(self): def GPIOCallback(channel): with self.gpio_lock: GPIO.output(STATUS_LED, GPIO.HIGH) #self.backlightOn() if channel == UP_BUTTON: print("UP", channel) self.current.onUp() elif channel == DOWN_BUTTON: print("DOWN", channel) self.current.onDown() elif channel == OK_BUTTON: print("OK", channel) self.current.onOK() elif channel == BACK_BUTTON: print("BACK", channel) self.current.onBack() self.updateScreen() GPIO.output(STATUS_LED, GPIO.LOW) return GPIOCallback def backlightOn(self): self.on_time = datetime.now() with self.lcd_lock: self.lcd.backlight_enabled = True self.panel.threadSafeSchedule( 11*1000, self.turn_off_backlight_if_inactivity ) def turn_off_backlight_if_inactivity(self): if datetime.now() - self.on_time >= timedelta(seconds=10): with self.lcd_lock: self.lcd.backlight_enabled = False def updateScreen(self): self.current.computeDisplay() with self.lcd_lock: self.lcd.clear() self.lcd.write_string(self.current.first_line) self.lcd.crlf() self.lcd.write_string(self.current.second_line) def cleanup(self): GPIO.cleanup() with self.lcd_lock: self.lcd.close(clear=True)
class LcdHandler(Thread): def __init__(self, rows, cols): Thread.__init__(self) self.daemon = True self.lcd = CharLCD('PCF8574', 0x27, rows=rows, cols=cols) self.rows = rows self.cols = cols self.state_channels = [False, False, False, False, False, False, False, False, False, False] self.lcd_states = ["config","channels"] self.lcd_blocked = False self.current_synth_name = 0 self.start() def get_active_synth_name(self): with open(os.path.dirname(os.path.abspath(__file__)) + '/../logs/current-synth-info.log') as f: content = f.readline() while "RUNNING_SYNTH_NAME" not in content: content = f.readline() content = content.replace('"','') content = content.strip() if "PLEASE WAIT" not in content.split('=')[1]: return content.split('=')[1] else: return self.current_synth_name def write_center(self, row, string): empty_row = ' ' * self.cols self.lcd.cursor_pos = (row,0) self.lcd.write_string(empty_row) string = string.lstrip(' ') #trim the spaces because we center the string ourselves string = string.rstrip(' ') if (len(string) > self.cols): string = string[0:self.cols] col = int((self.cols - len(string)) / 2) if col < 0: col = 0 self.lcd.cursor_pos = (row,col) self.lcd.write_string(string) def init_channels(self): self.lcd.clear() self.write_center(0, self.get_active_synth_name()) self.lcd.cursor_pos = (1, 0) self.lcd.write_string('1 2 3 4 5 R') def write_first_line(self, message, state): self.lcd_blocked = True self.lcd_states[0] = state self.lcd.cursor_pos = (0, 0) empty_row = ' ' * self.cols self.lcd.write_string(empty_row) self.lcd.cursor_pos = (0, 0) self.write_center(0, message) self.lcd_blocked = False def turn_channel_on(self, channel): if 1 <= channel <= 5: self.state_channels[channel] = True if not self.lcd_blocked: self.lcd.cursor_pos = (1, (channel - 1) * 2) self.lcd.write(0xFF) elif 5 < channel <= 9: self.state_channels[channel] = True if any(self.state_channels[6:-1]) and not self.lcd_blocked: self.lcd.cursor_pos = (1, 10) self.lcd.write(0xFF) def turn_channel_off(self, channel): if 1 <= channel <= 5: self.state_channels[channel] = False if not self.lcd_blocked: self.lcd.cursor_pos = (1, (channel - 1) * 2) self.lcd.write_string(str(channel)) elif 5 < channel <= 9: self.state_channels[channel] = False if not any(self.state_channels[6:-1]) and not self.lcd_blocked: self.lcd.cursor_pos = (1, 10) self.lcd.write_string('R') def run(self): self.write_center(0, "WavePi") self.current_synth_name = self.get_active_synth_name() self.write_center(1, self.current_synth_name) sleep(2) self.init_channels() while True: sleep(1) if self.lcd_states[0] == 'sysex_lcd': sleep(3) self.write_first_line(self.current_synth_name, 'config') elif self.current_synth_name != self.get_active_synth_name(): self.current_synth_name = self.get_active_synth_name() self.write_first_line(self.current_synth_name, 'config')
class LCDScreen(object): def __init__(self, welcome_text, i2c_bus=1, i2c_addr=0x27, lcd_width=16, lcd_rows=2): self.lcd = CharLCD(i2c_expander='PCF8574', address=i2c_addr, port=i2c_bus, cols=lcd_width, rows=lcd_rows, dotsize=8, charmap='A02', auto_linebreaks=True, backlight_enabled=True) self._lcd_width = lcd_width self.prevStr = '' # Create some custom characters self.lcd.create_char(0, (0, 0, 0, 0, 0, 0, 0, 0)) self.lcd.create_char(1, (16, 24, 24, 24, 24, 24, 24, 16)) self.lcd.create_char(2, (1, 3, 3, 3, 3, 3, 3, 1)) self.lcd.create_char(3, (17, 27, 27, 27, 27, 27, 27, 17)) self.lcd.create_char(4, (31, 31, 0, 0, 0, 0, 0, 0)) self.lcd.create_char(5, (0, 0, 0, 0, 0, 0, 31, 31)) self.lcd.create_char(6, (31, 31, 0, 0, 0, 0, 0, 31)) self.lcd.create_char(7, (31, 0, 0, 0, 0, 0, 31, 31)) self.lcd.backlight_enabled = True self.lcd.clear() self.print_line(welcome_text, 0, align='CENTER') self.print_line(__version__, 1, align='CENTER') self.lcd.home() def print_line(self, text, line=0, align='LEFT'): """Checks the string, if different than last call, update screen. :param text: :param line: :param align: :return: """ if isinstance(text, float): text = str(text) text = text.encode('utf-8') if self.prevStr != text: # Oh what a shitty way around actually learning the ins and outs of encoding chars... # Display string has changed, update LCD #self.lcd.clear() text_length = len(text) if text_length < self._lcd_width: blank_space = self._lcd_width - text_length if align == 'LEFT': text = text + b' ' * blank_space elif align == 'RIGHT': text = b' ' * blank_space + text else: text = b' ' * (blank_space // 2) + text + b' ' * ( blank_space - blank_space // 2) else: text = text[:self._lcd_width] self.lcd.cursor_pos = (line, 0) self.lcd.write_string(text.decode('utf-8')) # Save so we can test if screen changed between calls, don't update if not needed to reduce LCD flicker self.prevStr = text
#LED 번갈아 깜빡 GPIO.output(21, True) time.sleep(0.1) GPIO.output(21, False) GPIO.output(26, True) time.sleep(0.1) GPIO.output(26, False) GPIO.output(21, True) time.sleep(0.1) GPIO.output(21, False) GPIO.output(26, True) time.sleep(0.1) GPIO.output(26, False) if intrusion_control == 0: #침범했으면 카메라on lcd.clear() camera.capture( "./camera/theif_face.jpg") #theif_face.jpg라는 카메라 찍고 lcd.write_string('MOON YOON JI') #LCD에 영문이름 출력 lcd.crlf() lcd.write_string('201835652') #LCD에 학번 출력 intrusion_control += 1 #침범상황에 신호이미 날렸다.는 의미 if GPIO.input(12) == False: #버튼을 누르면 모든걸 끝. print("button pressed") GPIO.cleanup() #LED & buzzer off lcd.clear() #LCD 문구 없애고 intrusion_control = 0 #침범상황 마무리한 상황 (다시 침범가능성on) time.sleep(1) break
#dht를 이용해 습도,온도를 측정하고 lcd 화면에 표시하는 실습. from RPLCD.i2c import CharLCD import Adafruit_DHT import time dht_type = 11 # DHT 타입 bcm_pin = 23 # 핀 번호 lcd = CharLCD('PCF8574',0x27) try: while True: time.sleep(3) lcd.clear() humidity, temperature = Adafruit_DHT.read_retry(dht_type, bcm_pin) #read_retry(sensor, pin) : DHT 센서의 값을 읽어옴. humid = str(round(humidity,1)) #습도 소수점 1째자리에서 올림하고 문자화(str) temp = str(round(temperature,1)) #온도 소수점 1째자리에서 올림하고 문자화(str) print(temp,humid) #콘솔에도 띄우기 lcd.write_string('TEMP ') lcd.write_string(temp) lcd.write_string('C ') # ex) TEMP 36C lcd.crlf() # 한줄 띄움. lcd.write_string('HUMID ') lcd.write_string(humid) lcd.write_string('% ') # ex) HUMID 80% except KeyboardInterrupt: lcd.clear() #프로그램 종료 시 LCD 화면의 문자를 지우고 커서 위치 원상복귀.
from RPLCD.i2c import CharLCD import time import datetime # python date module lcd = CharLCD('PCF8574', 0x27) try: while True: now = datetime.datetime.now() # current time nowDate = now.strftime('%Y-%m-%d') # today's date parsing nowTime = now.strftime('%H-%M:%S') # today's time parsing print(now, nowDate, nowTime) time.sleep(1) lcd.clear() lcd.cursor_pos = (0, 3) # Position to mark letters lcd.write_string(nowDate) lcd.crlf() lcd.cursor_pos = (1, 4) lcd.write_string(nowTime) except KeyboardInterrupt: lcd.clear() # LCD clean
class Cart: products = [] totalPrice = 0 def __init__(self, reader): self._reader = reader self._lcd = CharLCD('PCF8574', 0x27) def scan(self, continue_reading): try: while continue_reading: id, text = self._reader.read() text = text.strip() if (not self.checkIfItIsCard(text)): name, price = text.split() sendData = convertToRaw(id, name, price) client.send(sendData) isNewProduct = self.verifyProduct(id) product = Product(name, id, price) if isNewProduct: self.addProductToCart(product) else: self.removeProductFromCart(product) else: print('Your shopping is over') print() if (input('Do you want to pay? (y/n)') is 'y'): self.payProducts(text) break else: print('Your shopping is continuing') continue time.sleep(1.5) print('End') finally: GPIO.cleanup() def addProductToCart(self, product): self.products.append(product) self.totalPrice += int(product.price) print('The product: ' + product.name + 'was added to cart. Product price: ' + product.price) print('Total price so far: ' + str(self.totalPrice)) self.writeToLCD(product.name + ' added') def removeProductFromCart(self, product): self.remove(product.code) self.totalPrice -= int(product.price) print(product.name + ' was removed from the shopping cart') print('Total price so far: ' + str(self.totalPrice)) self.writeToLCD(product.name + ' removed') #iteram peste lista de produse -> daca gasim un produs cu id identic, il scoatem def verifyProduct(self, id): #if len(self.products) == 0: #return True for product in self.products: if product.code == id: #print('Product code: '+ str(product.code) + ', id: ' + str(id)) return False return True def remove(self, id): for product in self.products: if product.code == id: self.products.remove(product) def writeToLCD(self, text): self._lcd.clear() self._lcd.write_string(text) self._lcd.cursor_pos = (1, 0) self._lcd.write_string('Total: ') self._lcd.write_string(str(self.totalPrice)) def checkIfItIsCard(self, text): return str.isdigit(text) def payProducts(self, money): print('Thank you for shopping') #aici putem sa intrebam daca doreste sa faca plata money = int(money) money -= int(self.totalPrice) self._lcd.clear() self._lcd.write_string(str(money)) print(str(money))
from RPLCD.i2c import CharLCD #LCD문자 import import Adafruit_DHT #온도센서(DHT) import import RPi.GPIO as GPIO #LED import import time #LCD 설정 lcd = CharLCD('PCF8574', 0x27) #DHT 설정 dht_type = 11 #DHT 타입 bcm_pin = 23 #핀 번호 normal_temperature = 27 try: while True: time.sleep(3) lcd.clear() humidity, temperature = Adafruit_DHT.read_retry(dht_type, bcm_pin) humid = round(humidity, 1) #여기선 연산비교를 해야되서 str()하면 안됨. temp = round(temperature, 1) print(temp, humid) #초기 : 콘솔에 현재 온/습도 출력 GPIO.setmode(GPIO.BCM) #LED 설정 GPIO.setup(16, GPIO.OUT) #LED1 red if normal_temperature < temp: #일정 온도(27도)보다 높을 때 lcd.write_string('201835652') #학번 띄우고 lcd.crlf() lcd.write_string('Need Cooling') # 출력 GPIO.output(16, True) # LED1 red on else: #일정 온도 이하로 내려가면 GPIO.cleanup() #LED off lcd.write_string('Temp ') #현재 온/습도 띄우기
class Tv(): lcd = None status = False channel = 0 volume = 0 def __init__(self, addr=0x27, port=1, backlight=True): try: self.lcd = CharLCD('PCF8574', address=addr, port=port, backlight_enabled=backlight) self.status = False self.channel = CHANNEL_DEFAULT self.volume = VOLUME_DEFAULT except: self.lcd = None def getStatus(self): return self.status def getChannel(self): return self.channel def getVolume(self): return self.volume def setText(self, textLIST): if self.lcd is None: return False for text in textLIST: self.lcd.cursor_pos = (text["y"], text["x"]) self.lcd.write_string(text["text"]) return True def switch(self, status): if self.lcd is None: return False self.lcd.clear() self.status = status if status: return self.setText([{ "x": 0, "y": 0, "text": "Channel" }, { "x": 8, "y": 0, "text": "--->" }, { "x": 13, "y": 0, "text": f"{self.channel:03}" }, { "x": 0, "y": 1, "text": "Volume" }, { "x": 8, "y": 1, "text": "--->" }, { "x": 13, "y": 1, "text": f"{self.volume:03}" }]) else: return True def updateValue(self, mode): if self.lcd is None: return False if mode == "channel": return self.setText([{ "x": 13, "y": 0, "text": f"{self.channel:03}" }]) if mode == "volume": return self.setText([{ "x": 13, "y": 1, "text": f"{self.volume:03}" }]) return False def switchTo(self, mode, num): if self.lcd is None: return False if self.status: if mode == "channel": if num >= CHANNEL_MIN and num <= CHANNEL_MAX: self.channel = num return self.updateValue("channel") else: if num < CHANNEL_MIN: self.channel = CHANNEL_MAX return self.updateValue("cahnnel") if num > CHANNEL_MAX: self.channel = CHANNEL_MIN return self.updateValue("channel") return False if mode == "volume": if num >= VOLUME_MIN and num <= VOLUME_MAX: self.volume = num return self.updateValue("volume") else: return False return False def switchNext(self, mode, num=1): if self.lcd is None: return False if mode == "channel": return self.switchTo("channel", self.channel + num) if mode == "volume": return self.switchTo("volume", self.volume + num) return False def switchLast(self, mode, num=1): if self.lcd is None: return False if mode == "channel": return self.switchTo("channel", self.channel - num) if mode == "volume": return self.switchTo("volume", self.volume - num) return False
class lcd_mgr(): lcd = None framebuffer = ['', ''] num_cols = 16 #threads = [] t = None def __init__(self): self.lcd = CharLCD(i2c_expander='PCF8574', address=0x27, port=1, cols=16, rows=2, dotsize=8, charmap='A00', auto_linebreaks=True, backlight_enabled=True) self.framebuffer[0] = ' ' self.framebuffer[1] = ' ' self.lcd.clear() self.charset() def write_to_lcd(self): """Write the framebuffer out to the specified LCD.""" self.lcd.home() for row in self.framebuffer: self.lcd.write_string(row.ljust(self.num_cols)[:self.num_cols]) self.lcd.write_string('\r\n') def set_fb_str(self, row, col, txt): self.framebuffer[row] = self.framebuffer[ row][:col] + txt + self.framebuffer[row][col + len(txt):] def lcd_text(self, txt): self.set_fb_str(0, 0, txt) self.write_to_lcd() def lcd_play(self, artist, track, filename, tracknumber, tracktotal): #self.lcd_text( '{1}{2}/{3}'.format('\x00',tracknumber,tracktotal) ) self.set_fb_str(1, 0, '{0}{1}/{2}'.format('\x00', tracknumber, tracktotal)) # Various display modes: # 1) Artist - Trackname if not artist == None and not track == None: testtxt = '{0} - {1}'.format(artist, track) else: testtxt = filename self.lcd_text(testtxt) #not the right place to stop... stop at every display change... hmm, write_to_lcd?? #threads[0].stop() #self.t.stop() THREADS CAN'T BE STOPPED IN PYTHON!!! ---- multiprocessing ? asyncio ? if len(testtxt) > 16: #todo run under separate thread! (or atleast async..) self.loop_string(testtxt, 0, delay=0) time.sleep(2) self.lcd_text(testtxt) #self.t = threading.Thread(target=self.worker, args=(testtxt,)) #threads.append(t) #self.t.start() #self.worker( testtxt, 0, delay=0 ) def lcd_ding(self, bla): if bla == 'src_usb': self.set_fb_str(1, 1, 'USB') self.write_to_lcd() elif bla == 'update_on': self.set_fb_str(1, 5, 'UPD') self.write_to_lcd() elif bla == 'random_on': self.set_fb_str(1, 9, 'RND') self.write_to_lcd() elif bla == 'att_on': self.set_fb_str(1, 13, 'ATT') self.write_to_lcd() def worker(self, string): while True: self.loop_string(string, 0, delay=0) time.sleep(2) self.lcd_text(string) time.sleep(2) def loop_string(self, string, row, postfix='', delay=0.3): padding = ' ' * self.num_cols s = string for i in range(len(s) - self.num_cols + 1 + len(postfix)): self.framebuffer[row] = s[i:i + self.num_cols - len(postfix)] + postfix self.write_to_lcd() time.sleep(delay) def charset(self): """ chr_play = ( 0b10000, 0b11000, 0b11100, 0b11110, 0b11100, 0b11000, 0b10000, 0b00000 ) """ chr_play = (0b00000, 0b10000, 0b11000, 0b11100, 0b11000, 0b10000, 0b00000, 0b00000) chr_pause = (0b11011, 0b11011, 0b11011, 0b11011, 0b11011, 0b11011, 0b11011, 0b00000) chr_up = (0b00000, 0b00100, 0b01110, 0b11111, 0b00100, 0b00100, 0b00100, 0b00000) chr_down = (0b00000, 0b00100, 0b00100, 0b00100, 0b11111, 0b01110, 0b00100, 0b00000) chr_left = (0b00000, 0b00000, 0b00100, 0b01100, 0b11111, 0b01100, 0b00100, 0b00000) chr_right = (0b00000, 0b00000, 0b00100, 0b00110, 0b11111, 0b00110, 0b00100, 0b00000) self.lcd.create_char(0, chr_play) self.lcd.create_char(1, chr_pause) self.lcd.create_char(4, chr_up) self.lcd.create_char(5, chr_down) self.lcd.create_char(6, chr_left) self.lcd.create_char(7, chr_right)
class LcdManager: def __init__(self): self.lcd = CharLCD('PCF8574', 0x27) def setEnduroScreenByModel(self, enduroScreenModel): self.setEnduroScreen(enduroScreenModel.distanceMiles, enduroScreenModel.milesToNextPossable, enduroScreenModel.routeSpeed, enduroScreenModel.averageSpeed, enduroScreenModel.currentSpeed, enduroScreenModel.timeTotalSeconds, enduroScreenModel.paceTotalSeconds) def setEnduroScreen(self, distance, milesToNextPossable, routeSpeed, averageSpeed, currentSpeed, timeTotalSeconds, paceTotalSeconds): # knh todo - limit speed to 2 digits paceMinutes = int(abs(paceTotalSeconds / 60.0)) paceSeconds = int(abs(paceTotalSeconds % 60)) if paceTotalSeconds < 0: paceMinutes = floor(abs(paceTotalSeconds / 60.0)) paceSeconds = int(abs(paceTotalSeconds) % 60) if paceMinutes > 10: paceMinutes = 9 paceSeconds = 59 paceSign = "+" if paceTotalSeconds < 0: paceSign = "-" sys.stdout.write('paceTotalSeconds ' + str(paceTotalSeconds) + '\r\n') sys.stdout.write('paceMinutes ' + str(paceMinutes) + '\r\n') sys.stdout.write('paceSeconds ' + str(paceSeconds) + '\r\n') sys.stdout.write('\r\n') line1 = ("D{:5.2f} P{}{:01.0f}:{:02d} {:2.0f}\r\n".format( distance, paceSign, paceMinutes, paceSeconds, routeSpeed)) if averageSpeed > 99: averageSpeed = 99 line2 = "{:20.0f}\r\n".format(averageSpeed) timeMinutes = int(round(timeTotalSeconds / 60.0)) % 60 timeSeconds = int(round(timeTotalSeconds % 60)) milesToNextPossableAdjusted = milesToNextPossable if milesToNextPossable > 10: milesToNextPossableAdjusted = 9.9 if currentSpeed > 99: currentSpeed = 99 line3 = ("T {:02.0f}:{:02d} NP{:4.1f} {:4.0f}\r\n".format( timeMinutes, timeSeconds, milesToNextPossableAdjusted, currentSpeed)) # knh todo - get rounding correct # always round away from zero paceMarkerCount = int(ceil(abs(paceTotalSeconds / 15.0))) # We will display at most 9 pace chars if paceMarkerCount > 9: paceMarkerCount = 9 # we have 20 chars, those that are not pace markers are spaces paddCharCount = 20 - paceMarkerCount # if we are ahead with positive paceTotalSeconds, use A # if we are behaind with negative paceTotalSeconds, use B if paceTotalSeconds > 0: paceMarkerChar = "A" else: paceMarkerChar = "B" paceString = "" # build correct length pace String for i in range(1, paceMarkerCount): paceString += paceMarkerChar # build correct length padd string and place it on the correct side #if paceTotalSeconds > 0: if paceTotalSeconds > 0: paddString = "" for i in range(1, paddCharCount): paddString += " " paceString = paddString + paceString line4 = paceString + "\r\n" # sys.stdout.write(line1) # sys.stdout.write(line2) # sys.stdout.write(line3) # sys.stdout.write(line4) self.lcd.clear() self.lcd.write_string(line1) self.lcd.write_string(line2) self.lcd.write_string(line3) self.lcd.write_string(line4)