#!/usr/bin/python3 import time import maestro from PIL import Image from PIL import ImageSequence import sys, getopt default_min = 7232 default_max = 4032 def create_display(s1, s2, s3): pixels = [ [ [s3, 8, 7232, 4032], [s3, 9], [s3, 10], [s3, 11], [s3, 12], [s3, 13], [s3, 14], [s3, 15], ], [ [s3, 0], [s3, 1], [s3, 2], [s3, 3], [s3, 4], [s3, 5], [s3, 6], [s3, 7], ], [ [s2, 16], [s2, 17], [s2, 18], [s2, 19], [s2, 20], [s2, 21], [s2, 22], [s2, 23], ], [ [s2, 8], [s2, 9], [s2, 10], [s2, 11], [s2, 12], [s2, 13], [s2, 14], [s2, 15], ], [ [s2, 0], [s2, 1], [s2, 2], [s2, 3], [s2, 4], [s2, 5], [s2, 6], [s2, 7], ], [ [s1, 16], [s1, 17], [s1, 18], [s1, 19], [s1, 20], [s1, 21], [s1, 22], [s1, 23], ], [ [s1, 8], [s1, 9], [s1, 10], [s1, 11], [s1, 12], [s1, 13], [s1, 14], [s1, 15], ], [ [s1, 0], [s1, 1], [s1, 2], [s1, 3], [s1, 4], [s1, 5], [s1, 6], [s1, 7], ] ] return display(pixels) class pixel: def __init__(self, servo, id, min=default_min, max=default_max): self.servo = servo self.id = id self.value = 0 self.dirty = True self.min = min self.max = max self.output() def set_min(self, value): self.min = value def set_max(self, value): self.max = value def set(self, value): if value < 0: value = 0 if value > 255: value = 255 if self.value != value: self.dirty = True self.value = value def get(self): return self.value def output(self): if self.dirty: value = ((self.max-self.min) * self.value / 255) + self.min #print('('+repr(self.id)+') '+repr(value)) if self.servo: self.servo.setTarget(self.id, int(round(value))) self.dirty = False def cal(self): self.servo.setTarget(self.id, 1500*4) class display: def __init__(self, params): self.p = [] for param_row in params: row = [] for args in param_row: row.append(pixel(*args)) self.p.append(row) def init(self, x, y, pixel): self.p[y][x] = pixel def set(self, x, y, value): self.p[y][x].set(value) def draw(self, im): for y, row in enumerate(self.p): for x, pixel in enumerate(row): pixel.set(im.getpixel((x, y))) def output(self): for row in self.p: for pixel in row: if pixel != None: pixel.output() def cal(self): for row in self.p: for pixel in row: if pixel != None: pixel.cal() def print(self): for row in self.p: s = "" for pixel in row: if pixel != None: if pixel.get() > 127: s += "X" else: s += " " print(s) print("") def slideshow(d, images, delay): for image in images: show(d, image) time.sleep(delay) def show(d, image): global viewmode print("Displaying " + repr(image)) im = Image.open(image) print(repr(im.info)) for frame in ImageSequence.Iterator(im): im8 = frame.convert("L") print(repr(frame.info)) if viewmode: im8.show() else: d.draw(im8) d.output() d.print() time.sleep(0.2) def test(d, value): print("Outputting "+repr(value)) for y in range(0,8): for x in range(0,8): d.set(x, y, value) d.output() baudrate = 115200 usage = "'pixel.py [-h] [-t] [-v] [-c] [-d delay] '" def main(argv): global viewmode delay = 10 testmode = False viewmode = False calmode = False try: opts, args = getopt.getopt(argv, "htvcd:", ["delay="]) except getopt.GetoptError: print(usage) sys.exit(2) for opt, arg in opts: if opt in ('-h', "--help"): print(usage) sys.exit() elif opt in ("-d", "--delay"): delay = arg elif opt in ("-t", "--test"): testmode = True elif opt in ("-v", "--view"): viewmode = True elif opt in ("-c", "--cal"): calmode = True d = None if not viewmode: try: s1 = maestro.Controller(device=0x0c, baud=baudrate) s2 = maestro.Controller(device=0x0d, baud=baudrate) s3 = maestro.Controller(device=0x0e, baud=baudrate) except: s1 = None s2 = None s3 = None d = create_display(s1, s2, s3) if calmode: d.cal() elif testmode: test(d, 0) time.sleep(1) test(d, 255) time.sleep(1) test(d, 0) else: slideshow(d, args, delay) if not viewmode: s3.close s2.close s1.close if __name__ == "__main__": main(sys.argv[1:])