Impractical electromechanical display
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

#!/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:])