def create_character(fontpath, size, c, bypp, crop, bpp): try: from PIL import Image from PIL import ImageDraw from PIL import ImageFont from PIL import ImageChops except: # we will get respawn hopefully after python-PIL is loaded print 'failed to load PIL to create fonts, aborting...' import time time.sleep(3) exit(1) ifont = ImageFont.truetype(fontpath, size) size = ifont.getsize(c) image = Image.new('RGBA', size) draw = ImageDraw.Draw(image) draw.text((0, 0), c, font=ifont) if crop: bg = Image.new(image.mode, image.size, image.getpixel((0, 0))) diff = ImageChops.difference(image, bg) bbox = diff.getbbox() if bbox: image = image.crop(bbox) if bpp: data = list(image.getdata()) for i in range(len(data)): d = 255 / (1<<bpp) v = int(round(data[i][0] / (255 / (1<<bpp))) * (255 / ((1<<bpp)-1))) data[i] = (v,v,v,v) image.putdata(data) return ugfx.surface(image.size[0], image.size[1], bypp, image.tobytes())
def draw(surface, pos, text, size, bw, crop=False): if not size in fonts: fonts[size] = {} font = fonts[size] if pos: x, y = pos else: x, y = 0, 0 origx = x width = 0 lineheight = 0 height = 0 for c in text: if c == '\n': x = origx y += lineheight height += lineheight lineheight = 0 continue if not c in font: filename = fontpath + '/%03d%03d' % (size, ord(c)) if bw: filename += 'b' if crop: filename += 'c' #print 'ord', ord(c), filename font[c] = ugfx.surface(filename) if font[c].bypp == 0: font[c] = create_character( os.path.abspath(os.path.dirname(__file__)) + "/font.ttf", size, c, surface.bypp, crop, bw) font[c].store_grey(filename) if pos: surface.blit(font[c], x, y) x += font[c].width width = max(width, x - origx) lineheight = max(lineheight, font[c].height) return width, height + lineheight
def __init__(self, screen): # w, h, self.bw = 44, 84, 1 # w, h, self.bw = 64, 128, 1 # w, h, self.bw = 320, 480, 0 self.config = {} self.configfilename = os.getenv('HOME') + '/.pypilot/lcdclient.conf' self.config['contrast'] = 60 self.config['invert'] = False self.config['flip'] = False self.config['language'] = 'en' self.config['bigstep'] = 10 self.config['smallstep'] = 1 print 'loading load config file:', self.configfilename try: file = open(self.configfilename) config = json.loads(file.readline()) for name in config: self.config[name] = config[name] except: print 'failed to load config file:', self.configfilename if screen: w, h = screen.width, screen.height mul = int(math.ceil(w / 48.0)) self.bw = 1 if w < 256 else False width = min(w, 48*mul) self.surface = ugfx.surface(width, width*h/w, screen.bypp, None) self.frameperiod = .25 # 4 frames a second possible else: self.surface = None self.frameperiod = 1 self.set_language(self.config['language']) self.range_edit = False self.modes = {'compass': self.have_compass, 'gps': self.have_gps, 'wind': self.have_wind, 'true wind': self.have_true_wind}; self.modes_list = ['compass', 'gps', 'wind', 'true wind'] # in order self.initial_gets = gains + ['servo.min_speed', 'servo.max_speed', 'servo.max_current', 'servo.period', 'imu.alignmentCounter'] self.have_select = False self.create_mainmenu() self.longsleep = 30 self.display_page = self.display_connecting self.connecting_dots = 0 self.client = False self.keystate = {} self.keypad = [False, False, False, False, False, False, False, False] self.keypadup = list(self.keypad) self.blink = black, white self.control = False self.wifi = False self.overcurrent_time = 0 if orangepi: self.pins = [11, 16, 13, 15, 12] else: self.pins = [17, 23, 27, 22, 18] if GPIO: if orangepi: for pin in self.pins: cmd = 'gpio -1 mode ' + str(pin) + ' up' os.system(cmd) GPIO.setmode(GPIO.BOARD) else: GPIO.setmode(GPIO.BCM) for pin in self.pins: try: GPIO.setup(pin, GPIO.IN, pull_up_down=GPIO.PUD_UP) pass except RuntimeError: os.system("sudo chown tc /dev/gpiomem") GPIO.setup(pin, GPIO.IN, pull_up_down=GPIO.PUD_UP) def cbr(channel): self.longsleep = 0 GPIO.add_event_detect(pin, GPIO.BOTH, callback=cbr, bouncetime=20) global LIRC if LIRC: try: LIRC.init('pypilot') self.lirctime = False except: print 'failed to initialize lirc. is .lircrc missing?' LIRC = None
def main(): print 'init...' screen = None for arg in sys.argv: if 'nokia5110' in arg: sys.argv.remove(arg) print 'using nokia5110' screen = ugfx.nokia5110screen() if not screen: if use_glut: screen = glut.screen((120, 210)) #screen = glut.screen((64, 128)) #screen = glut.screen((48, 84)) else: screen = ugfx.screen("/dev/fb0") if screen.width == 416 and screen.height == 656: # no actual device or display print 'no actual screen, running headless' screen = None if screen.width > 480: screen.width = 480 screen.height= min(screen.height, 640) lcdclient = LCDClient(screen) if screen: # magnify to fill screen mag = min(screen.width / lcdclient.surface.width, screen.height / lcdclient.surface.height) if mag != 1: print "magnifying lcd surface to fit screen" magsurface = ugfx.surface(screen) invsurface = ugfx.surface(lcdclient.surface) def idle(): if screen: lcdclient.display() surface = lcdclient.surface if lcdclient.config['invert']: invsurface.blit(surface, 0, 0) surface = invsurface surface.invert(0, 0, surface.width, surface.height) if mag != 1: magsurface.magnify(surface, mag) surface = magsurface # mag = 2 #surface.magnify(mag) screen.blit(surface, 0, 0, lcdclient.config['flip']) screen.refresh() if 'contrast' in lcdclient.config: screen.contrast = int(lcdclient.config['contrast']) lcdclient.idle() if use_glut: from OpenGL.GLUT import glutMainLoop from OpenGL.GLUT import glutIdleFunc from OpenGL.GLUT import glutKeyboardFunc from OpenGL.GLUT import glutKeyboardUpFunc from OpenGL.GLUT import glutSpecialFunc from OpenGL.GLUT import glutSpecialUpFunc glutKeyboardFunc(lcdclient.glutkeydown) glutKeyboardUpFunc(lcdclient.glutkeyup) glutSpecialFunc(lcdclient.glutspecialdown) glutSpecialUpFunc(lcdclient.glutspecialup) glutIdleFunc(idle) # glutIgnoreKeyRepeat(True) glutMainLoop() else: while True: idle()
def __init__(self, hat): self.hat = hat self.config = hat.config['lcd'] default = { 'contrast': 60, 'invert': False, 'backlight': 200, 'flip': False, 'language': 'en', 'bigstep': 10, 'smallstep': 1, 'remote': False } for name in default: if not name in self.config: self.config[name] = default[name] # set the driver to the one from hat eeprom driver = 'default' if self.hat.hatconfig: driver = self.hat.hatconfig['lcd']['driver'] for pdriver in [ 'nokia5110', 'jlx12864', 'glut', 'framebuffer', 'none' ]: if pdriver in sys.argv: sys.argv.remove(pdriver) driver = pdriver break print('Using driver', driver) use_glut = 'DISPLAY' in os.environ self.use_glut = False if driver == 'none': screen = None elif driver == 'nokia5110' or (driver == 'default' and not use_glut): screen = ugfx.spiscreen(0) elif driver == 'jlx12864': screen = ugfx.spiscreen(1) elif driver == 'glut' or (driver == 'default' and use_glut): self.use_glut = True print('using glut') import glut #screen = glut.screen((120, 210)) #screen = glut.screen((64, 128)) screen = glut.screen((48, 84)) #screen = glut.screen((96, 168)) from OpenGL.GLUT import glutKeyboardFunc, glutKeyboardUpFunc from OpenGL.GLUT import glutSpecialFunc, glutSpecialUpFunc glutKeyboardFunc(self.glutkeydown) glutKeyboardUpFunc(self.glutkeyup) glutSpecialFunc(self.glutspecialdown) glutSpecialUpFunc(self.glutspecialup) # glutIgnoreKeyRepeat(True) elif driver == 'framebuffer': print('using framebuffer') screen = ugfx.screen("/dev/fb0") if screen.width > 480: screen.width = 480 screen.height = min(screen.height, 640) if screen: w, h = screen.width, screen.height mul = int(math.ceil(w / 48.0)) self.bw = 1 if w < 256 else False width = min(w, 48 * mul) self.surface = ugfx.surface(width, int(width * h / w), screen.bypp, None) # magnify to fill screen self.mag = min(screen.width / self.surface.width, screen.height / self.surface.height) if self.mag != 1: print('magnifying lcd surface to fit screen') self.magsurface = ugfx.surface(screen) self.invsurface = ugfx.surface(self.surface) self.frameperiod = .25 # 4 frames a second possible self.lastframetime = 0 else: self.surface = None self.frameperiod = 1 self.screen = screen self.set_language(self.config['language']) self.range_edit = False self.modes = { 'compass': self.have_compass, 'gps': self.have_gps, 'wind': self.have_wind, 'true wind': self.have_true_wind } self.modes_list = ['compass', 'gps', 'wind', 'true wind'] # in order self.watchlist = [ 'ap.enabled', 'ap.mode', 'ap.pilot', 'ap.heading_command', 'gps.source', 'wind.source', 'servo.controller', 'servo.flags', 'imu.compass.calibration', 'imu.compass.calibration.sigmapoints', 'imu.compass.calibration.locked', 'imu.alignmentQ', 'rudder.calibration_state' ] self.initial_gets = [ 'servo.speed.min', 'servo.speed.max', 'servo.max_current', 'servo.period', 'imu.alignmentCounter' ] self.create_mainmenu() self.display_page = self.display_control self.connecting_dots = 0 self.keypad = [False, False, False, False, False, False, False, False] self.keypadup = list(self.keypad) self.blink = black, white self.control = False # used to keep track of what is drawn on screen to avoid redrawing it self.wifi = False