You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
261 lines
5.8 KiB
261 lines
5.8 KiB
#!/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] <files>'" |
|
|
|
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:]) |
|
|
|
|
|
|