Python scripting - Digital LED lights

Soldato
Joined
28 Sep 2004
Posts
3,128
Location
Devon, UK
Hi there,

Can anyone help me with some Python scripting language for some digital led lights?

I've looked over it but really don't understand it much, tried taking some bits out and altering it but it doesn't seem to do what I want.

I basically want to change or make a chase setting. But where the LEDs come on one by one and stay lit for X amount of time. Where I can change how quickly they come on and choose the colour aswell.

I don't have to use thid particular code if someone knows something different which will work?

Here is the full script

Code:
import argparse
import csv
import socket
import time

try:
    import cwiid
    CWIID_ENABLED = True
except ImportError:
    CWIID_ENABLED = False
import Image


# 3 bytes per pixel
PIXEL_SIZE = 3
PIXEL_SIZE_SM16716 = 4

# My chips are not working if you send all bits with zero (just the first led is turning off)
# Change the value if pure black is working for you. Or use filter_pixel(BLACK, 1)
SM16716BLACK = bytearray(b'\x01\x01\x01\x01')

BLACK = bytearray(b'\x00\x00\x00')
AQUA = bytearray(b'\x00\xff\xff')
AQUAMARINE = bytearray(b'\x7f\xff\xd4')
AZURE = bytearray(b'\xf0\xff\xff')
BEIGE = bytearray(b'\xf5\xf5\xdc')
BISQUE = bytearray(b'\xff\xe4\xc4')
BLANCHEDALMOND = bytearray(b'\xff\xeb\xcd')
BLUE = bytearray(b'\x00\x00\xff')
BLUEVIOLET = bytearray(b'\x8a\x2b\xe2')
BROWN = bytearray(b'\xa5\x2a\x2a')
BURLYWOOD = bytearray(b'\xde\xb8\x87')
CADETBLUE = bytearray(b'\x5f\x9e\xa0')
CHARTREUSE = bytearray(b'\x7f\xff\x00')
CHOCOLATE = bytearray(b'\xd2\x69\x1e')
CORAL = bytearray(b'\xff\x7f\x50')
CORNFLOWERBLUE = bytearray(b'\x64\x95\xed')
CORNSILK = bytearray(b'\xff\xf8\xdc')
CRIMSON = bytearray(b'\xdc\x14\x3c')
CYAN = bytearray(b'\x00\xff\xff')
DARKBLUE = bytearray(b'\x00\x00\x8b')
DARKCYAN = bytearray(b'\x00\x8b\x8b')
DARKGOLDENROD = bytearray(b'\xb8\x86\x0b')
DARKGRAY = bytearray(b'\xa9\xa9\xa9')
DARKGREY = bytearray(b'\xa9\xa9\xa9')
DARKGREEN = bytearray(b'\x00\x64\x00')
DARKKHAKI = bytearray(b'\xbd\xb7\x6b')
DARKMAGENTA = bytearray(b'\x8b\x00\x8b')
DARKOLIVEGREEN = bytearray(b'\x55\x6b\x2f')
DARKORANGE = bytearray(b'\xff\x8c\x00')
DARKORCHID = bytearray(b'\x99\x32\xcc')
DARKRED = bytearray(b'\x8b\x00\x00')
DARKSALMON = bytearray(b'\xe9\x96\x7a')
DARKSEAGREEN = bytearray(b'\x8f\xbc\x8f')
DARKSLATEBLUE = bytearray(b'\x48\x3d\x8b')
DARKSLATEGRAY = bytearray(b'\x2f\x4f\x4f')
DARKSLATEGREY = bytearray(b'\x2f\x4f\x4f')
DARKTURQUOISE = bytearray(b'\x00\xce\xd1')
DARKVIOLET = bytearray(b'\x94\x00\xd3')
DEEPPINK = bytearray(b'\xff\x14\x93')
DEEPSKYBLUE = bytearray(b'\x00\xbf\xff')
DIMGRAY = bytearray(b'\x69\x69\x69')
DIMGREY = bytearray(b'\x69\x69\x69')
DODGERBLUE = bytearray(b'\x1e\x90\xff')
FIREBRICK = bytearray(b'\xb2\x22\x22')
FLORALWHITE = bytearray(b'\xff\xfa\xf0')
FORESTGREEN = bytearray(b'\x22\x8b\x22')
FUCHSIA = bytearray(b'\xff\x00\xff')
GAINSBORO = bytearray(b'\xdc\xdc\xdc')
GHOSTWHITE = bytearray(b'\xf8\xf8\xff')
GOLD = bytearray(b'\xff\xd7\x00')
GOLDENROD = bytearray(b'\xda\xa5\x20')
GRAY = bytearray(b'\x80\x80\x80')
GREY = bytearray(b'\x80\x80\x80')
GREEN = bytearray(b'\x00\x80\x00')
GREENYELLOW = bytearray(b'\xad\xff\x2f')
HONEYDEW = bytearray(b'\xf0\xff\xf0')
HOTPINK = bytearray(b'\xff\x69\xb4')
INDIANRED = bytearray(b'\xcd\x5c\x5c')
INDIGO = bytearray(b'\x4b\x00\x82')
IVORY = bytearray(b'\xff\xff\xf0')
KHAKI = bytearray(b'\xf0\xe6\x8c')
LAVENDER = bytearray(b'\xe6\xe6\xfa')
LAVENDERBLUSH = bytearray(b'\xff\xf0\xf5')
LAWNGREEN = bytearray(b'\x7c\xfc\x00')
LEMONCHIFFON = bytearray(b'\xff\xfa\xcd')
LIGHTBLUE = bytearray(b'\xad\xd8\xe6')
LIGHTCORAL = bytearray(b'\xf0\x80\x80')
LIGHTCYAN = bytearray(b'\xe0\xff\xff')
LIGHTGOLDENRODYELLOW = bytearray(b'\xfa\xfa\xd2')
LIGHTGRAY = bytearray(b'\xd3\xd3\xd3')
LIGHTGREY = bytearray(b'\xd3\xd3\xd3')
LIGHTGREEN = bytearray(b'\x90\xee\x90')
LIGHTPINK = bytearray(b'\xff\xb6\xc1')
LIGHTSALMON = bytearray(b'\xff\xa0\x7a')
LIGHTSEAGREEN = bytearray(b'\x20\xb2\xaa')
LIGHTSKYBLUE = bytearray(b'\x87\xce\xfa')
LIGHTSLATEGRAY = bytearray(b'\x77\x88\x99')
LIGHTSLATEGREY = bytearray(b'\x77\x88\x99')
LIGHTSTEELBLUE = bytearray(b'\xb0\xc4\xde')
LIGHTYELLOW = bytearray(b'\xff\xff\xe0')
LIME = bytearray(b'\x00\xff\x00')
LIMEGREEN = bytearray(b'\x32\xcd\x32')
LINEN = bytearray(b'\xfa\xf0\xe6')
MAGENTA = bytearray(b'\xff\x00\xff')
MAROON = bytearray(b'\x80\x00\x00')
MEDIUMAQUAMARINE = bytearray(b'\x66\xcd\xaa')
MEDIUMBLUE = bytearray(b'\x00\x00\xcd')
MEDIUMORCHID = bytearray(b'\xba\x55\xd3')
MEDIUMPURPLE = bytearray(b'\x93\x70\xd8')
MEDIUMSEAGREEN = bytearray(b'\x3c\xb3\x71')
MEDIUMSLATEBLUE = bytearray(b'\x7b\x68\xee')
MEDIUMSPRINGGREEN = bytearray(b'\x00\xfa\x9a')
MEDIUMTURQUOISE = bytearray(b'\x48\xd1\xcc')
MEDIUMVIOLETRED = bytearray(b'\xc7\x15\x85')
MIDNIGHTBLUE = bytearray(b'\x19\x19\x70')
MINTCREAM = bytearray(b'\xf5\xff\xfa')
MISTYROSE = bytearray(b'\xff\xe4\xe1')
MOCCASIN = bytearray(b'\xff\xe4\xb5')
NAVAJOWHITE = bytearray(b'\xff\xde\xad')
NAVY = bytearray(b'\x00\x00\x80')
OLDLACE = bytearray(b'\xfd\xf5\xe6')
OLIVE = bytearray(b'\x80\x80\x00')
OLIVEDRAB = bytearray(b'\x6b\x8e\x23')
ORANGE = bytearray(b'\xff\xa5\x00')
ORANGERED = bytearray(b'\xff\x45\x00')
ORCHID = bytearray(b'\xda\x70\xd6')
PALEGOLDENROD = bytearray(b'\xee\xe8\xaa')
PALEGREEN = bytearray(b'\x98\xfb\x98')
PALETURQUOISE = bytearray(b'\xaf\xee\xee')
PALEVIOLETRED = bytearray(b'\xd8\x70\x93')
PAPAYAWHIP = bytearray(b'\xff\xef\xd5')
PEACHPUFF = bytearray(b'\xff\xda\xb9')
PERU = bytearray(b'\xcd\x85\x3f')
PINK = bytearray(b'\xff\xc0\xcb')
PLUM = bytearray(b'\xdd\xa0\xdd')
POWDERBLUE = bytearray(b'\xb0\xe0\xe6')
PURPLE = bytearray(b'\x80\x00\x80')
RED = bytearray(b'\xff\x00\x00')
ROSYBROWN = bytearray(b'\xbc\x8f\x8f')
ROYALBLUE = bytearray(b'\x41\x69\xe1')
SADDLEBROWN = bytearray(b'\x8b\x45\x13')
SALMON = bytearray(b'\xfa\x80\x72')
SANDYBROWN = bytearray(b'\xf4\xa4\x60')
SEAGREEN = bytearray(b'\x2e\x8b\x57')
SEASHELL = bytearray(b'\xff\xf5\xee')
SIENNA = bytearray(b'\xa0\x52\x2d')
SILVER = bytearray(b'\xc0\xc0\xc0')
SKYBLUE = bytearray(b'\x87\xce\xeb')
SLATEBLUE = bytearray(b'\x6a\x5a\xcd')
SLATEGRAY = bytearray(b'\x70\x80\x90')
SLATEGREY = bytearray(b'\x70\x80\x90')
SNOW = bytearray(b'\xff\xfa\xfa')
SPRINGGREEN = bytearray(b'\x00\xff\x7f')
STEELBLUE = bytearray(b'\x46\x82\xb4')
TAN = bytearray(b'\xd2\xb4\x8c')
TEAL = bytearray(b'\x00\x80\x80')
THISTLE = bytearray(b'\xd8\xbf\xd8')
TOMATO = bytearray(b'\xff\x63\x47')
TURQUOISE = bytearray(b'\x40\xe0\xd0')
VIOLET = bytearray(b'\xee\x82\xee')
WHEAT = bytearray(b'\xf5\xde\xb3')
WHITE = bytearray(b'\xff\xff\xff')
WHITESMOKE = bytearray(b'\xf5\xf5\xf5')
YELLOW = bytearray(b'\xff\xff\x00')
YELLOWGREEN = bytearray(b'\x9a\xcd\x32')
RAINBOW = [AQUA, AQUAMARINE, AZURE, BEIGE, BISQUE, BLANCHEDALMOND, BLUE, BLUEVIOLET, BROWN, BURLYWOOD, CADETBLUE, CHARTREUSE, CHOCOLATE, CORAL, CORNFLOWERBLUE, CORNSILK, CRIMSON, CYAN, DARKBLUE, DARKCYAN, DARKGOLDENROD, DARKGRAY, DARKGREY, DARKGREEN, DARKKHAKI, DARKMAGENTA, DARKOLIVEGREEN, DARKORANGE, DARKORCHID, DARKRED, DARKSALMON, DARKSEAGREEN, DARKSLATEBLUE, DARKSLATEGRAY, DARKSLATEGREY, DARKTURQUOISE, DARKVIOLET, DEEPPINK, DEEPSKYBLUE, DIMGRAY, DIMGREY, DODGERBLUE, FIREBRICK, FLORALWHITE, FORESTGREEN, FUCHSIA, GAINSBORO, GHOSTWHITE, GOLD, GOLDENROD, GRAY, GREY, GREEN, GREENYELLOW, HONEYDEW, HOTPINK, INDIANRED, INDIGO, IVORY, KHAKI, LAVENDER, LAVENDERBLUSH, LAWNGREEN, LEMONCHIFFON, LIGHTBLUE, LIGHTCORAL, LIGHTCYAN, LIGHTGOLDENRODYELLOW, LIGHTGRAY, LIGHTGREY, LIGHTGREEN, LIGHTPINK, LIGHTSALMON, LIGHTSEAGREEN, LIGHTSKYBLUE, LIGHTSLATEGRAY, LIGHTSLATEGREY, LIGHTSTEELBLUE, LIGHTYELLOW, LIME, LIMEGREEN, LINEN, MAGENTA, MAROON, MEDIUMAQUAMARINE, MEDIUMBLUE, MEDIUMORCHID, MEDIUMPURPLE, MEDIUMSEAGREEN, MEDIUMSLATEBLUE, MEDIUMSPRINGGREEN, MEDIUMTURQUOISE, MEDIUMVIOLETRED, MIDNIGHTBLUE, MINTCREAM, MISTYROSE, MOCCASIN, NAVAJOWHITE, NAVY, OLDLACE, OLIVE, OLIVEDRAB, ORANGE, ORANGERED, ORCHID, PALEGOLDENROD, PALEGREEN, PALETURQUOISE, PALEVIOLETRED, PAPAYAWHIP, PEACHPUFF, PERU, PINK, PLUM, POWDERBLUE, PURPLE, RED, ROSYBROWN, ROYALBLUE, SADDLEBROWN, SALMON, SANDYBROWN, SEAGREEN, SEASHELL, SIENNA, SILVER, SKYBLUE, SLATEBLUE, SLATEGRAY, SLATEGREY, SNOW, SPRINGGREEN, STEELBLUE, TAN, TEAL, THISTLE, TOMATO, TURQUOISE, VIOLET, WHEAT, WHITE, WHITESMOKE, YELLOW, YELLOWGREEN, YELLOWGREEN]
#RAINBOW = [RED, GREEN, BLUE, YELLOW, VIOLET, ORANGE, GRAY, OLIVE, BROWN]


def write_stream(pixels):
    if args.chip_type == "LPD6803":
        pixel_out_bytes = bytearray(2)
        spidev.write(bytearray(4))
        pixel_count = len(pixels) / PIXEL_SIZE
        for pixel_index in range(pixel_count):

            pixel_in = bytearray(pixels[(pixel_index * PIXEL_SIZE):((pixel_index * PIXEL_SIZE) + PIXEL_SIZE)])

            pixel_out = 0b1000000000000000  # bit 16 must be ON
            pixel_out |= (pixel_in[0] & 0x00F8) << 7  # RED is bits 11-15
            pixel_out |= (pixel_in[1] & 0x00F8) << 2  # GREEN is bits 6-10
            pixel_out |= (pixel_in[2] & 0x00F8) >> 3  # BLUE is bits 1-5

            pixel_out_bytes[0] = (pixel_out & 0xFF00) >> 8
            pixel_out_bytes[1] = (pixel_out & 0x00FF) >> 0
            spidev.write(pixel_out_bytes)
        spidev.write(bytearray(len(pixels) / 8 + 1))
    elif args.chip_type == "LPD8806":
        spidev.write(pixels)
        spidev.write(bytearray(b'\x00\x00\x00'))  # zero fill the last to prevent stray colors at the end
        spidev.write(bytearray(b'\x00'))
    elif args.chip_type == "SM16716":
        #Each frame for SM17616 starts with 50bits set to '0'
        #Also every pixel needs to start with a bit set to '1'
        spidev.write(bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') + pixels)
    else:
        spidev.write(pixels)

    return


def correct_pixel_brightness(pixel):
    corrected_pixel = bytearray(3)
    corrected_pixel[0] = int(pixel[0] / 1.1)
    corrected_pixel[1] = int(pixel[1] / 1.1)
    corrected_pixel[2] = int(pixel[2] / 1.3)

    return corrected_pixel


def pixelinvaders():
    print ("Start PixelInvaders listener " + args.UDP_IP + ":" + str(args.UDP_PORT))
    sock = socket.socket(socket.AF_INET,  # Internet
                      socket.SOCK_DGRAM)  # UDP
    sock.bind((args.UDP_IP, args.UDP_PORT))
    UDP_BUFFER_SIZE = 1024
    while True:
        data, addr = sock.recvfrom(UDP_BUFFER_SIZE)  # blocking call

        pixels_in_buffer = len(data) / PIXEL_SIZE

        if args.chip_type == "SM16716":
            pixels = bytearray(pixels_in_buffer * PIXEL_SIZE_SM16716)
        else:
            pixels = bytearray(pixels_in_buffer * PIXEL_SIZE)

        for pixel_index in range(pixels_in_buffer):
            pixel_to_adjust = bytearray(data[(pixel_index * PIXEL_SIZE):((pixel_index * PIXEL_SIZE) + PIXEL_SIZE)])

            pixel_to_filter = correct_pixel_brightness(pixel_to_adjust)
            if args.chip_type == "SM16716":
                pixels[((pixel_index) * PIXEL_SIZE_SM16716):] = filter_pixel(pixel_to_filter[:], 1)  # for every starting pixel a bit set to '1'
            else:
                pixels[((pixel_index) * PIXEL_SIZE):] = filter_pixel(pixel_to_filter[:], 1)

        write_stream(pixels)
        spidev.flush()


def strip():
    img = Image.open(args.filename).convert("RGB")
    input_image = img.load()
    image_width = img.size[0]
    print "%dx%d pixels" % img.size
    # Create bytearray for the entire image
    # R, G, B byte per pixel, plus extra '0' byte at end for latch.
    print "Allocating..."
    column = [0 for x in range(image_width)]
    for x in range(image_width):
        if args.chip_type == "SM16716":
            column[x] = bytearray(args.array_height * PIXEL_SIZE_SM16716)
        else:
            column[x] = bytearray(args.array_height * PIXEL_SIZE + 1)

    print "Process Image..."
    for x in range(image_width):
        for y in range(args.array_height):
            value = input_image[x, y]
            y3 = y * 3
            if args.chip_type == "LPD8806":
                # Convert RGB into column-wise GRB bytearray list.
                column[x][y3] = gamma[value[1]]
                column[x][y3 + 1] = gamma[value[0]]
                column[x][y3 + 2] = gamma[value[2]]
            elif args.chip_type == "SM16716":
                column[x][y3] = b'\x01'
                column[x][y3 + 1] = value[0]
                column[x][y3 + 2] = value[1]
                column[x][y3 + 3] = value[2]
            else:
                column[x][y3] = value[0]
                column[x][y3 + 1] = value[1]
                column[x][y3 + 2] = value[2]

    print "Displaying..."
    while True:
        for x in range(image_width):
            write_stream(column[x])
            spidev.flush()
            time.sleep(0.001)
        time.sleep((args.refresh_rate / 1000.0))


def array():
    images = []
    if ('filelist.txt' in args.filename):
        with open(args.filename, 'r') as file:
            for filename in file:
                filename = filename.rstrip()
                if not filename:
                    continue
                print filename
                images.append(Image.open(filename).convert("RGB"))
    else:
        images.append(Image.open(args.filename).convert("RGB"))

    for img in images:
        input_image = img.load()
        print "%dx%d pixels" % img.size
        print "Reading in array map"
        pixel_map_csv = csv.reader(open("pixel_map.csv", "rb"))
        pixel_map = []
        for p in pixel_map_csv:
            pixel_map.append(p)
        if len(pixel_map) != args.array_width * args.array_height:
            print "Map size error"
        print "Remapping"
        value = bytearray(PIXEL_SIZE)

        # Create a byte array ordered according to the pixel map file
        if args.chip_type == "SM16716":
            pixel_output = bytearray(args.array_width * args.array_height * PIXEL_SIZE_SM16716)
        else:
            pixel_output = bytearray(args.array_width * args.array_height * PIXEL_SIZE + 1)
        for array_index in range(len(pixel_map)):
            value = bytearray(input_image[int(pixel_map[array_index][0]), int(pixel_map[array_index][1])])

        if args.chip_type == "SM16716":
            pixel_output[(array_index * PIXEL_SIZE_SM16716):] = filter_pixel(value[:], 1)
        else:
            pixel_output[(array_index * PIXEL_SIZE):] = filter_pixel(value[:], 1)
        print "Displaying..."
        write_stream(pixel_output)
        spidev.flush()
        time.sleep((args.refresh_rate) / 1000.0)


def pan():
    img = Image.open(args.filename).convert("RGB")
    input_image = img.load()
    image_width = img.size[0]
    print "%dx%d pixels" % img.size
    print "Reading in array map"
    pixel_map_csv = csv.reader(open("pixel_map.csv", "rb"))
    pixel_map = []
    for p in pixel_map_csv:
        pixel_map.append(p)
    if len(pixel_map) != args.array_width * args.array_height:
        print "Map size error"
    print "Remapping"

    # Create a byte array ordered according to the pixel map file
    if args.chip_type == "SM16716":
        pixel_output = bytearray(args.array_width * args.array_height * PIXEL_SIZE_SM16716)
    else:
        pixel_output = bytearray(args.array_width * args.array_height * PIXEL_SIZE + 1)
    while True:
        for x_offset in range(image_width - args.array_width):
            for array_index in range(len(pixel_map)):
                value = bytearray(input_image[int(int(pixel_map[array_index][0]) + x_offset), int(pixel_map[array_index][1])])
                if args.chip_type == "SM16716":
                    pixel_output[(array_index * PIXEL_SIZE_SM16716):] = filter_pixel(value[:], 1)
                else:
                    pixel_output[(array_index * PIXEL_SIZE):] = filter_pixel(value[:], 1)

        print "Displaying..."
        write_stream(pixel_output)
        spidev.flush()
        time.sleep((args.refresh_rate) / 1000.0)


def all_off():
    if args.chip_type == "SM16716":
        pixel_output = bytearray(args.num_leds * PIXEL_SIZE_SM16716)
    else:
        pixel_output = bytearray(args.num_leds * PIXEL_SIZE + 3)
    print "Turning all LEDs Off"
    for led in range(args.num_leds):
        if args.chip_type == "SM16716":
            pixel_output[led * PIXEL_SIZE_SM16716:] = SM16716BLACK
        else:
            pixel_output[led * PIXEL_SIZE:] = filter_pixel(BLACK, 1)
    write_stream(pixel_output)
    spidev.flush()


def all_on():
    if args.chip_type == "SM16716":
        pixel_output = bytearray(args.num_leds * PIXEL_SIZE_SM16716)
    else:
        pixel_output = bytearray(args.num_leds * PIXEL_SIZE + 3)
    print "Turning all LEDs On"
    for led in range(args.num_leds):
        if args.chip_type == "SM16716":
            pixel_output[led * PIXEL_SIZE_SM16716:] = filter_pixel(WHITE, 1)
        else:
            pixel_output[led * PIXEL_SIZE:] = filter_pixel(WHITE, 1)
    write_stream(pixel_output)
    spidev.flush()


def fade():
    if args.chip_type == "SM16716":
        pixel_output = bytearray(args.num_leds * PIXEL_SIZE_SM16716)
        current_color = bytearray(PIXEL_SIZE_SM16716)
    else:
        pixel_output = bytearray(args.num_leds * PIXEL_SIZE + 3)
        current_color = bytearray(PIXEL_SIZE)
    print "Displaying..."

    while True:
        for color in RAINBOW:
            for brightness in [x * 0.01 for x in range(0, 100)]:
                current_color[:] = filter_pixel(color[:], brightness)
                if args.chip_type == "SM16716":
                    for pixel_offset in [(x * 4) for x in range(args.num_leds)]:
                        pixel_output[pixel_offset:] = current_color[:]
                else:
                    for pixel_offset in [(x * 3) for x in range(args.num_leds)]:
                        pixel_output[pixel_offset:] = current_color[:]
                write_stream(pixel_output)
                spidev.flush()
                time.sleep((args.refresh_rate) / 1000.0)
            for brightness in [x * 0.01 for x in range(100, 0, -1)]:
                current_color[:] = filter_pixel(color[:], brightness)
                if args.chip_type == "SM16716":
                    for pixel_offset in [(x * 4) for x in range(args.num_leds)]:
                        pixel_output[pixel_offset:] = current_color[:]
                else:
                    for pixel_offset in [(x * 3) for x in range(args.num_leds)]:
                        pixel_output[pixel_offset:] = current_color[:]
                write_stream(pixel_output)
                spidev.flush()
                time.sleep((args.refresh_rate) / 1000.0)


if CWIID_ENABLED:
    def wiimote():
        if args.chip_type == "SM16716":
            pixel_output = bytearray(args.num_leds * PIXEL_SIZE_SM16716)
        else:
            pixel_output = bytearray(args.num_leds * PIXEL_SIZE + 3)
        print 'Put Wiimote in discoverable mode now (press 1+2)...'
        global wiimote
        global wii_movetimeout
        global wii_movedir
        global wii_color
        wii_color = bytearray(PIXEL_SIZE)
        wiimote = cwiid.Wiimote()
        wiimote.mesg_callback = callback
        print "Displaying..."
        pixel_index = 0
        wiimote.rpt_mode = cwiid.RPT_ACC
        move_timeout = 0
        while True:
            if move_timeout >= wii_movetime:
                move_timeout = 0
                if wii_movedir == 1:
                    pixel_index = (pixel_index + 1) % args.num_leds
                else:
                    pixel_index = pixel_index - 1
            if pixel_index == -1:
                        pixel_index = args.num_leds
            move_timeout = move_timeout + 1

    #is this needed; poling?
        wiimote.request_status()
        if args.chip_type == "SM16716":
            pixel_output[((pixel_index) * PIXEL_SIZE_SM16716):] = filter_pixel(wii_color[:], 1)
            pixel_output += SM16716BLACK * ((args.num_leds - pixel_index))
        else:
            pixel_output[((pixel_index) * PIXEL_SIZE):] = filter_pixel(wii_color[:], 1)
            pixel_output += '\x00' * ((args.num_leds + 1 - pixel_index) * PIXEL_SIZE)

        write_stream(pixel_output)
        spidev.flush()
        time.sleep(wii_move_timeout)


def chase():
    if args.chip_type == "SM16716":
        pixel_output = bytearray(args.num_leds * PIXEL_SIZE_SM16716)
    else:
        pixel_output = bytearray(args.num_leds * PIXEL_SIZE + 3)
    print "Displaying..."
    current_color = bytearray(PIXEL_SIZE)
    pixel_index = 0
    while True:
        for current_color[:] in RAINBOW:
            for pixel_index in range(args.num_leds):
                if args.chip_type == "SM16716":
                    pixel_output[((pixel_index - 2) * PIXEL_SIZE_SM16716):] = filter_pixel(current_color[:], 0.2)
                    pixel_output[((pixel_index - 1) * PIXEL_SIZE_SM16716):] = filter_pixel(current_color[:], 0.4)
                    pixel_output[((pixel_index) * PIXEL_SIZE_SM16716):] = filter_pixel(current_color[:], 1)
                    pixel_output += SM16716BLACK * ((args.num_leds - pixel_index))
                else:
                    pixel_output[((pixel_index - 2) * PIXEL_SIZE):] = filter_pixel(current_color[:], 0.2)
                    pixel_output[((pixel_index - 1) * PIXEL_SIZE):] = filter_pixel(current_color[:], 0.4)
                    pixel_output[((pixel_index) * PIXEL_SIZE):] = filter_pixel(current_color[:], 1)
                    pixel_output += '\x00' * ((args.num_leds - 1 - pixel_index) * PIXEL_SIZE)

                write_stream(pixel_output)
                spidev.flush()
                time.sleep((args.refresh_rate) / 1000.0)
                if args.chip_type == "SM16716":
                    pixel_output[((pixel_index - 2) * PIXEL_SIZE_SM16716):] = SM16716BLACK
                else:
                    pixel_output[((pixel_index - 2) * PIXEL_SIZE):] = filter_pixel(current_color[:], 0)


gamma = bytearray(256)


# Open SPI device, load image in RGB format and get dimensions:
def load_image():
    print "Loading..."


# Apply Gamma Correction and RGB / GRB reordering
# Optionally perform brightness adjustment
def filter_pixel(input_pixel, brightness):
    if args.chip_type == "SM16716":
        output_pixel = bytearray(PIXEL_SIZE_SM16716)
    else:
        output_pixel = bytearray(PIXEL_SIZE)

    input_pixel[0] = int(brightness * input_pixel[0])
    input_pixel[1] = int(brightness * input_pixel[1])
    input_pixel[2] = int(brightness * input_pixel[2])

    if args.chip_type == "LPD8806":
        # Convert RGB into GRB bytearray list.

        # Some LPD8806 strips use this ordering:
        # output_pixel[0] = gamma[input_pixel[1]]
        # output_pixel[1] = gamma[input_pixel[0]]
        # output_pixel[2] = gamma[input_pixel[2]]

        # While some others use this one:
        output_pixel[0] = gamma[input_pixel[2]]
        output_pixel[1] = gamma[input_pixel[0]]
        output_pixel[2] = gamma[input_pixel[1]]
    elif args.chip_type == "SM16716":
        # ON bit at the pixel front
        # What is gamma correction for?
        output_pixel[0] = b'\x01'
        output_pixel[1] = input_pixel[0]
        output_pixel[2] = input_pixel[1]
        output_pixel[3] = input_pixel[2]
    else:
        output_pixel[0] = gamma[input_pixel[0]]
        output_pixel[1] = gamma[input_pixel[1]]
        output_pixel[2] = gamma[input_pixel[2]]
    return output_pixel


parser = argparse.ArgumentParser(add_help=True, version='1.0', prog='pixelpi.py')
subparsers = parser.add_subparsers(help='sub command help?')
common_parser = argparse.ArgumentParser(add_help=False)
common_parser.add_argument('--chip', action='store', dest='chip_type', default='WS2801', choices=['WS2801', 'LPD8806', 'LPD6803', 'SM16716'], help='Specify chip type LPD6803, LPD8806, WS2801 or SM16716')
common_parser.add_argument('--verbose', action='store_true', dest='verbose', default=True, help='enable verbose mode')
common_parser.add_argument('--spi_dev', action='store', dest='spi_dev_name', required=False, default='/dev/spidev0.0', help='Set the SPI device descriptor')
common_parser.add_argument('--refresh_rate', action='store', dest='refresh_rate', required=False, default=500, type=int, help='Set the refresh rate in ms (default 500ms)')
parser_strip = subparsers.add_parser('strip', parents=[common_parser], help='Stip Mode - Display an image using POV and a LED strip')
parser_strip.set_defaults(func=strip)
parser_strip.add_argument('--filename', action='store', dest='filename', required=False, help='Specify the image file eg: hello.png')
parser_strip.add_argument('--array_height', action='store', dest='array_height', required=True, type=int, default='7', help='Set the Y dimension of your pixel array (height)')
parser_array = subparsers.add_parser('array', parents=[common_parser], help='Array Mode - Display an image on a pixel array')
parser_array.set_defaults(func=array)
parser_array.add_argument('--filename', action='store', dest='filename', required=False, help='Specify the image file eg: hello.png')
parser_array.add_argument('--array_width', action='store', dest='array_width', required=True, type=int, default='7', help='Set the X dimension of your pixel array (width)')
parser_array.add_argument('--array_height', action='store', dest='array_height', required=True, type=int, default='7', help='Set the Y dimension of your pixel array (height)')
parser_pixelinvaders = subparsers.add_parser('pixelinvaders', parents=[common_parser], help='Pixelinvaders Mode - setup pixelpi as a Pixelinvaders slave')
parser_pixelinvaders.set_defaults(func=pixelinvaders)
parser_pixelinvaders.add_argument('--udp-ip', action='store', dest='UDP_IP', required=True, help='Used for PixelInvaders mode, listening address')
parser_pixelinvaders.add_argument('--udp-port', action='store', dest='UDP_PORT', required=True, default=6803, type=int, help='Used for PixelInvaders mode, listening port')
parser_fade = subparsers.add_parser('fade', parents=[common_parser], help='Fade Mode - Fade colors on all LEDs')
parser_fade.set_defaults(func=fade)
parser_fade.add_argument('--num_leds', action='store', dest='num_leds', required=True, default=50, type=int,  help='Set the  number of LEDs in the string')
parser_chase = subparsers.add_parser('chase', parents=[common_parser], help='Chase Mode - Chase display test mode')
parser_chase.set_defaults(func=chase)
parser_chase.add_argument('--num_leds', action='store', dest='num_leds', required=True, default=50, type=int,  help='Set the  number of LEDs in the string')
parser_pan = subparsers.add_parser('pan', parents=[common_parser], help='Pan Mode - Pan an image across an array')
parser_pan.set_defaults(func=pan)
parser_pan.add_argument('--filename', action='store', dest='filename', required=False, help='Specify the image file eg: hello.png')
parser_pan.add_argument('--array_width', action='store', dest='array_width', required=True, type=int, default='7', help='Set the X dimension of your pixel array (width)')
parser_pan.add_argument('--array_height', action='store', dest='array_height', required=True, type=int, default='7', help='Set the Y dimension of your pixel array (height)')
parser_all_on = subparsers.add_parser('all_on', parents=[common_parser], help='All On Mode - Turn all LEDs On')
parser_all_on.set_defaults(func=all_on)
parser_all_on.add_argument('--num_leds', action='store', dest='num_leds', required=True, default=50, type=int,  help='Set the  number of LEDs in the string')
parser_all_off = subparsers.add_parser('all_off', parents=[common_parser], help='All Off Mode - Turn all LEDs Off')
parser_all_off.set_defaults(func=all_off)
parser_all_off.add_argument('--num_leds', action='store', dest='num_leds', required=True, default=50, type=int,  help='Set the  number of LEDs in the string')
if CWIID_ENABLED:
    parser_wiimote = subparsers.add_parser('wiimote', parents=[common_parser], help='Wiimote Mode - move and LED witht he Wiimote')
    parser_wiimote.set_defaults(func=wiimote)
    parser_wiimote.add_argument('--num_leds', action='store', dest='num_leds', required=True, default=50, type=int,  help='Set the  number of LEDs in the string')

args = parser.parse_args()
spidev = file(args.spi_dev_name, "wb")
# Calculate gamma correction table. This includes
# LPD8806-specific conversion (7-bit color w/high bit set).
if args.chip_type == "LPD8806":
    for i in range(256):
        gamma[i] = 0x80 | int(pow(float(i) / 255.0, 2.5) * 127.0 + 0.5)

if args.chip_type == "SM16716":
    for i in range(256):
        gamma[i] = int(pow(float(i) / 255.0, 2.5) * 255.0)

if args.chip_type == "WS2801":
    for i in range(256):
        gamma[i] = int(pow(float(i) / 255.0, 2.5) * 255.0)

#LPD6803 has 5 bit color, this seems to work but is not exact.
if args.chip_type == "LPD6803":
    for i in range(256):
        gamma[i] = int(pow(float(i) / 255.0, 2.0) * 255.0 + 0.5)
args.func()


#print "Chip Type             = %s" % args.chip_type
#print "File Name             = %s" % args.filename
#print "Display Mode          = %s" % args.mode
#print "SPI Device Descriptor = %s" % args.spi_dev_name
#print "Refresh Rate          = %s" % args.refresh_rate
#print "Array Dimensions      = %dx%d" % (args.array_width, args.array_height)


if CWIID_ENABLED:
    def print_state(state):
        print 'Report Mode:',
        for r in ['STATUS', 'BTN', 'ACC', 'IR', 'NUNCHUK', 'CLASSIC', 'BALANCE', 'MOTIONPLUS']:
            if state['rpt_mode'] & eval('cwiid.RPT_' + r):
                print r,
        print

        print 'Active LEDs:',
        for led in ['1', '2', '3', '4']:
            if state['led'] & eval('cwiid.LED' + led + '_ON'):
                print led,
        print

        print 'Rumble:', state['rumble'] and 'On' or 'Off'

        print 'Battery:', int(100.0 * state['battery'] / cwiid.BATTERY_MAX)

        if 'buttons' in state:
            print 'Buttons:', state['buttons']

        if 'acc' in state:
            print 'Acc: x=%d y=%d z=%d' % (state['acc'][cwiid.X],
                                           state['acc'][cwiid.Y],
                                           state['acc'][cwiid.Z])

        if 'ir_src' in state:
            valid_src = False
            print 'IR:',
            for src in state['ir_src']:
                if src:
                    valid_src = True
                    print src['pos'],

            if not valid_src:
                print 'no sources detected'
            else:
                print

        if state['ext_type'] == cwiid.EXT_NONE:
            print 'No extension'
        elif state['ext_type'] == cwiid.EXT_UNKNOWN:
            print 'Unknown extension attached'
        elif state['ext_type'] == cwiid.EXT_NUNCHUK:
            if 'nunchuck' in state:
                print 'Nunchuk: btns=%.2X stick=%r acc.x=%d acc.y=%d acc.z=%d' % \
                  (state['nunchuk']['buttons'], state['nunchuk']['stick'],
                   state['nunchuk']['acc'][cwiid.X],
                   state['nunchuk']['acc'][cwiid.Y],
                   state['nunchuk']['acc'][cwiid.Z])
        elif state['ext_type'] == cwiid.EXT_CLASSIC:
            if 'classic' in state:
                print 'Classic: btns=%.4X l_stick=%r r_stick=%r l=%d r=%d' % \
                  (state['classic']['buttons'],
                   state['classic']['l_stick'], state['classic']['r_stick'],
                   state['classic']['l'], state['classic']['r'])
        elif state['ext_type'] == cwiid.EXT_BALANCE:
            if 'balance' in state:
                print 'Balance: right_top=%d right_bottom=%d left_top=%d left_bottom=%d' % \
                  (state['balance']['right_top'], state['balance']['right_bottom'],
                   state['balance']['left_top'], state['balance']['left_bottom'])
        elif state['ext_type'] == cwiid.EXT_MOTIONPLUS:
            if 'motionplus' in state:
                print 'MotionPlus: angle_rate=(%d,%d,%d)' % state['motionplus']['angle_rate']

    def callback(mesg_list, time):
        print 'time: %f' % time
        for mesg in mesg_list:
            if mesg[0] == cwiid.MESG_STATUS:
                print 'Status Report: battery=%d extension=' % \
                       mesg[1]['battery'],
                if mesg[1]['ext_type'] == cwiid.EXT_NONE:
                    print 'none'
                elif mesg[1]['ext_type'] == cwiid.EXT_NUNCHUK:
                    print 'Nunchuk'
                elif mesg[1]['ext_type'] == cwiid.EXT_CLASSIC:
                    print 'Classic Controller'
                elif mesg[1]['ext_type'] == cwiid.EXT_BALANCE:
                    print 'Balance Board'
                elif mesg[1]['ext_type'] == cwiid.EXT_MOTIONPLUS:
                    print 'MotionPlus'
                else:
                    print 'Unknown Extension'

            elif mesg[0] == cwiid.MESG_BTN:
                print 'Button Report: %.4X' % mesg[1]

            elif mesg[0] == cwiid.MESG_ACC:
                print 'Acc Report: x=%d, y=%d, z=%d' % \
                      (mesg[1][cwiid.X], mesg[1][cwiid.Y], mesg[1][cwiid.Z])
                if mesg[1][cwiid.X] > 512:
                    wii_movedir = 1
                else:
                    wii_movedir = 0
                if abs(mesg[1][cwiidX] - 512) > 50:
                    wii_move_timeout = 0.02
                else:
                    wii_move_timeout = 0.4

            elif mesg[0] == cwiid.MESG_IR:
                valid_src = False
                print 'IR Report: ',
                for src in mesg[1]:
                    if src:
                        valid_src = True
                        print src['pos'],

                if not valid_src:
                    print 'no sources detected'
                else:
                    print

            elif mesg[0] == cwiid.MESG_NUNCHUK:
                print ('Nunchuk Report: btns=%.2X stick=%r ' + \
                       'acc.x=%d acc.y=%d acc.z=%d') % \
                      (mesg[1]['buttons'], mesg[1]['stick'],
                       mesg[1]['acc'][cwiid.X], mesg[1]['acc'][cwiid.Y],
                       mesg[1]['acc'][cwiid.Z])
            elif mesg[0] == cwiid.MESG_CLASSIC:
                print ('Classic Report: btns=%.4X l_stick=%r ' + \
                       'r_stick=%r l=%d r=%d') % \
                      (mesg[1]['buttons'], mesg[1]['l_stick'],
                       mesg[1]['r_stick'], mesg[1]['l'], mesg[1]['r'])
            elif mesg[0] == cwiid.MESG_BALANCE:
                print ('Balance Report: right_top=%d right_bottom=%d ' + \
                       'left_top=%d left_bottom=%d') % \
                      (mesg[1]['right_top'], mesg[1]['right_bottom'],
                       mesg[1]['left_top'], mesg[1]['left_bottom'])
            elif mesg[0] == cwiid.MESG_MOTIONPLUS:
                print 'MotionPlus Report: angle_rate=(%d,%d,%d)' % \
                      mesg[1]['angle_rate']
            elif mesg[0] == cwiid.MESG_ERROR:
                print "Error message received"
                global wiimote
                wiimote.close()
                exit(-1)
            else:
                print 'Unknown Report'
 
Soldato
Joined
6 Mar 2008
Posts
10,079
Location
Stoke area
I've not had time to do anything but glance over and its a lot of code for that kind of window.

The program already has a chase function "def chase():". Have a play with things like refresh rate in there.

If I get chance later I will have a proper look over it
 
Soldato
OP
Joined
28 Sep 2004
Posts
3,128
Location
Devon, UK
Sorry yes I know Im posting from my phone but will try and shorten it down on laptop tomorrow.

I've tried changing some of the chase code but I don't really know what any of the code mean. I've tried taking some out to see what difference it makes but it doesn't seem to do much.

The chase function does work but it turns the led on then right off again. What I want to do is turn them on one by one and stay on.

Thanks
 
Soldato
Joined
6 Mar 2008
Posts
10,079
Location
Stoke area
where did you get the code from?

and is this actual LED lights or fake LEDs on a screen? If its just software it might be easier for me to try it myself :D
 
Last edited:
Soldato
OP
Joined
28 Sep 2004
Posts
3,128
Location
Devon, UK
I've kind of got somewhere now using a different script.

The problem is it keeps looking and I only want it to run once then stop. I've tried adding a sys.exit() but if I put it in the def knightrider it only turns on one led then ends the script. If I put it anywhere else it does nothing :(

Code:
# Simple Example for accessing WS2801 LED stripes
# Copyright (C) 2013 Philipp Tiefenbacher <[email protected]>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For more information about this project please visit:
# http://www.hackerspaceshop.com/ledstrips/raspberrypi-ws2801.html
import math
import sys
import time

from LedStrip_WS2801 import LedStrip_WS2801, LedStrip_WS2801_FileBased

def mySin(a, min, max):
return min + ((max - min) / 2.) * (math.sin(a) + 1)

def knight_rider(ledStrip, trail_nb_leds=3, color=[255, 0, 0], times=5, sleep=0.08):

if trail_nb_leds > ledStrip.nLeds or trail_nb_leds <= 0:
raise ValueError("Wrong trail_nb_leds value")
black_color = [0, 0, 0]

for i in range(times):
# left to right
for i in range(ledStrip.nLeds + trail_nb_leds):
ledStrip.setAll(black_color)
for j in range(min(i + 1, trail_nb_leds)):
if i - j <= ledStrip.nLeds:
ledStrip.setPixel(index=i - j, color=[x / max((j * 8), 1) for x in color]) # division is to fake lower brightness
ledStrip.update()
time.sleep(sleep)

if __name__ == '__main__':
if len(sys.argv) == 1:
nrOfleds = 160
else:
nrOfleds = int(sys.argv[1])
delayTime = 0.01
# oldStrip = LedStrip_WS2801_FileBased(nrOfleds, "/dev/spidev0.0")
# fillAll(oldStrip, [255, 0, 0], delayTime)
# oldStrip.close()
ledStrip = LedStrip_WS2801(nrOfleds)
while 1:

knight_rider(ledStrip)
 
Back
Top Bottom