Introduction: PixelBrite

About: Artist/engineer
I originally started this project because I wanted to recreate the scene in the movie the Close Encounters of the Third Kind where the humans are communicating with the Mothership via a huge color organ. So I glued various bits of software together and made some prototypes and before I knew it I was talking with the Mothership with my own color organ!

I was intrigued by the potential of the color organ, but without about 20 more years of piano lessons I would never reach that maximum potential. I wanted something more programmable, a general instrument, not a musical instrument thought, a LED instrument. I wanted something I could play, just like the idea of the color organ but with more complex patterns and animations and simpler controls. I wanted a way to add texture, color, and motion to music. I wanted a light show I could perform with, pixels to play with, a real-time playable instrument that could accompany a musical performance. I wanted it portable, scalable, easy to setup, easy to play, and so I built four PixelBrites, setup a couple of stage light trip-pods and plugged in my MIDI controller and laptop and I became the light show. Fun times were had by all!

But I knew I couldn't be an overly protective parent and hover above my progeny all the time,  I wanted the PixelBrite to act as a standalone light. I wanted to remove myself and the computer and simplify the experience. I wanted a disco coffee table and a minimalist light sculpture. I wanted to hang it on my wall and let it become part of the background. I wanted a night light, a party light, and a mood light. So I created a way to easily make animations and patterns and added a SD card slot to stream patterns without a computer. Now when I get home I get low-res ambiance without even opening my laptop.

If you ever had a Light-Brite when you were a kid then you might remember the experience of playing with light. PixelBrite is my digital version of the Light-Brite. It’s a plug-n-play light show, it’s a minimalist light sculpture, it’s a conversation starter and it’s a piece of wall décor. It’s a futuristic Ikea coffee table and a Daft Punk disco light. It’s bright, dark and colorful. It’s digital stained-glass. A center-piece or a perimeter-piece, it’s portable, playable and programmable.

Welcome to my Instructable, I hope you enjoy.

Step 1: Project Overview

This will be your guide into the world of pixels. I’ll teach you a bit about color theory and display science, and then I’ll show you how I was able to make four PixelBrite LED panels. I’ll provide all the sources for building your own and provide a step-by-step guide. I’ve also included a whole bunch of pixel art patterns and animations I made with software included in this guide. I hope you find this guide useful and if you do let me know by getting in touch through my website:

Here’s the quick and dirty: tech specs, components, tool references, and downloads.

Technical Specifications:
  • Resolution: 10 x 10 pixels
  • Operating Voltage: 5V
  • Max Current: ~6A
  • Max frame rate: 60fps
  • Color depth: 24 bits/pixel = 16 million colors/pixel
  • Size: 610mm x 610mm x 90mm
  • Pixel fill factor: 90%
  • Weight: <5lbs
Hardware Components:
  • WS2801 RGB LED Pixel strands (25 pixels/strand, 4 strands/PixelBrite) 
  • Teensy Microcontroller (Atmel 32u4)
  • SD card reader
  • 10A DC power supply
  • Acrylic panels
  • MicroRax aluminum extrusion
  • Painted foam waffle divider
  • Custom PCB
  • Misc. interface electronics (switch, button, resistor, etc...)
Build Tools:
  • Soldering iron
  • Wire strippers/cutters
  • Dremel
  • Hacksaw
  • PCB etchant, Developer, Acetone
  • Caulking
  • Hot glue gun
  • Scribe
  • Allen wrench
  • Straight edge
All the files are available from the LeoneLabs PIxelBrite GitHub repo. This includes all the Processing and Arduino code as well as a whole bunch of content to play with.

Step 2: The Bill of Materials

I can think of no better way to sum up the PixelBrite hardware than with an awesome spreadsheet, chock-full of the most valuable information you'll see all day. Behold!... the Bill of Materials...! This is really the one-stop-shop if you want to try and build your own PixelBrite. 

Bill of Materials:


LeoneLabs PixelBrite Bill of Materials - June 2013


Component Part Description Vendor Value Qty Price Unit Cost


Translucent acrylic panel ACRYLITE® GP P-95, sheet, Black/White 9H04 23.875" x 23.875" x 0.118" (3mm thick) 2 $6.63 sq-ft $31.24


Opaque acrylic panel ACRYLITE® FF (extruded), sheet, Black 9M001 23.875" x 23.875" x 0.118" (3mm thick) 1 $5.20 sq-ft $25.58


Aluminum extrusion 10mm Profile, 600mm 8 $7.20 $57.60


Aluminum extrusion 10mm Profile, 70mm 4 $0.84 $28.80


Aluminum tri-corner bracket 8 $2.40 $19.20


Foam 6mm White Depron - 10 Sheets, Size 27"x39" 6mm thick 0.4 $69.00 10 sheets $27.60


Laser Cutting Service Laser cutting 1 backplane, 8 rails_0, 8 rails_1 0.5 $203.00 Quoted for 2 sets of parts $101.50


Teensy 2.0 Microcontroller Teensy USB Development Atmel 32u4 microcontroller 1 $16.00 $16.00


MicroSD Card 1 $8.00 $8.00


USB adapter USB Cable, Mini-B to Standard-B Panel Mount 1 $5.50 $5.50


Invidually-addressable RGB LED pixel strands 12mm Diffused Flat Digital RGB LED Pixels (Strand of 25) - WS2801 4 $39.95 1 strand = 25 pixels $159.80


5V DC power supply 5V 10A switching power 5V 10A 1 $25.00 $25.00


PCB Board Circuit Skills #1: Jameco Value Pro Prototyping 0.5 $46.95 $23.48


Molex Header + Wiring Molex Jumper 6 Wire 6-wire 1 $1.95 $1.95


DC Barrel Jack Panel Mount 2.1mm DC barrel 2.1mm barrel 1 $2.95 $2.95


Rocker power switch SWITCH ROCKER SPST 16A SPST, 16A, rocker 1 $0.96 $0.96


Momentary Button SWITCH PUSH SPST-NO 3A SPST, 3A, momentary 1 $1.80 $1.80


Terminal Block Fixed Terminal Blocks 4P 2.54mm 4 positions, 2.54mm (0.1") pitch 1 $2.43 $2.43


Twist-on wire connector ("wire nut") Radioshack $0.00


22awg wire Radioshack $0.00


Resistor Radioshack 10k $0.00


Total: $539.39

Here’s the top four most expensive components
  • $159.80 | RGB Pixels
  • $129.10 | Laser cut foam
  • $105.60 | MicroRax
  • $56.82 | Acrylic
If there are better sources let me know!

Step 3: The Electronics

The electronics include off-the-shelf components and a custom printed circuit board (PCB). The circuit itself is relatively simple, the primary functionality is to read streaming pixel data from a USB port or SD card and then send it out to the LEDs.

A rocker switch turns ON and OFF the PixelBrite. When turned ON the Teensy microcontroller uses hardware SPI (serial peripheral interface) to send color information to the individual IC (integrated circuits) next to the LEDs. A push button is used as a hardware interrupt and to change the internal state of the microcontroller. The state can be changed from streaming data from the USB port to streaming pixel data from an SD card, a bit like an mp3 player but with pixels rather than sounds. On each button press, the next file in the SD card is read and displayed on the PixelBrite. The whole thing is powered from a 5V source which can come from a wall-plug or a battery pack.

This microchip is really the tentpole for this whole project. The WS2801 describes itself as a "3-Channel Constant Current LED Driver With Programmable PWM Outputs", but in its essence the WS2801 is the magic that turns a simple RGB LED into and RGB Pixel. A WS2801 microchip sits next to each RGB LED in the strand and each one can turn a stream of high-speed ones and zeros into 8-bit grayscale color value in less than a thousand of a second(? need calc). What's more, it passes along the data for the next pixel in the chain so everyone down the line can get their next color instruction. What's even more amazing is that the next generation of LED controller IC's (WS2811) are being integrated directly next to the LED as a bare die!
Power Supply:
The power is provided by a 5V DC source and this could either an enclosed DC power supply like the one provided by Adafruit or a battery pack. I've tried both and both work. Depending on the pattern the current draw can be signicantly less than the rated maximum and so a batter pack can provide just enough juice for an event but not much more. I used a battery pack when using the PixelBrite as a coffee table or night light and it works well. For the stage events I'll typically switch to a wall-plug DC power supply.

The real consideration when choosing the power supply, though, is the amount of current that they can provide. The individual LEDs can max out at around 20mA, so for 100 pixels with three LEDs per pixel that means the total system could draw upwards of 6 amps. I decided to measure the amount of current that was being consumed when a full-white image, which would correspond to max power. The results showed that rather than ~6A I was instead only drawing roughly 2.3A. 

At less than half the rated maximum I'm speculating that it has something to do with the resistance of my interfaces or contact points. I'm using some pretty light crimp connections between the DC power supply jack and the PCB board which may be restricting the current draw. I'm going to poke around to see if I can't uncover the cause of this.

Regardless, for battery powered use a lower current consumption is preferred and for most images and animations the amount of current needed is far below the maximum. The current discharge rate of the batteries will limit the maximum brightness of the system but as the video and images show, 4X AA batteries can provide enough current to turn the PixelBrite into an un-tethered coffee table, wall hanging, or mood light.

The engineer in me says there is still plenty of engineering to work out in this area. I'll continue to see if I can't flesh out more details in the future so stay tuned.

Step 4: LED Wiring

These RGB LED strands and strips have grown in popularity due to dropping prices, increased availability, and some good ol-fashioned open-source elbow grease. These strands provide a very convenient way for making an array of pixels and I first came across them on Adafruit which includes a ton of great resources for getting started. Be sure to check out these links if you've never worked with these LED strands before.

Adafruit Links:Wiring:
The LEDs are connected with 4 wires:
  1. Power
  2. Data
  3. Clock
  4. Ground
The LED strands from Adafruit come in 25-pixel sections. For the PixelBrite panel four strands are used, making a total chain of 100 pixels. The layout is serpentine rather than the typical raster scan layout used in digital displays. I chose the column-dominated serpentine layout in order for the PixelBrites to easily tiled.

LED Teardown
The LED and populated PCB are encased in epoxy for weatherproofing. Cutting open one of the LED shells reveals the following.

The label on the top of the PCB reads:
  • SJ-1515ICRGB
The labels on the bottom of the PCB include the channels:
  • Green = Clock (C0)
  • Yellow = Data (D0)
  • Blue = Ground (GND)
  • Red = 5V+
There’s also an arrow indicating the input side.

Bad pixels
Working with about 400 pixels I came across several that appeared defective. Some were worse than others so I used my best judgement before deciding to amputate the pixel and replace it with a known-good one. I’m not sure what might have caused them to go bad, although I wonder what the expected yield is out of the factory and in some cases what is the level for pass-fail because overall the uniformity is OK but not great.

Power distribution
I found it necessary to include four power distribution lines, that’s 2-wires each, +5V and GND, between the input and the end of each strand. Putting up just a plane full-white image reveals the power dips. If you ignore the slight change in color temperature, you can see the image on the left only uses 1 power distribution line to the very end of the fourth-strand in the lower left corner. In the center of the PixelBrite the brightness is reduced and non-uniform. The image on the left includes 4 power distribution lines and the uniformity and brightness is much better.

Step 5: Waffle Grid

For lack of a better term I decided to go with “waffle grid.” I sometimes also refer to it as a “louvre” or “light guide” because its purpose is to define the pixel boundaries and reduce hotspot from the center LED.  Here are the quick stats:
  • The foam is 6mm thick.
  • The pixel pitch is 60mm
  • The holes are 12mm in diameter (which matches the spec for the LED Pixels from Adafruit)
  • The slots are 6mm (which matches the depron foam from RCFoam)
  • The backpanel and rails are 606mm in length.
  • The rails are 60mm tail (and stand 54mm above the backpanel when slotted)
  • There are two interlocking rail designs
  • The SVGs contain 1 backplane, 19 rail_0 design, and 14 rail_1 design.
Here's the three PixelBrite SVGs I sent to Pololu for laser cutting. There sizes are matched to cutting area and the size of the foam sheets. Be sure to check out Polulu's Custom Laser Cutting Guide. I ended up using Pololu because they offered some of the largest cutting areas available; they are able to take sheets up to  35.5" x 50" in size (at 606mm, the waffle grid pieces are just under 24" in size).

No waffle grid vs. waffle grid
During the project I decided to test the PixelBrite without the waffle grid. Here’s a side-by-side comparison. There are a couple of things that should be apparent. The one on the right does not have the waffle grid and you can see the hotspots are much more pronounced. Furthermore, the color saturation is lower because adjacent pixels are leaking across their logical boundaries and mixing with the a neighbors. This tends to cause the pixels to “wash out” and create a sort of whitish haze. Overall I think its easy to see the waffle grid is an effective light guide and hotspot diffuser.

Step 6: Ninja Box

One thing I’ve noticed with usual build guide for LED arrays is the lack of a modular enclosure. I’d built previous LED matrices with just a simple backplane, some foamcore poster board or cardboard, but there were wires everywhere and I felt it was in constant danger of being accidentally destroyed. My solution was to enclose the LEDs in acrylic and use the very handy MicroRax aluminum profiles to hold it together. Also I was able to find some great sign-grade acrylic that was tinted so the panel would look black when the LEDs were OFF. This turned out to be great choice for helping dim the LEDs, diffuse the hotspots, and create a good looking box even when the LEDs weren't ON.

The Ninja Box stat sheet:
  • The pigmented acrylic is 10-15% transmissive
  • The acrylic is glossy on one side and matte on the other
  • The MicroRax is 10mm-wide aluminum profile
  • The dimensions of the acrylic are 606mm x 606mm
  • The dimension of the side panels are 76mm x 606mm
  • The acrylic is 3mm thick

Step 7: Close Encounters of the Third Kind Demo

There is an iconic scene in the movie Close Encounters of the Third Kind which shows a giant color organ being used to communicate with an alien Motherhship. Now if you've never heard of a color organ, as the name might suggest, its a way to play with visual colors the same way a organist plays with musical notes.  In the movie, the color organ is used with great effect to John Williams score and became a shining example of the possibilities. However, despite its abilities to communicate with aliens, the color organ never really materialized as a product the average person could connect with. Regardless of its history, it wasn't until I came across this interesting comment that I felt the need to dig deeper: 

"In the film, the original aspirations of Castel’s ocular harpsichord appear to be finally realized. However, when I recently spoke to Philip Dodds, the former ARP engineer who appears in Close Encounters as the synthesizer operator, he told me that the synthesizer and light console used in the film were never actually linked."

-James Peel, 
The Scale and the Spectrum, 2006

Never linked!? Of course I can't confirm this quote (if anyone knows tell me!), but it sounded enough like a challenge to try and hack something together.  Overall it ended up being a pretty messy process with all the tempo changes that take place in the scene, but it turned out alright (lets just not mention the fact that a couple of notes are missing from the beginning, ok?...)

I used a Lenovo T410i ThinkPad which, oddly, does not have the ability to natively record from the sound card. This made it necessary for me to install another driver (Conexant CX20671 SmartAudio HD) in order for me to access the sounds coming through my sound card.

While I originally crafted my own software to translate the MIDI signals into triggered pixel patterns, I ended up preferring to use Madrix, a piece of stage-light software designed for pixelized displays. In Madrix I was able to generate a script that would draw colored lines when a MIDI note was detected and so now all I had to do was send the MIDI data into Madrix.

To do this I combined Ableton and a free virtual MIDI driver called LoopBe. LoopBe allowed my to send out MIDI signals from Ableton as the MIDI file was played to this virtual MIDI port which Madrix was setup to listen to. Thus I could play and edit the MIDI notes in Ableton and then see the pixel patterns being triggered in Madrix, all without even having any hardware!

Once I was able to build the PixelBrite panels and get the firmware working, I could then just broadcast the Madrix view to the PixelBrite with the PixelPal software as Ableton sent out the MIDI notes in real time.

Overall I thought it turned out pretty well. Now I just need to find some Motherships…

Step 8: DJ Setup

Perhaps one of my favorite uses for the PixelBrite panels is for creating live light shows to accompany a DJ or musician. Here’s a summary of my experience:
  • Multiple PixelBrite can be easily tiled together and controlled
    • I ended up building four PixelBrite panels and tiled them together. My preferred layout is 4x1, although 2x2 ain’t bad either.
  • Setup is fast and easy
    • The PixelBrite panels are hung from t-bars mounted on tripods. I used O-rings (like a key-chain ring) and so no clamps or other mounting hardware is needed.
  • They are a fraction of the cost of other stage lights.
    • Gear is expensive, and in some cases needs to be, but if I could have bought a cheaper pixel panel setup I would have… instead I built one.
  • No DMX,  no DVI, just USB
    • DMX is a signal protocol akin to MIDI signals used with audio, except DMX is meant for stage lighting. While there's nothing wrong with that in principle, it requires unnecessary middleware if you want to run some lights from your laptop.
    • There are a lot of projectionist that will use projectors for light shows with amazing success. However in this case a full DVI video signal is needed, that includes a lot of pixels, for high-definition that’s 2 million pixels! Yet you don’t need a video port to do the job of a serial port, and so with a fraction of the bandwidth you can still create a pretty awesome light show with a 100 pixels. 

I’m able to control them with a USB MIDI controller and my laptop. By piping in the audio line from the main DJ mixer I can create sound-reactive effects. Madrix has a good collection of equalizers and sound-reactive effects. I've also included my own collection that you can download from the GitHub repo.

Tiling multiple PixelBrites together:
To tile the PixelBrites together all that has to be done is to connect the LED strands from one box to the next. You only need one master box which includes the PCB and electronics. The other boxes can just be passive strands of LEDs however for larger arrays more power and more power distribution is needed.


I experimented a lot with Madrix and over the course of the project generated a bunch of effects and color palettes. You'll need to download Madrix 2.14 (free to try) in order to open these files.

Step 9: Color and Light

If there’s only one light in each pixel where do all the colors come from? Well, if you remember your basic color mixing from grade school or you’ve ever opened up MS Paint you’ll see that with only three primary colors it’s possible to mix them in various amounts to create any color in spectrum.

But wait! We aren’t mixing red, blue and yellow like we did paint brushes, when we mix light we are mixing color differently than when we are mixing paints or pigments. It’s an additive process rather than a subtractive process and that means the primary colors are different. It’s not red, blue and yellow. The primary colors for mixing light are red, green and blue.

Inside each pixel is three light sources, a red one, green one, and blue one (RGB). By turning up or turning down the brightness of the individual components we can make any color. The same technique is used in every display around, albeit with tiny pixels rather than jumbo ones, but the principle is the same.

Pixel Patterns
So what are pixel patterns? In their simplest form they are just a big list of numbers, one value for each red, green, and blue component within each pixel of every frame. Most often a color is represented as a triplet, for example:
  • Yellow = {255,255,0}
  • Blue = {0,0,255}
Therefore to make an array of pixels we just need a list of triplets, and if we set up the physical hardware into a 2D array that list of triplets will get mapped out to the rows and columns physical pixels.

As a part of the software development I decided to try and keep things as simple as possible so rather than saving the pixel patterns as images I decided to save them as raw binary files. This means they are just pixel values, there’s no metadata about what the physical array of pixels looks like. This means that the pixel pattern files need to be opened in the PixelPal software in order to see what colors the values translate to, but you can also look at them in a hex editor if you’re curious.

For reference here’s what a raw binary file looks like in the free hex editor, Frhed, compared to the actual colors of the pattern. You can see the first three entries correspond to the color triplet of the first pixel. The numbers are represented in hex notation so “FF” is equivalent to a value of 255 or the maximum value of an 8-bit number. The first triplet is {FF, 00, FF} which is equivalent to the magenta pixel seen in the pattern.

Step 10: PixelPal Software

In order to make the PixelBrite more accessible to everyone I spent a lot of time working a software app that would be useful but also be able to create lots of great content. The PixelPal software is standalone and doesn’t require the PixelBrite. It lets you record, play, and save your own pixel patterns. Be sure to check out the Software Demo video to learn more about how to use the application.


How does it work?
It creates ultra low-res pictures by undersampling what appears on your desktop. You specify the pixel array (e.g. 10x10, 20x5, 200x200) and the capture window and the PixelPal software will grab the color values from your desktop and create a pattern to save or display.

How do I start?
On Windows, just download the Processing code and run the PixelPal.exe in the "application.windows32" folder.

You'll need java if you want to try and hook it up to the PixelBrite. Get it from

To compile the source code you’ll need:

What about the Arduino code?
You can use the PixelPal software without a PixelBrite or without the Arduino code, however, if you want to stream data over the USB port than you’ll need the Arduino code. To use the Arduino code you also need a couple of libraries

Also don’t forget to change the numPixels variable in the Arduino code to match the number of LEDs being used in the PixelBrite otherwise the images will look scrambled.

Screen resolution
The desktop capture feature of the problem should scale with your screen resolution, so the app should always look similar to image shown. However, I’ve only really tested this with a screen resolution set to 1280x768, so caveat emptor!

Gamma adjustment:
Easily apply gamma correction to the pixel patterns in order to generate the proper colors on the PixelBrite hardware. For more information on gamma correction be sure to check out the Measurements section.

Serpentine Remapping:
As the LED wiring shows, the LEDs are connected in a serpentine fashion. This means that the order of the pixels stored in memory is different than the physical order of pixels in the PixelBrite hardware. As a result, if the image is to be displayed corrected the pixels must be saved in a new ordering. This is easily accomplished with the “Remap” button which will take a rasterscan normal pixel pattern and reorder it to match the column-major serpentine layout of the PixelBrite

Code Reference:

  • Processing (PixelPal)
    • LeoneLabs_PixelPal_v1_41
      • setup()
      • draw()
      • stop()
      • mouseDragged()
      • mousePressed()
      • controlEvent(theEvent)
    • Animation(buffer, array_width, array_height)
      • getFrame(frame_n)
    • CaptureGUI (x, y, w, h, array_width, array_height)
      • display()
      • capture()
      • renderFrame()
      • blendFrames(src_img0, src_img1, float percentage)
      • mouseEvent()
      • grabDesktop()
      • resizeImage(out_img, in_img scale)
      • updateCaptureWindow(x, y)
      • expandCaptureWindow(x, y)
      • updateCaptureCoords()
      • updateCaptureScaler()
      • sampleImage(source_image)
      • histSampleImage(histsize_x, histsize_y, source_image)
    • FileManager(x, y, w, h, path)
      • listFiles(dir)
      • listFileNames(dir)
      • AddToListBox(path, filenames, files)
      • loadPatternFromFile(filepath)
    • PixelBrite (app, x, y, w, h)
      • display()
      • updateArray(app)
      • controls(list)
      • controls(controller)
    • PixelPlayer(app, x, y, array_width, array_height)
      • display()
      • applyRemapGamma(input_img)
      • renderFrame(n, anim, previous_frame)
      • blendFrames(src_img0, src_img1, percentage)
      • resizeImage(out_img, in_img, scale)
      • resizeImage(out_img, in_img, scale_x, scale_y)
      • updateBlendCount()
      • updateFrameRange()
      • loadAnimation(filepath)
      • loadAnimation(pixel_buffer)
      • savePNG(fileName)
      • saveBytesToFileVer2(fileName)
      • controls(controller)
      • saveAnimationToFile(selection)
      • saveGIFToFile(selection)
      • openGIF(selection)
      • savePNGToFile(selection)
      • sampleImage(source_image)
      • sampleImageVer2(source_image)
    • PixelRecorder(x, y, w, h, array_width, array_height)
      • saveToOutputBuffer()
      • display()
      • updateProgressBar()
      • mouseEvent()
      • record(sampled_img)
      • controls(controller)
    • PixelStreamer(app, x, y, array_width, array_height)
      • display(pixel_array)
      • connect()
      • disconnect()
      • controls(controller)
  • Arduino (PixelBrite_v1)
    • LeoneLabs_PixelBrite_v1
      • setup()
      • loop() //not used
      • butStateChanged()
      • colorWipe(wait)
      • startup(wait)
      • rainbow(wait)
      • Wheel(WheelPos)
      • Color(r,g,b)
    • LEDstream()
    • SDstream(wait)
      • setPixels(pixels[],wait)

Step 11: The Build

Layout – Foam and PCB
The first thing I did was generate the layout files for the foam waffle grid light guide. I used the free, open-source vector graphics editor Inkscape. This process was a straightforward combination of the basic shapes and the Boolean operators built into Inkscape.

For the PCB I used the free, open-source layout software Fritzing. This turned out to be a bit of an uphill battle. I ended up having to create two layouts, one in the schematic editor and one in the PCB editor. However, all I needed up front was the PCB layout so I started from there and then added the schematic as a reference later.

Laser cutting services from
Once I'd completed the layout I exported the .svg files to .dxf and then uploaded them to Their online quotation tool was easy to use. I also drop shipped them an order of 6mm depron foam sheets I'd ordered from They sent me a selection of quotes from 5-day to same-day service! I opted for the lowest-cost, 5-day service, however the results exceeded my expectations!  

Paint the foam waffle grid
The raw foam itself is not a very good light guide. The foam is too translucent and if used in its raw state would let a lot of light leak from one pixel to the next. The best solution I could come up with was to paint the foam.

Now in hindsight this wasn't the best choice; painting foam, as it turns out, is a very labor-intensive process. One might think that you could throw a layer of paint onto each side of the foam and you'd have a completely opaque piece of foam. You might even think that you could get away with a couple coats of spray paint... oh you poor naive child! As it turns out it took me about 7 coats of paint before I was satisfied with the opacity of the foam.

This was perhaps the most time consuming part of the whole process. I think in retrospect it would have been a lot easier to go with some normal corrugated cardboard and then simply paint them white. I spent some time looking for 2-sided white cardboard but came up short. This would have probably produced some more opaque rails and created better pixel separation but I'm satisfied with the painted foam despite the extra effort.

Cut the MicroRax frame
The MicroRax aluminum extrusion can be cut a variety of ways, I opted for some hand vices and a hacksaw. 

  • MicroRax :
    • 8 pieces, 600mm*
    • 4 pieces, 70mm*

*As a possible coincidence (who knows!), you can buy these sizes directly from MicroRax and no cutting is needed!

Assemble the frame
Once the pieces were cut the frame was easily assembled by screwing the tri-corner brackets onto the ends of the aluminum profiles.

For added strength I used some silicone caulking between the Microrax and the acrylic panels on the front and back faces. What I found was that the tricorner brackets could hold the entire assembly together but when I was picking up or hanging the panels the aluminum would flex slightly in the middle.

Some silicone caulking in the V-groove of the MicroRax helped improve the grip to the acrylic and create a more rigid enclosure. I ended up only doing this for the front and back panels leaving the side panels removable in case some internal repair was needed.

My one err during this process was not realizing I would want to add some nut-plates to the back panel before it was too late. These nut-plates would let me screw on some additional mounting hardware in the future but with the back panel fully cured I could no longer simply slide the nut plates into the V-groove as intended. Instead I had to dremel out a bit of the V-groove to wedge them into place. In the end it worked, but it did leave a little scar.

Scribe and break the Acrylic
To reduce the number of cuts needed, I ordered the acrylic with a fixed width, this way the side panels would only require one cut to make. I set out with ruler and sharpie to mark out an acrylic panel for scribing, remembering that the cover on the acrylic should be left on until the very end.

For cutting the acrylic I had a tough choice to make, my abode does not lend itself well to a table-saw which is arguably the tool of choice for cutting strips of acrylic, so how am I going to cut these pieces? Well as it so happens I have a saying and that’s “anything that can be done with a power tool can be done with a hand tool.” And as it turned out I discovered a rather convenient way to create strips of acrylic. The tool: a scorer or scribe, like this one on

The scribe is incredibly sharp and will make an awful screeching every time you rake the scribe across the acrylic. You’ll want to apply some good downward pressure to the scribe and get it to really dig into the surface of the acrylic. I ended up scribing across the acrylic five times (5X) per side, that’s a total of 10 screeching scribing scrapes per piece. If it weren’t for the ghastly sound this technique would be the ultimate low-tech solution for cutting acrylic.
Here’s a single scribe pass on one side. Only 9 more…

During the scribing process you can see I’m using one of these big clamping straight edges  to guide the scribe.
After the ten passes of the scribe, I clamp a heavy piece of particle board that was used for a shelf on top of the acrylic and then extend the piece over the end of the work table. With everything clamped down tight and scribe lane sitting right on the edge of the table I press down firmly with both hands to snap the acrylic right along the scribe lane.
The pieces come out a bit uneven but the MicoRax frame allows for loose tolerances. These could be evened out, perhaps with a belt sander, but it wasn't necessary.

Assemble the waffle grid
I discovered that using painted foam was a nice idea to keep the weight of the PixelBrite down especially compared to something like MDF or acrylic which would add a lot of weight. Fitting the foam together, however, was a bit tedious. The interlocking rails were a snug fit and the squeaking sound of foam of foam was sign that it might just be a pretty good pixel separator. One rail at a time the puzzle came together.

Hot glue the pixels to the back panel
I discovered that even though the diameter of the holes match the spec’d size of the LEDs there was enough tolerance that the LEDs would tend to slide out if too much force was applied on the wires. The solution I found was to grab the glue gun and give a couple shots of hot glue to the rim of the LED and then twist it in place. The wires should also zig-zag rather than stick out from the back, otherwise this piece will be too thick to fit into the Ninja box!

Wire additional power and ground leads
Ensuring that each pixel receives the necessary current and voltage requires some additional connections for power and ground connections. I used some twist-on wire connectors or “wire nuts” along with some 18-22awg stranded wire to provide the power busses. I ended up with four power busses and that seemed to create a pretty uniform pixel array.

Build a custom PCB for the electronics
To move the circuit off the breadboard I used a basic PCB prototyping process pretty well documented by Jameco and Make magazine

With a laser printer I transferred the digital layout of my PixelBrite circuit board I’d made in Fritzing  to a 3M transparency. The transparency was cut and mounted in a dollar-store picture frame with the photoresist coated PCB and then exposed for roughly 8 minutes. After developing the resist for about a minute, the board was etched in ferric chloride and after about a half an hour I had a completed PCB.

After drilling the holes the components were ready to be soldered in place. It’s important to remember to cut the power trace on the Teensy board (see PRJC for more info) before soldering in place. This will make it so the Teensy does not try to draw its power from the USB but rather the VCC and GND pins.

Route the acrylic side panel for the electronic ports
For the control panel I decided to keep it quick and dirty by just hand routing the holes for the components… a laser cutter might have been the right tool hear.  I took it slow and made sure I had the acrylic well clamped before starting.

Final Assembly
The best method I found for assemble was to proceed from the bottom up, so start with the back face and the PCB circuit. Drop the side panel in with the bulk head connections and get everything lined up and fixed. Then drop in the LED/waffle grid assembly ontop and connect the 4-pin Molex on the LEDs to the 4-pin Molex on the PCB board from the side. Drop the side panels in place and then press the waffle grid down with the front panel. Tighten the screws on the tricorner brackets and everything should be ready.

As part of this process I discovered the USB panel-mount was bumping into the underside of one of the LEDs. To remedy it I had to mount the USB connector with the flanges on the outside rather than inside.

Load the firmware
The Arduino firmware must be loaded onto the Teensy, get the code from the LeoneLabs PixelBrite repo on GitHub. If you’re just getting started with the Teensy be sure to check out PRJCs Teensyduino Tutorial.
There are a couple of important things to remember in order for the system to run correctly:

  • In the Arduino code:
    • dataPin = 2 (matched to the physical pin of the Teensy)
    • clockPin = 1 (matched to the physical pin of the Teensy)
    • numPixels = 100 (matched to the number of physical pixels)
  • You’ll need Adafruits WS2801 library and the SDFat library to compile the Arduino source code
  • The file names on the SD card need to be short; they are limited to 8 characters with a 3 character extension. This is a limitation of the SDFat library.
    • “Color_bars.pixex” will not work because “Color_bars” > 8 characters and file extension, “pixex” > 3 characters
    • “ColorBrs.pix” will work
  • The SD card will stream from the “PB” folder within the root directory of the SD card so all the patterns and animations must be stored in this folder on the SD card.

Power ON!
Plug in the power supply, flip the switch and plug in the USB port or load a SD card to get started. The pushbutton will cycle through the operating states. There are three states:

  1.  Color swirl
    • This is a hard-coded pattern used just for reference
  2. USB streaming
    • The PixelBrite is waiting for data to be streamed via the USB. The PixelPal software must be loaded up and connected in order for streaming to work. If no streaming is taking place the display will briefly show the color swirl pattern before turning black.
  3. SD card stream
    • If the “PB” folder on the SD card contains patterns, then after advancing to this state the PixelBrite will continuously stream the pattern or animation until the pushbutton is pressed again, at which point it would advance to the next file.

Step 12: Pixel Art Gallery

If you need a crash course on the category of Pixel Art I highly recommend this documentary called: Pixel – A pixel art documentary.

While I didn’t originally intend the PixelBrite to be classified as a piece of pixel art it is easily recognizable as one. The ultra low-res, digital feel is easy to see, however I wanted the pixel art that resulted to be a bit different. I’ve found that there’s a very gray area between pixel art and abstract art, especially as the number of pixels is reduced. Details become textures and then textures become blocks of color, just a palette of tones and hues

Eventually one must ask, where is the line between the actual object and just blocks of color? How few pixels are needed to capture its essence? Some things are recognizable down to 10x10 pixels. Some things you wouldn’t know what you were looking at without being prompted.

If you’ve ever seen or played minecraft you might know the feeling. The representation of a person and his surroundings are modest… to say the least. But somehow it’s all still there and somehow it’s just as fun and possible more fun than if everything were represented in full detail. It’s this kind of experience that I want to showcase, the one where there’s a spark-gap, where your mind jumps past what your eyes see and creates a new world and a new experience.

All the images and animations were all made using the PixelPal app. The videos were recorded as a screencast in order to capture the synchronized audio.

Video Game:

Famous Paintings


Madrix VJ Loops

Corporate Logos


PixelPal Videos

PixelBrite Performance Videos:

PixelBrite Live Music Videos

Step 13: Measurements

Intro and Uniformity
When I first set out to measure the PixelBrite I wanted to see if I could “calibrate” it to make the image look better. To me, this meant developing a way to measure the output of every pixel. I saw Adafruit had just released a color sensor break out board so I thought why not give that a try. Here’s the color sensor: RGB Color Sensor with IR filter - TCS34725 -

I used a Teensy, a cardboard tube, a little circular perf board from Radioshack and some black spray paint to make my own USB color sensor.

After creating a Processing sketch to measure all the pixels I was able to come up with the following image. The picture shows the 10 x 10 grid of pixels on the PixelBrite when they are displaying pure white… which doesn’t look very white does it?

There are several reasons this looks very non-uniform.

1. They are raw measurement values, optical power not perceived brightness, they aren’t gamma corrected and so they don’t visually represent what the PixelBrite looks like (for more info on gamma correction check the following section).

2. The LEDs themselves or the driver circuits have not been calibrated or matched, and so whatever manufacturing tolerances existed appear as variations in color.

a. This would be fine for just the bare LEDs which would normally look very bright and washed out and ones that aren’t meant for displays.

Even after trying to take this data and come up with a way to improve the uniformity I relinquished because it was a bit like chasing your shadow. This uniformity isn’t constant, but rather is varies with the power, so a single look-up table (LUT) would not work. Also, the PixelBrite already looks pretty good, the non-uniformity is not really a distraction.

Much of the design of the PixelBrite stems from the point of removing the hotspot associated with the LED and turning it from a very bright point of light to a nice soft glowing pixel. The following figure (Figure 40) shows the intensity profile from a single pixel. While this doesn’t represent the actual optical power being put out by the pixel, I adjusted the camera settings to match my own eye, it does mirror the intensity seen by an observer. I took the photo

Achieving a perfectly flat pixel profile is very challenging. Initially I experimented with several different pixel geometries, changing both the pitch and thickness of the waffle grid until I found that with these particular brand of LEDs a waffle grid with pixels 50-60mm per side looked good enough.

The concept of gamma or “gamma correction” or “gamma encoding” is a bit tricky to explain but the basic premise is that the complexities of the human vision system require our displays be controlled in a non-linear way in order for them to look “correct.” Here’s the Wikipedia article on Gamma Correction which gives a pretty good run down.

I made two different measurements of the output of the LEDs on the PixelBrite to show what Gamma looks like.

The straight) lines show the linear output of the LEDs as the grayscale input value was increased. This is what you’d expect if you were opening a water valve, open a tiny bit and a tiny stream of water comes through, open it twice as wide and twice as much water comes through. Yet, when this mode is used the displayed image does not look correct, it looks washed out, like the following image shows.

On the other hand, the curved lines show the non-linear output when applying gamma correction. Now when the valve is opened just a fraction only a tiny fraction of water is allowed to pass through, moreover, when the valve is opened twice as wide the amount of water allowed to pass through is nowhere near double as it was previously. While this nonlinear relationship may seem odd, when gamma correction is applied the colors of the images look much more realistic or “correct.” See.

Using the actual part of the color sensor, the part that measures how much red or green or blue, was actually a bit disappointing. The color sensor uses narrowband color filters to get the individual readings for the red, green and blue channels. As it so happens, the output of the LEDs do not match the filters and so if the green channel gets a little red and blue light too (and there’s some green in the red channel, and green blue channel as well), so for trying to calibrate colors it’s a bit of a mess. As a result I just ended up using the “clear” channel to make all the measurements and just do it one color channel at a time.

Pixel-to-Pixel Contrast
As you may have noticed, the waffle grid does not perfectly isolate the light from one pixel, instead some light bleeds through. This is partly from the semi-opaqueness of the painted foam and also partly from the slates where the pieces interlock.

I attempted to measure this with the color sensor but with the acrylic in place the light leaking into the neighboring pixels was at the noise floor of the sensor. I ended up taking off the acrylic and measuring the pixels without it in place and the measurements indicated about a (100-150):1 difference in optical power between the pixel ON in the middle and the pixels directly next to it.For most “realistic” images this isn’t very noticeable but it does mean that pixels are talking to one another and the colors we’re seeing aren’t exact matches of the colors we want to display. It’s more noticeable with abstract or binary-type patterns. Here’s some checkerboards which illustrates this effect.

Step 14: Project Meta Data

This is a bit like the bonus features on a new Blu-Ray. I included a little extra info at the end of my last Instructable so I thought I'd do it again.
  • I shot most of the footage with the Pentax Q camera I won in the last Instructable Contest
    • This also means most of the original footage is 1080p rather than the 720p I was working with before.
  • I started down the road of building LED pixel panels back in 2010 when I bought my first Arduino and a bunch of ShiftBrites
  • I upgraded to Adobe Premiere for my video editing
  • I'm still using Microsoft PowerPoint for annotations and markup
  • I used a free font called "KG Second Chance" for the title, and "Denne Marker" for the text. Get in touch with me through my website

    Shout out to the open-source, DIY, maker community. As always, this wouldn't have been possible with you.

    Final Note:
    I've been pushing hard to try and get this project finished by the deadline for the Epilog Laser contest and the Battery-powered contest. It seems I made it just under the gun, so If you enjoyed please show your support with a vote. Thanks!
Epilog Challenge V

First Prize in the
Epilog Challenge V

Battery Powered Contest

Finalist in the
Battery Powered Contest