diff --git a/host_python/README b/host_python/README new file mode 100644 index 0000000..ff3639b --- /dev/null +++ b/host_python/README @@ -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 diff --git a/host_python/demo.py b/host_python/demo.py new file mode 100755 index 0000000..929b445 --- /dev/null +++ b/host_python/demo.py @@ -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()) diff --git a/host_python/ledbar.py b/host_python/ledbar.py new file mode 100644 index 0000000..72fed7d --- /dev/null +++ b/host_python/ledbar.py @@ -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 diff --git a/host_python/rainbow.py b/host_python/rainbow.py new file mode 100755 index 0000000..36aa39c --- /dev/null +++ b/host_python/rainbow.py @@ -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 diff --git a/host_python/send_to_serial.py b/host_python/send_to_serial.py new file mode 100755 index 0000000..f9b4d3b --- /dev/null +++ b/host_python/send_to_serial.py @@ -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())