Merge pull request #2 from k21/dev-python

Added Python scripts to controll the ledbar
This commit is contained in:
Thomas Mudrunka 2011-09-21 18:02:52 -07:00
commit a872406927
5 changed files with 254 additions and 0 deletions

26
host_python/README Normal file
View file

@ -0,0 +1,26 @@
INTRODUCTION:
The scripts in this directory try to work according to the KISS principle. It
contains a script which redirects its stdin to serial device
(send_to_serial.py), one that simulates the ledbar and sends the data unaltered
from its stdin to its stdout, a module that helps programmers to program
various graphical effects and some example effect generators using this module.
EXAMPLES:
./rainbow.py | ./demo.py >/dev/null
- only simulate the rainbow effect, do not send it anywhere
./rainbow.py | ./send_to_serial.py
- only send the data to the serial device, do not show the simulation
./rainbow.py | ./demo.py | ./send_to_serial.py
- combine both options, show a simulation and send the data to the serial
device
DEPENDENCIES:
demo.py requires PyGame, Python wrapper around SDL
send_to_serial.py requires PySerial, Python library for work with serial ports

75
host_python/demo.py Executable file
View file

@ -0,0 +1,75 @@
#!/usr/bin/python
# vim:et:sw=4:ts=4:sts=4
import sys
import getopt
import pygame
def print_usage():
print '''\
USAGE:
%s [-n number] [-h]
OPTIONS:
-n number number of controlled boxes
-h --help show this help
''' % sys.argv[0]
def read_byte():
r = sys.stdin.read(1)
if len(r) == 0: raise EOFError
return ord(r)
def write_byte(b):
sys.stdout.write(chr(b))
def main():
try:
opts, args = getopt.getopt(sys.argv[1:], 'n:h', ['help'])
except getopt.GetOptError:
print_usage()
return 1
if len(args):
print_usage()
return 1
number = 10
show_help = False
for k, v in opts:
if k == '-n':
if not v.isdigit():
print_usage()
return 1
number = int(v)
elif k == '-h' or k == '--help': show_help = True
if show_help:
print_usage()
return 0
pygame.init()
screen_size = [800, 600]
screen = pygame.display.set_mode(screen_size)
pygame.display.set_caption("ledbar demo viewer")
offset = 5
pixel_width = (screen_size[0]-offset) / number
try:
exit = False
while not exit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit = True
continue
screen.fill([0, 0, 0])
for i in xrange(number):
r = read_byte()
g = read_byte()
b = read_byte()
pygame.draw.rect(screen, [r, g, b], [pixel_width*i, 0, pixel_width-offset, pixel_width-offset])
write_byte(r); write_byte(g); write_byte(b)
pygame.display.flip()
except EOFError:
pass
finally:
pygame.quit()
return 0
sys.exit(main())

50
host_python/ledbar.py Normal file
View file

@ -0,0 +1,50 @@
#!/usr/bin/python
# vim:et:sw=4:ts=4:sts=4
import sys
import time
class Ledbar:
def __init__(self, boxes=10, secs_per_frame=0.025):
self.boxes = boxes
self.secs_per_frame = secs_per_frame
self.last_update = time.time()
self.pixels = []
for i in xrange(boxes):
self.pixels.append([0, 0, 0])
def set_pixel(self, pixel, red, green, blue):
self.set_red(pixel, red)
self.set_green(pixel, green)
self.set_blue(pixel, blue)
def set_red(self, pixel, red):
if red < 0.0 or red > 1.0: raise ValueError('red has to be between 0.0 and 1.0')
self.pixels[pixel][0] = int(red*255.99)
def set_green(self, pixel, green):
if green < 0.0 or green > 1.0: raise ValueError('green has to be between 0.0 and 1.0')
self.pixels[pixel][1] = int(green*255.99)
def set_blue(self, pixel, blue):
if blue < 0.0 or blue > 1.0: raise ValueError('blue has to be between 0.0 and 1.0')
self.pixels[pixel][2] = int(blue*255.99)
def echo(self, s, no_newline=False):
sys.stderr.write(str(s) + ('' if no_newline else '\n'))
def update(self):
now = time.time()
delta = now - self.last_update
if delta < self.secs_per_frame:
time.sleep(self.secs_per_frame - delta)
try:
for p in self.pixels:
for c in p:
sys.stdout.write(chr(c))
sys.stdout.flush()
except IOError:
return False
self.last_update += self.secs_per_frame
return True

33
host_python/rainbow.py Executable file
View file

@ -0,0 +1,33 @@
#!/usr/bin/python
# vim:et:sw=4:ts=4:sts=4
import sys
from ledbar import Ledbar
PIXELS = 10
def update(t, i):
offset = float(i)/PIXELS
time = 0.005*t
phi = 6*offset+time
phase = int(phi%6)
part = phi % 1.0
inc = part
dec = 1-part
if phase == 0: return ( 1, inc, 0)
elif phase == 1: return (dec, 1, 0)
elif phase == 2: return ( 0, 1, inc)
elif phase == 3: return ( 0, dec, 1)
elif phase == 4: return (inc, 0, 1)
elif phase == 5: return ( 1, 0, dec)
l = Ledbar(PIXELS)
t = 0
work = True
while work:
for i in xrange(PIXELS):
c = update(t, i)
l.set_pixel(i, c[0], c[1], c[2])
work = l.update()
t += 1

70
host_python/send_to_serial.py Executable file
View file

@ -0,0 +1,70 @@
#!/usr/bin/python
# vim:et:sw=4:ts=4:sts=4
import sys
import serial
import getopt
def print_usage():
print '''\
USAGE:
%s [-h | [-n number] [-b speed] serial]
OPTIONS:
serial write output to serial device
-b speed speed of the serial device
-n number number of controlled boxes
-h --help show this help
''' % sys.argv[0]
def main():
try:
opts, args = getopt.getopt(sys.argv[1:], 's:b:n:h', ['help'])
except getopt.GetOptError:
print_usage()
return 1
speed = 38400
number = 10
show_help = False
for k, v in opts:
if k == '-n':
if not v.isdigit():
print_usage()
return 1
number = int(v)
elif k == '-b':
if not v.isdigit():
print_usage()
return 1
speed = int(v)
elif k == '-h' or k == '--help': show_help = True
if show_help:
print_usage()
return 0
if len(args) != 1:
print_usage()
return 1
try:
output_stream = serial.Serial(args[0], speed)
except serial.serialutil.SerialException:
print 'Could not open the serial device'
return 1
try:
while True:
data = ''
to_read = number*3
while to_read > 0:
read = sys.stdin.read(to_read)
if len(read) == 0: break
to_read -= len(read)
data += read
if len(read) == 0: break
output_stream.write(data)
output_stream.flush()
except IOError:
pass
return 0
sys.exit(main())