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.
262 lines
5.8 KiB
262 lines
5.8 KiB
7 years ago
|
#!/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:])
|
||
|
|
||
|
|