Back

16x16 LED matrix controlled by raspberry

Project description

This is an idea I had inspired by this product I used a WS2812B LED strip (with individualy adressable leds), and cut it so it could fit into a wooden frame. Then soldered the cut strips together and connected the beginning to a 2.5mm jack.

Finding the strip

The strip must have at least 16x16 = 256 pixels and so the 5m IP30 is perfect for this. Although at first I made a mistake and bought the IP67 istead of the IP30, which has a silicone coating for water resistance, but the coating was easy to remove. Find the strip here

ledStrip

Designing the wooden frame

I wanted to make the casing with wood, so I drew an inkscape file with all the pieces I wanted and gave it to a person who has a cnc laser cutter to cut it for me.Find the svg file here

ledStrip

Glueing and soldering the pieces

This was the most time consuming part, as soldering requires lots of time and precision. The solders don't have to be perfect, as long as the ends are not connected.

ledStrip ledStrip ledStrip

Designing and printing the diffuse grid

For the LEDs to be proper diffused and look like square pixels, I designed a grid in FreeCAD that will be placed above the leds Find the STL file here

3Dview
TimeLapse

Assembly

This was one of my favorite stages of the project :)

I used paper as a screen, since the pvc I ordered was too thic and the pixels were not apearing clearly.

finished finished

Finished

finished finished finished finished finished

Controll with Python

I used the library rpi_ws281x to controll the RBG Strip. When you run the script, it checks the folder "gifs" for all the gifs inside, ands asks which one to play. It also asks for the brightness and delay between frames. It resizes the gif and saves it in the "resized" folder inside the gifs folder. If it already is in the resized folder, it doesnt resize it as it takes some time. The resize function I used is from my resize excercise

    from PIL import Image
    import math
    import time
    import sys
    import os
    from resize import *
    from rpi_ws281x import *
    LED_COUNT = 256
    LED_PIN = 18
    LED_FREQ_HZ = 800000
    LED_DMA = 10
    #LED_BRIGHTNESS = 255
    LED_INVERT = False
    LED_CHANNEL = 0

    files = []
    i =0
    for file in os.listdir("/home/pi/Documents/LEDMatrix/gifs/"):
        if file.endswith(".gif") or file.endswith(".png") or file.endswith(".jpg"):
            print(i, ": ", file)
            files.append(file)
            i+=1



    filenum =int(input("Which one to play? "))
    LED_BRIGHTNESS = int(input("bightness: "))
    checkpath = str("/home/pi/Documents/LEDMatrix/gifs/resized/res_"+files[filenum])
    print(checkpath)
    print("exists in resized: ",os.path.exists(checkpath))
    delay = input("delay (leave blank for 0.1) ? ")
    if delay == "":
        delay = 0.1

    if not os.path.exists(checkpath):
        gif = Image.open(str("gifs/"+files[filenum]))
        print("resizing...")
        resizeGif(gif, 16, 16, str("res_"+str(files[filenum])), "/home/pi/Documents/LEDMatrix/gifs/resized")


    frames = []
    im = Image.open(checkpath)
    for i in range(0, im.n_frames):
        im.seek(i)
        rgbIm = im.convert('RGBA')
        frames.append(rgbIm)

    strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL)
    strip.begin()

    def SetLedColor(lednum, color):
        strip.begin()
        strip.setPixelColor(lednum, Color(color[0], color[1], color[2]))

    def SetPixelColor(ledx, ledy, color,):
        if color[3] == 255:
            if ledy%2 == 1:
                strip.setPixelColor((15-ledy)*16+ledx, Color(color[0], color[1], color[2]))
            if ledy%2 == 0:
                strip.setPixelColor((15-ledy)*16-1  + 16 - ledx, Color(color[0], color[1], color[2]))
    run = True
    print("playing...")
    while run:
        for i in range(0, len(frames)):
            width, height = frames[i].size
            pix = frames[i].load()
            for x in range(0, width):
                for y in range (0, height):
                #    print(x, y, pix[x,y])
                    SetPixelColor(x, y, pix[x,y])
            strip.show()
            time.sleep(float(delay))