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.
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
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
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.
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
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.
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))