Jurek and the Amazing Techno, Colored DreamWall

Jurek and the Amazing Techno, Colored DreamWall

The title is mostly a placeholder, as I haven't really figured out a name for it yet. This project is a wall hanging that consists of semi-large triangular pixels using discrete RGB LED's and PWM to control intensity levels of each LED, resulting in a 4096-color display.

Friday, November 10, 2006

Progress Update & Videos


A friendly reminder that the Level_13: Bonus Round art show is opening on Friday, November 17th at 6pm! As always, there is no admission, and refreshments are provided.


I finished mounting the switch for controlling the pseudo-random seed, on the same section as the power plug. The switch has a slightly unsmooth feel to it, but what can you expect from a $0.50 RadioShack switch?
I also removed some of the felt from the wall on the bottom half and replaced it with velcro. The bottom piece of acrylic wasn't holding up very well, so I needed some more sticking power on it. I'll probably do some more, but what I changed seems to have helped immensely.


I've made huge strides in the coding since the Sunday videos.
Things I've added:
  • 2 new still images
    1. strawberry
    2. ghost (4 color variations)
  • 2 multi-frame images
    1. Fireball is a 4-frame animation
    2. goomba is a simple 2-frame animation
  • 2 new emitters
    1. emitter_single - colors the given pixel according to a palette index value
    2. emitter_random - turns on/off (19/81% probability) a number of pixels
  • 4 new transforms
    1. triple spiral
    2. multiple spiral
    3. starburst
    4. zigzag
The new transforms all use a basic encoding scheme, so adding new ones is a relatively simple process. It's pretty simplistic and only allows me to encode 4 different actions per pixel:
  1. keep the same value
  2. get left neighbor's value
  3. get right neighbor's value
  4. get top/bottom neighbor's value
The transform map for this only takes up 30 bytes of storage (4 pixels per byte), which still leaves me with plenty of storage in reserve. If needed, I could bump this up to 60 bytes and have more complex actions, such as 2- & 4- pixel averaging (basically making the "neighbor average" function a simple map). I think currently, I'm using 602 of the 1024 available external RAM of the processor.
  • 3 channels * 120 pixels * 1 byte = 360 bytes for pixel value storage
  • 120 pixels * 1 byte = 120 bytes for temporary pixel value storage (for transform functions)
  • 16 colors * 2 bytes = 32 bytes for color palette value storage
  • 120 pixels * 4 bits for index value = 60 bytes for image map storage
  • 120 pixels * 2 bits for transform mode = 30 bytes for transform map storage
  • -----------------------------------------------------------
  • 602 bytes of external RAM storage, leaving me 422 bytes left to use!

So... on to the goods...

One of my coworkers was nice enough to lend me his video camera for a couple days, so I could take some real footage of the wall in action. I've taken and encoded 2 videos. One weighs in at 2:34, and the other is 7:00 long. I've provided 2 different encoding options, .mov and .wmv.

Shorter video, 2:34
QuickTime 4.09MB
WMV 8.56MB

Longer video, 7:00
QuickTime 46.7MB
WMV 24.7MB

Labels: ,

Sunday, November 05, 2006



I got a few more switches for the fan and the pseudo-random number generator seeder, got them mounted (I still need to mount the pseudo-RNG switch somewhere), and gosome felt glued to the back side of the pegboard. This last part was an attempt to protect the boards somewhat from the outside elements. It should stop small stray debris, small amounts of liquid, and thin metal rods (e.g. screwdrivers) from coming in direct contact with any of the boards or the terminal strips.

I also bought some hanging brackets and started working on a way to secure the pegboard to the wall. Currently, I'm planning on securing (Liquid Nailz) several pieces of wood on the back side and just using velcro to secure the pegboard. Some larger pieces of wood and a few holes cut into the pegboard should be sufficient to mount the hanging brackets, in case I want to bring it up off the floor at all.


This is the real reason for the post, however.
Behold, lots of eyecandy!

4.1MB QT4.0MB QT

4.0MB QT4.0MB QT

I'm sorry about the short videos; my camera can only take up to 16 seconds at a time.

These videos show the 6 still images I've designed (from this directory), as well as the single generator I've got coded up (edge emitter). Also shown are several of the transforms in action.
For the still images, it picks between two different transforms:
  • fade
  • neighbor average
Fade works like I described in my previous posting: simply fading from the current color to either black or white (exclusively black in these videos).
Neighbor average takes the value of each pixel plus the 3 adjacent pixels, and averages them to compute the pixel's value. Over time, the whole board turns to black because there is a certain amount of information lost with each average computation that takes place.

For the edge emitter, there are two transforms that are being used at the same time:
  • fade
  • translate
Both work as I described before, and the translate always works in the direction opposite where the emitter is positioned; if it's generating pixels on the left, the translation happens to the right.

Right now, I'm using about 5.2kB of codespace. Each of the still images takes up a moderate amount of space (~600-800 bytes), so I can't have a huge amount of them. However, I'm still well under the 32kB of available space.

The bigger issue currently is speed. The neighbor average function is very expensive, mainly because I have to keep an equal-sized pixel map to calculate the new values and then copy the new pixel map over to the old one.

Labels: ,

Friday, November 03, 2006

Post-vacation Assembly


I'm back from my vacation and have spent a little time tonight working on the wall. I've finished attaching the velcro to the acrylic/contact paper and have basically finished the routing/securing of the cabling in the backside of the wall. I have yet to mount a few of the switches (microcontroller power switch, fan power switch), and I've got to glue some felt on a few places on the pegboard (for protection of the boards), as well as gluing the A/C power receptacle.

After all of that is done, all I need to do for this module's assembly is attach some blocks on the inside to allow me to secure the pegboard, as well as provide mounting brackets for hanging it. I will probably put 4 pieces on the top (all near the very top of the wall) and 2 pieces in the bottom. There really isn't a whole lot of room in the bottom, and I will have to rearrange some of the wiring as it is to make room.
Hopefully, it won't be too much of an issue. I was only planning on using Liquid Nailz to attach it, and that should definitely hold it well enough.

'Til next time...


Thursday, October 26, 2006

Status update

This will be a pretty short post. I am leaving on a vacation for a week and won't update the blog (or the wall!) until at least next Wednesday (Nov 1st).


I've got all 120 pixels glued in and working!!! whoo hoo! Let's add a few more exclamation points just to show how happy I am!!! OK, two more!!

All my progress was not forward, however. It saddens me to say that one of my driver boards is now not operational. During my testing, I noticed that the red LED on one of the pixels wouldn't work (out of 360 LEDs, only 1 didn't work... not bad). I tested a bit and eventually figured out that the pin for this LED from the driver chip wasn't making good, solid contact from the driver board. I could press down on the chip a little and then the LED would work again.
I tried resoldering the connection, but that only proved to make things worse. After resoldering, all of the surrounding LEDs glowed faintly, indicating a leakage voltage somewhere.

Luckily, I had made 7 driver boards, so I grabbed the remaining one and it works fine.

Everyone is just going to have to take my word for it that stuff is working great. I'll get some pictures and videos up when I get back. I promise!

Oh, and for those that are wondering just how crazy I am, I've put in 56 hours in the last 2 weeks (and that's with no work on Wednesdays and only half of Sundays).


Sunday, October 22, 2006

Mondo Update

LED Segments

I've gotten 20 more of these done! That puts me at 152/240, with 2 more needed for this first module. I will probably do them a little tonight and then finish them up Monday or Tuesday. After that, I can stop for a while (thankfully). My fingers are pretty sore and sensitive from the heat and metal.


I had to remove one of the pieces of contact paper from one of the pieces of acrylic, because the velcro I had been using just wasn't cutting it (or, more precisely, was burning it from the hot glue). I bought about 30ft of self-adhesive velcro, 3/4" thick, and used a fabric cutting wheel to make nice, straight cuts along it (gotta cut it into thirds!). This works wonderfully, as the adhesive on the velcro is unlike anything I've ever seen. It stick amazingly well to basically everything.
Anyway, I got a new piece of contact paper put on the acrylic and spent a couple hours today putting the velcro on it. The first (bottom) piece of acrylic is now completely done and looks "OK". I say "OK" because there are still air bubbles randomly throughout it and a few minor holes. Not the best job in the world, but I'm now under a small time constraint (read below).

I finally got the processor board mounted to the wall, along with the different switches for reset, ISP, USB unload, and power supply selector. The only switch I have yet to mount is the main on/off switch. The switch I've been using isn't the one that I plan on using, so I haven't made a hole for it yet. Actually, I'm not sure if I will even use a switch right away. It's not entirely needed (the main power switch works fine) and especially not right away.

Here're some pictures of the guts behind the pixels (and man is it messy!):
InternalsPower SupplyProcessor MountProcessor Mount, with labelled switches

There're still plenty of wires to add, such as power & control cables for the "upper" 3 boards, as well as finalizing the cabling for everything. You can see in the overhead shot that there are orange, purple, and grey clip cables attached to random squiggly wires. These are the reset lines for the boards, and I'm going to be tying them to power directly, but I don't want to route the cables completely yet. Once I get all 6 driver boards working, then I will finish that step.

The processor and switches are mounted on the opposite side as the power supply, with enough room to take up the two remaining compartments (the angled compartment on the end is barely used).

You can also see the two fans (poorly) mounted for cooling. The one on the right blows into the area, whilst the one on the left blows out of it. They probably don't work too well, considering that there are large open areas for the air to simply escape through, instead of cycling the hot air around the power supply. I'm still not entirely sure how much cooling will be needed. I started doing some temperature measurements without the fans running, but the battery for my multimeter died, so I couldn't test any more. After about 3-4 hours of running 1/2 of the pixels in just 1 module at about 20% capacity, it rose from 74F to about 95F. Once I get everything running, I'll try turning all 120 pixels of module 1 on full white and just leave it there for a couple hours. If all goes well, it shouldn't get much above, say, 130F, which is still fine as far as I'm concerned.

I cut a small notch in the internal wall for the power supply source switch, which fit nice and snug in there. It's currently only being held in by duct tape (I don't think "duct tape" is even used by HVAC technicians on ductwork), but that can be "enahanced" with glue later. The other 3 main switches are all mounted on a simple strip of galvanized hanger strap. The large holes worked perfectly for the threading, and it's stable enough for what I need.
The large terminal block looks very similar to the one next to the power supply (which is used for power!), but is for the TWI bus. This seemed like the most effective method of breaking out the bus from the processor to the 6 boards that all require the same signal.


I've begun coding up a few basic tranform functions to apply to the wall. Currently I have:
  • Inversion (inverts the colors of all the pixels... red -> cyan, black -> white, yellow -> blue, etc)
  • Shift up/down/left/right (shifts all pixels up/down/left/right 1 row)
The inversion can be enhanced to only invert certain channels (e.g. only the red channel)
The shifting functions can either roll over the shifted-out pixels, or just shift in a blank (black) pixel.
If you combine "shift up" with "shift left", for example (or "shift down" with "shift right"), then you get a tranform that shifts all pixels along the upper-left/lower-right axis (there are 3 axes with triangles, not the normal 2 with rectangular ones!). Likewise, combining "shift up" with "shift right" (or "shift down" with "shift left") translates the pixels along the upper-right/lower-left axis.
Simple, but powerful stuff.

Other potential transform functions are
  • Average (averages the surrounding 3 or 12 surrounding triangles)
  • Rotate (rotates the pixels 60 or 120 degrees about a given pixel)
  • Fade (slowly fades the pixel from its current value to black (or white, or any given channel!))

I managed to find, in the documentation, the status bits for controlling the speed of the TWI bus. I think, by default, the transmission speed is set to 62.5 kHz. By setting the speed bits to the fastest setting (266.6 kHz, a 4.3x speed increase), I was able to increase the framerate of the wall by about 50%. This was a very welcome change, indeed. Hoo-ray!


Some of you may have been wondering why there has been a huge bump in the progress in this project over the last 2 months. Indeed, I've put in 27 hours this previous week, and 85 hours since September 1st. Well, there is reason for this, and quite an exciting one (for me, at least).

Now that it's official, and I've committed myself time-wise for it, I feel I can mention that the "technowall" (NOT the official name!) will be part of the upcoming (Artist's reception/opening is on November 17th) video game art show at Altered Esthetics: "Level_13: Bonus Round!". Their address at the time of the show is:

Altered Esthetics
1224 Quincy St. NE
Minneapolis, MN 55413

This is just off Broadway and Central; for those that need directions, please consult your favorite mapping website. If you need more information than this, please contact me.

I will only have the 1st module done, and won't have any computer interface ready, but I will be spending a fair amount of time with coding to get various random (and not-so-random!) patterns working. The pseudorandom seed switch (see the October 10th post) should keep everything random enough for my needs.

I have already designed several patterns, as well as a few other neat designs, with more to come (hopefully). If anyone wants to try their hand at designing something, here is a PNG template that I've been using:

Please email any creations to me! I'd love to see people's creativity with such a small (and oddly-constrained) resolution!

Exciting news!

Labels: , , ,

Wednesday, October 18, 2006

15x4 pixels done


Well, now that I got my latest Digikey shipment in, I was able to wire up the TWI bus properly so I could connect more than one driver board to the microcontroller. I tested this out yesterday (10/16) and had a minor scare.
In my haste to get everything connected up to test, I accidentally wired up one of the power cables backwards. I first plugged everything in and hit the power switches, but nothing turned on. After flipping everything off and on a few times, I tried to see if somehow I connected things incorrectly. Everything seemed to be conducting properly, but then I noticed that the red and black wires were swapped going into one of the boards!

Oh noes!

I quickly disconnected everything, and the power cables were a bit warm. The ground pin for the TWI bus coming into both the driver boards had started to melt the plastic socket, and the header pin on the board itself had started to tarnish and turn black. I swapped the wires, plugged everything back in, crossed my fingers, and turned everything back on. Much to my relief, everything started working fine. The wiring was crazy messy, but at least the code was working fine for 2 driver boards.

So tonight, I set out to clean up most of the wiring. I started with the power supply and got that all organized and routed well, and even managed to install both the fans I bought for cooling. It took several hours to do that and reroute/organize the power and data cables going to the driver boards. Everything looks much better now and can handle all of the cable routing needed for the upper half, plus the power cables needed for the second module.

Video of 15x4 pixels running (3.9MB QuickTime)

Video, sans diffuser (3.0MB QuickTime)

So far, everything's holding up to the scaling from 4 to 12 driver chips, as it should. The only problem now seems to be speed. In the video, everything is running at about 15fps. This isn't horrible, except that this is with only 1/2 of the final number of pixels, so the final speed will be about 7fps. In my opinion, that is unacceptable for what I want.
I have managed to tweak the SDCC compiler to make things a bit faster, but I don't know if there are many tweaks left that I can do to speed it up any more. I will have to dig into the code and see what I can do for shortcuts. Right now, there are quite a few extra steps it's doing each and every time for computing the color value, so that's probably going to be my main focus for optimization.

More to come!


Thursday, October 12, 2006

Gluing progress

20 more pixels glued into place. That leaves me 33% done with the gluing. This round went much faster than the first time. Woo!

I've just been playing around a little bit with things here and there. Currently, there's not a whole lot I've been really attempting. I would like to have some sort of unique pseudo-random number generator. Pseudo-random is fine for what I need, but that's only as random as its initial seed, which is deterministic for the microprocessor without any sort of analog input (white noise, ADC, user input, etc). I think the easiest approach currently would be to have a small switch on one of the unused ports that can be pressed at any time while it's running that would update the seed. I could just have an unsigned int as a counter for the main loop, and whenever it detects the switch as closed, I can just call srand with the counter as an argument.

I'm going to be ordering a few odds and ends (wire, terminal blocks, crimp terminals) for the current stages I'm in.
I've recalculated a few times how many of each length of LED triplets I will need, and with my current calculations, I need to solder 31 more triplets of various lengths (2 10", 17 8", & 12 4") for the first module.

Labels: , ,

Saturday, October 07, 2006

Pretty Colors!

I made some more good progress today. I got 20 of the pixels glued into place (the first driver board I was testing with Thursday). This means a far better color mixing than Thursday's video had. As you can see by the first video (4.2MB), there are really very few hotspots at all and you have to look hard to find them.

The second video (3.4MB) was a request by someone who wanted to see the LEDs in action without the diffusing acrylic. It still looks pretty neat and gives a bit different of an effect. Maybe I can make 2 different tops, one that's the standard acrylic with contact paper and another that's either clear acrylic or slightly-buffed/sanded.

Yes, I actually have made a small amount of progress in the coding department today. There were a couple bugs and inconsistencies with the way I was coding everything up. I wasn't able to address a single driver chip individually, so I was seeing some rather odd side effects whenever I tried.
The main issue I tracked it down to was P0 (one of the I/O busses) not working at all on either the starter kit board, nor my own board. Perhaps there's a processor register setting that I'm not doing to get these ports to work properly; I'll have to dig through the manual.
As is evident in the videos, I am quite able to address each driver chip individually.

I also tested to see how white "white" is, and it's rather sad and abysmal. On most pixels, it's quite pink (red is overpowering), and in others, it's purple or blue (green is underpower). It's a little late in the game to fix this, so I guess I'll just have to live with it. Oh well... :/

Labels: , ,

Friday, October 06, 2006



There is a certain amount of celebration in order!

I cobbled this up last night. The color mixing is absolutely horrid, because this movie was taken upside down (the wall is sitting on sawhorses, backside up) and the LEDs are just hanging in the pixels. I haven't glued them down yet, because I wanted to make sure everything still worked.
I tested to make sure all the individual colors still worked, and I tested first with the starter kit board then my own board, and I'm quite happy to report that it still works.

I still have to figure out how to connect the TWI bus to all 6 boards (it's pretty trivial to connect to 1 board, but I don't have TWI outputs on the driver boards... oops). Perhaps I can use another 8-position terminal block. It seems a bit overkill, but whatever works in the end, I guess.


Friday, March 10, 2006

Construction and Testing

I now have 3 pieces of wood attached to each other. These are the real-deal pieces and I've taken great care in aligning them and making sure that all the nail holes are correct before doing it. I used wood glue along the floor plywood and outer wall joint as nails really aren't enough. On the inner wall connection, I've only used 4 L-brackets without any glue, as I need these sections to be able to be disassembled (for now). At this point, I just need to start cutting more floor plywood pieces so I can continue.

I've done a bit more testing on my soldered uC board tonight. I soldered on the reset switch, ISP switch, and USB unload switch and verified that Windows can recognize it when I perform the correct switch incantation ritual. The uC programming software correctly connects to it and I've successfully programmed code to the device. Whee, yet another hurdle checked off.

I also extended the LED blinking program (BLINKY) to send signals to all 32 I/O ports available (the P4.1 & P4.2 are used solely for the TWI) and verified with LEDs that they all work. So far, so good.

The only major things I haven't tested yet are the ADCs. I have a bunch more to do, like get the TWI working with the driver boards, so I have a bit of testing yet to do before I get to that stage. As a simple test of the ADCs, what I've envisioned is just hooking up LEDs to each I/O port and then have it be a 32-position bar chart, displaying the values returned by the ADC. I can then test this on each of the channels of both chips (there are 8 channels per chip).

Progress marches on!

Labels: ,