From b81f2a512e1c9de4fc156802cb2608eff95d5445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Vinot?= Date: Wed, 24 Jun 2015 00:13:26 +0200 Subject: [PATCH] add multiple easy samples --- .../multiple_tests/data_generator.py | 136 ++++++++++++++++++ .../multiple_tests/multiple_tests.pyde | 81 +++++++++++ .../processing/multiple_tests/network.py | 36 +++++ .../processing/multiple_tests/prepare.py | 29 ++++ 4 files changed, 282 insertions(+) create mode 100644 v2/backend/processing/multiple_tests/data_generator.py create mode 100644 v2/backend/processing/multiple_tests/multiple_tests.pyde create mode 100644 v2/backend/processing/multiple_tests/network.py create mode 100644 v2/backend/processing/multiple_tests/prepare.py diff --git a/v2/backend/processing/multiple_tests/data_generator.py b/v2/backend/processing/multiple_tests/data_generator.py new file mode 100644 index 0000000..ac72e13 --- /dev/null +++ b/v2/backend/processing/multiple_tests/data_generator.py @@ -0,0 +1,136 @@ +import jarray +import math +import itertools +import time + +_byte_lookup = {} +brightness_max = 0.5 + +# Bit values which represent the zero and one bit pulses. +_ZERO = bytearray([0b00000000]) +_ONE = bytearray([0b11111111]) + +def _build_byte_lookup(): + """Return lookup table to map from every byte value 0-255 and the associated raw SPI data.""" + lookup = {} + for i in range(256): + value = bytearray() + for j in range(7, -1, -1): + if ((i >> j) & 1) == 0: + value += _ZERO + else: + value += _ONE + lookup[i] = value + return lookup + +def color_to_rgb(c): + """Convert a 24 bit color to RGB triplets.""" + return ((c >> 16) & 0xFF, (c >> 8) & 0xFF, c & 0xFF) + +def _encode_color_grb(c): + """Encode an RGB tuple into NeoPixel GRB 24 byte SPI bit stream.""" + return _byte_lookup[int(c[1] * brightness)] + _byte_lookup[int(c[0] * brightness)] + _byte_lookup[int(c[2] * brightness)] + +def _encode_pixel(c): + """Encode an RGB tuple into NeoPixel GRB 24 byte SPI bit stream.""" + rgb = color_to_rgb(c) + encoded = _encode_color_grb(rgb) + return encoded + +def prepare_data(dimension, b): + global brightness + global _byte_lookup + if b > brightness_max: + brightness = brightness_max + else: + brightness = b + _byte_lookup = _build_byte_lookup() + data = jarray.zeros(dimension * 24 + 1, "b") + return data + +''' +Possibilities: + Start: Top left / Top Right / Bottom Left / Bottom Right + Direction: Up / Down / Right / Left +''' + + +def make_line(type, nb, long_line): + ''' + If moving up or down: 0 <= nb < height + If moving right or left: 0 <= nb < width + ''' + indexes = [] + if type == 0: + # top left -> down / OK + pxstart = nb + for h in range(height): + indexes.append(pxstart + width * h) + elif type == 1: + # top left -> right / OK + pxstart = nb * width + for w in range(width): + indexes.append(pxstart + w) + elif type == 2: + # bottom left -> up / OK + pxstart = width * (height - 1) + nb + for h in range(height): + indexes.append(pxstart - width * h) + elif type == 3: + # bottom left -> right / OK + pxstart = width * (height - 1) - nb * width + for w in range(width): + indexes.append(pxstart + w) + elif type == 4: + # top right -> down / OK + pxstart = width - 1 - nb + for h in range(height): + indexes.append(pxstart + width * h) + elif type == 5: + # top right -> left / OK + pxstart = width - 1 + nb * width + for w in range(width): + indexes.append(pxstart - w) + elif type == 6: + # bottom right -> up / OK + pxstart = width * height - 1 - nb * height + for h in range(height): + indexes.append(pxstart - width * h) + elif type == 7: + # bottom right -> left / OK + pxstart = width * height - 1 - nb * width + for w in range(width): + indexes.append(pxstart - w) + else: + raise Exception("Invalid Type") + + if long_line and nb % 2 == 1: + return reversed([pixels[px] for px in indexes]) + return [pixels[px] for px in indexes] + + +def image2data(data, type, long_line): + offset = 0 + loadPixels() + inline_image = [] + if type in [0, 2, 4, 6]: + # Organized up or down + for x in range(0, width): + inline_image += make_line(type, x, long_line) + elif type in [1, 3, 5, 7]: + # Organized left or right + for x in range(0, height): + inline_image += make_line(type, x, long_line) + for img_px in inline_image: + py_bytes = _encode_pixel(img_px) + for b in py_bytes: + if b > 127: + # Convert to signed bytes (expected by jarray) + b -= 256 + data[offset] = b + else: + data[offset] = b + offset += 1 + # New line + data[-1] = 10 + return data diff --git a/v2/backend/processing/multiple_tests/multiple_tests.pyde b/v2/backend/processing/multiple_tests/multiple_tests.pyde new file mode 100644 index 0000000..63cf048 --- /dev/null +++ b/v2/backend/processing/multiple_tests/multiple_tests.pyde @@ -0,0 +1,81 @@ +""" +Saturation. + +Saturation is the strength or purity of the color and represents the +amount of gray in proportion to the hue. A "saturated" color is pure +and an "unsaturated" color has a large percentage of gray. +Move the cursor vertically over each bar to alter its saturation. +""" + +add_library('net') +from network import send_TCP +from prepare import prepare +import random + +# Config, will be checked upstream +height = 8 +width = 32 +framerate = 10 +brightness = 0.05 +##################################### +receiver_IP = "10.2.113.211" +#receiver_IP = "dummy" +receiver_port = 9999 + +# Do we have one single long line? +long_line = True +# Type of installation (see details in data_generator) +type = 0 + +ledTCP = None +data = None + +barWidth = 1 + + +def setup(): + global ledTCP + global data + # for the text example + global f + size(width, height) + colorMode(HSB, width, height, 100) + frameRate(framerate) + + # For the text examples + f = createFont("Comic", 5, True) + ledTCP, data = prepare(Client, receiver_IP, receiver_port, height, width, framerate, brightness) + send_TCP(ledTCP, data, long_line, type) + +def line_mouse(): + whichBar = mouseX / barWidth + barX = whichBar * barWidth + fill(barX, mouseY, random.randint(0, 255)) + rect(barX, 0, barWidth, height) + +def ellipse_mouse(): + if mousePressed: + fill(150) + else: + fill(0) + ellipse(mouseX, mouseY, 2, 2) + +def draw_text(): + textFont(f,8) + textAlign(CENTER) + text("Level 2", width/2, 7) + +def advanced_text(): + noStroke(); + smooth(); + x = 1 + background(100) + message = "Level2" + for i in range(len(message)): + textSize(random.randint(6, 8)) + text(message[i], x, height - 1) + x += textWidth(message[i]) + 1 + +def draw(): + advanced_text() + send_TCP(ledTCP, data, long_line, type) diff --git a/v2/backend/processing/multiple_tests/network.py b/v2/backend/processing/multiple_tests/network.py new file mode 100644 index 0000000..c271e3a --- /dev/null +++ b/v2/backend/processing/multiple_tests/network.py @@ -0,0 +1,36 @@ +import jarray +import time +import struct +from data_generator import image2data + +def TCPConfigure(cl_class, server, port): + return cl_class(this, server, port) + +def receive_config(socket): + max_height = jarray.zeros(4, "b") + max_width = jarray.zeros(4, "b") + max_framerate = jarray.zeros(4, "b") + while True: + available_bytes = socket.available() + if available_bytes > 0: + break + time.sleep(1) + socket.readBytes(max_height) + socket.readBytes(max_width) + socket.readBytes(max_framerate) + max_height = struct.unpack(" max_height: + return False, "height cannot be higher than {}. Current: {}.".format(max_height, height) + if width <= 0 or width > max_width: + return False, "width cannot be higher than {}. Current: {}.".format(max_width, width) + if framerate <= 0 or framerate > max_framerate: + return False, "framerate cannot be higher than {}. Current: {}.".format(max_framerate, framerate) + return True, None + +def prepare(cl_class, server_ip, server_port, height, width, framerate, brightness): + # Just to make sure pixels[] is initialized. + if server_ip == 'dummy': + size(width, height) + loadPixels() + return None, None + ledTCP = TCPConfigure(cl_class, server_ip, server_port) + max_height, max_width, max_framerate = receive_config(ledTCP) + good, reason = check_config(max_height, max_width, max_framerate, height, width, framerate) + if not good: + raise Exception(reason) + send_config(ledTCP, height, width, framerate) + size(width, height) + loadPixels() + dimension = width * height + data = prepare_data(dimension, brightness) + return ledTCP, data