Wednesday, September 11, 2013

RGB Glasses

After my green LED glasses worked out so well, I decided to expand on the idea and build a new pair with more capabilities. The most notable upgrade is they are RGB instead of just green, but they also include 7 individually-controlled groups instead of all LEDs operating the same. This allows me to run animations spatially across the frame by showing different colors and brightnesses at different locations.

The LEDs I used are Cree PLCC6display LEDs. These are perfect for this application because they have the red, green, and blue emitters set behind a diffused optic that mixes the colors, and the package is shaped to throw light only forward without secondary optics. I had a rough guess at how many LEDs would fit on the frame based on how many XP-Cs I fit onto thelast pair (about 53). Wiring that many LEDs with three times the connections for colors would be impossible to do by hand so I started laying out a PCB.

I used ExpressPCB for the project so I could get the boards quickly. The layout software is not very full-featured, so my first step of modeling the shape of the glasses frame was tedious. I'm using the same glasses I did before, they're cheapo sunglasses from Walmart. Once I had the frame modeled I started filling it with LEDs. The recommended footprint for these LEDs is oblong (despite the LEDs being square) to give runout room on the solder pads, so I had to pay attention to keeping spacing consistent between the horizontal and vertical segments.

I had originally planned to include control electronics directly on the back of the PCB that held the LEDs, but after chaining together the R, G, B, and common anode channels, there was no room left at all. This meant I wouldn't be able to have as many individual groups as I wanted. The final LED count came out to 70, which severely limited the possible arrangements of groups I could choose from. At this point I decided that the best plan for current regulation would be to use AMC7135 regulators for the low side of each color channel. These regulate to 350mA, and since the LEDs are rated for 35mA max per color, I split the LEDs into 7 groups of 10 LEDs each. The cathodes for all 70 of each color are connected, and the common anode for 10 LEDs in each group are connected, leaving 11 connections to wire out to the control board. 7 groups is annoying to work with in an 8-bit system, but it worked out well based on the shape of the glasses—two segments on top, two on bottom, two sides, and the nose in the center.

The control board uses a PIC16F1829. Six pins are devoted to communication with the nRF24L01+ 2.4GHz radio module through the SPI port. Seven pins operate the P-channel FETs that switch the high side of each LED group, and three pins on PWM channels run the low-side regulators for each color. That left only one I/O pin open, and since I knew I wanted to do a sound-reactive mode at some point, I broke that pin out to a wire pad in case I decided to use it. I designed the board to allow the radio module to plug in and stack on top of the control board, but in the final assembly I decided that was too tall and wired it out to lay next to the control board.

In order to get the price break on ExpressPCB's Miniboard Pro service, I split the LED sections up and packed them into the 2.5x3.5” space to be cut out by hand. The board also includes the glasses control board and the remote control board (worn on the wrist). After assembling the glasses I realized that splitting them up like this was much better than trying to keep them as one piece because they needed to wrap around slightly to conform to the shape of the glasses, and the split sections allowed bends. I actually ended up putting extra cuts in the PCB later to bend it further.

Cutting and populating the boards was straightforward once I got them. Boards are connected to the glasses frame with hot glue, and everything is wired together with black 30AWG wire-wrap wire. Since these are fairly low power, I included a small 120mAh lithium ion cell directly on the glasses so they can operated standalone (with no external battery pack and cable). In most modes, this cell can run the glasses for about an hour.

After the initial build I did add a sound-reactive mode and the hardware required to do that. I used an electret microphone with an opamp. The opamp has its input ac-coupled to the microphone, puts it through a 100:1 gain, ac-couples the output with a Vcc/2 bias, then low-pass filters that to shed anything higher than 250Hz. This is fed directly into the ADC on the microcontroller. The opamp circuit was free-form assembled and wrapped in heatshrink, which occasionally seems to cause a weird feedback loop effect.

Even with this level of complexity in the hardware, the software was more complex still. I set up a multiplex routine in the timer interrupt that cycles through each of the 7 groups at 1kHz. There are two arrays that control the output—brightness and color, with 7 bytes in each array corresponding to each LED group. Brightness is a full 8-bit value that sets the overall intensity of the light on all three channels in the group. Color is a 5-bit value (+1 for white, so 33 values) that corresponds to a mix of red, green, and blue to make any color. This way I don't have to crunch a lot of data to set individual R,G,B values for each channel, I just select and manipulate a single color value. Every time the multiplexer is called, it uses the color value to call out to lookup tables for the R, G, and B values that correspond to that color. These values are then multiplied by the overall brightness value for that group, and finally bit-shifted back into the 8-bit range before being output onto the PWM for the color channels.

With the multiplexer running in the background, the main loop can run color and brightness patterns by manipulating the two 7-byte arrays. Animations are often made simpler by moving values around within the array instead of calculating them from scratch. The software is built in my usual structure, with the main loop only acting as a task handler and single instances of tasks initiated by interrupt actions and sometimes by other tasks.

The modes of operation are split into brightness modes and color modes, and a combination of any brightness mode with any color mode is allowed. At the time of writing this, there are 21 color modes and 17 brightness modes, for a total of 357 possible operating modes. (while we're crunching numbers, I like to quote the total possible operating states at any instant (loosely defining “instant” because I’m talking about time-based PWM for brightnesses plus multiplexing) based on the degrees of freedom I have. With the original green glasses, it was 2^8 = 256 states. These glasses have: ((2^8)^3)^7 = 3.74x10^50 possible states.)

Demo of color modes (read the list first, otherwise it's hard to tell what's going on):

Demo of brightness modes:

Color modes:
Smooth chase – rotates the whole spectrum of colors around the glasses, gradually transitioning between colors
Gradual chase – hard to describe; chases around the glasses with a new color that very gradually transitions through the spectrum. Watch the video to see
Full chase – rotates the whole spectrum of colors around the glasses; mostly obsolete after I wrote in smooth chase
All same – gradually fades through the whole spectrum, but with all 7 segments acting together
Stepping – steps through all the colors one by one, all segments together
Chase stepping – like stepping, but when it transitions to the next color, the new color chases around the glasses until it has filled all 7 segments
Fire – emulates fire with reds, oranges, and yellows. Pseudo-randomly generates a new red-orange color on the bottom row, then advances that color up towards the top of the glasses, turning it yellower as it goes
XYZ – not yet working. Attempting to set R, G, B color levels from accelerometer X, Y, Z values
White -
Red -
Green -
Blue -
Violet -
Yellow -
Turquoise -
Pale blue -
Pale green -
Eyes blue green – one eye blue, the other green, middle segment is the color in between
Eyes blue red -
Eyes red green -
Stoplight – red on top segments, yellow in the middle, green on bottom segments. I added this to be used with the VU meter brightness mode

Brightness modes:
Sound-reactive – pulses brightness to the beat of music
VU meter – shows audio levels like a meter, rising higher on the frame with louder sounds. Not yet working very well
Chase – chases around the frame
NRZ (non-return to zero) chase – chases around the frame but doesn't turn segments all the way down to off
DC (discontinuous) chase – chases from one corner of the frame all the way around and then goes away, repeats after short delay
Bracelet pulse – reacts to motion, same function the old green glasses did
Auto pulse – pulses overall brightness up and down
Eyes pulse – fades brightness back and forth between the two eyes
Bracelet strobe – same as bracelet pulse but strobing at the same time
Strobe -
Bracelet chase – chases brightness around the frame, but scales overall brightness in response to motion
Low chase – chase at lower overall brightness
Twinkle – randomized flickering of all segments (originally added for use with the fire color mode)
Slight twinkle – less intense effect
Max – full brightness
Low – 6.2% brightness, the lowest it can go and maintain full resolution on colors
Very low – 2.7% brightness, colors lose half their resolution at this level

There is a color mode updater that handles changing color actions when it is called periodically (triggered by timer interrupt), and a similar brightness updater. All of the changing modes are created by state machines that are called periodically, make quick updates, and go back to the main loop. Other task handlers are the radio update to get new data, mode changers, and the audio analyzer.

All of these functions are controlled by the bracelet. The bracelet has the other PCB that was on the board, which is basically just a PIC16F1824 with a radio module connector and breakouts. It sends data up to the glasses over the 2.4GHz link based on input from two buttons and the 3-axis accelerometer. This is all powered by a tiny 70mAh lithium ion cell. All of these components are attached to a nylon watch band with hot glue. One of the switches on the bracelet advances color mode, and the other advances brightness mode.

In the end, I couldn't be happier with how these came out. I have to fight the urge to wear them everywhere all the time. Thanks for reading this extremely long post; you can see more pictures of these if you scan the crowd in pictures from Raleigh-area EDM shows in the coming months:

Here's the code for the glassesand the controller.

No comments:

Post a Comment