Arduino-controlled RGB LED Infinity Mirror

FeaturedContest WinnerContest Winner
Picture of Arduino-controlled RGB LED Infinity Mirror
Update 11/22/2013: Thanks to everyone who voted for this project in the Microcontroller Contest! It was one of three first-prize winners.

Update 9/17/2013: Thanks to everyone who voted for this project in the Arduino contest (I was one of ten "second prize" winners)! If you want to try this project with an addressable LED strip instead of an analog strip, check out the Rainbow Jar project (also an Arduino contest winner).

This is my take on a combination of two classic projects: RGB LED control with an Arduino, and an Infinity Mirror. It's an RGB LED infinity mirror that lets you toggle between an adjustable-speed color-fade mode and a direct-control mode where you individually set the red, green, and blue LED brightness levels. The primary inspiration for this particular project comes from this infinity mirror Instructable and Adafruit's RGB LED Strip tutorial, but there are many more quality resources out there on both projects.

I've done my best to gear this project towards newbies by providing an exact list of materials I used and the exact procedure that I followed. One recurring theme I've noticed in comment sections for other infinity mirrors is a lack of links to specific parts (e.g. exactly what type of LEDs or LED strips were used, what power supply, where to buy the mirrors, the enclosure...). Clearly, if you know what you're doing and want to spend more (or less) money to design a slightly different mirror, you can adjust your materials as needed, use a different Arduino board, etc. You can skip the Arduino entirely and make a pretty simple, cheap infinity mirror if you want (just search Instructables for "infinity mirror" and you'll find a few), or go crazy and spend hundreds if not thousands of dollars (search YouTube for "infinity mirror table" and you'll get the idea).

So, on to the materials list. Remember that this is an exact list of parts that I used, but I gradually cobbled together the supplies for this project over a long period of time. I didn't sit down, compare vendors (e.g. Adafruit vs. Sparkfun) and find the absolute cheapest way to build this. So, feel free to shop around to bring down the cost (and post links in the comments if you find a better/cheaper version of a certain part!). Quantities are just 1 (one) unless otherwise noted, prices are rounded to the nearest dollar as of September 2013.

Materials: Electronics

  • Arduino UNO R3 with mini breadboard and jumper wires. I have the Getting Started with Arduino Kit from Maker Shed ($65).
  • (Optional): Arduino/breadboard holder. The Maker Shed kit didn't come with one - I 3D printed this cool minimalist design I found on Thingiverse.
  • 1 meter RGB LED strip ($25). This is an analog strip, which means you can only control the color of the whole strip at once. SparkFun also carries a digital RGB LED strip which has individually addressable LEDs (if you wanted to send pulses of light down the strip one LED at a time, or have some other pattern), but it's more expensive ($45) and you'll need completely different Arduino code. Both strips can be cut to length to fit your mirror.
  • Four 10K potentiometers ($1 each).
  • Three N-channel MOSFETs ($1 each).
  • SPDT power switch ($1.50).
  • 22 AWG hookup wire (black), 100 feet ($8). This is only required if you pref to color-code your V+ and ground connections with red and black respectively. Otherwise you can just use the multi-colored jumper wires that come with most Arduino kits. 100 feet is also WAY more than you'll need for this project, but you can never have too much hookup wire! You can get a smaller 25' roll from SparkFun.
  • 22 AWG hookup wire (red), 100 feet ($8). Same note as above, with smaller roll here.
  • Barrel jack breadboard adapter ($1).
  • 12V/5A DC power supply ($25). This is a big place to potentially save money. The RGB LED strip I used requires 12V, and according to the datasheet, draws 60mA for every 3-LED segment (the smallest unit the strip can be cut into). So at 60 LEDs for the whole strip, that's an absolute maximum of 1.2A at full brightness. I had a 12V charger laying around from some old long-forgotten device, but it was only rated at 0.5A and couldn't light the whole strip. So, I went ahead and bought a beefy supply because I figured it would be useful for future projects anyway. Adafruit and SparkFun both carry smaller, cheaper 12V supplies (1A and 600mA respectively) that might suit your needs just fine depending on the size of your mirror and how many LEDs it will use. You could also scavenge something like an old laptop charger, but be sure to check the output voltage and current specs (usually printed on the label).
Materials: Building the Mirror

Important: there are three main parts that need to fit together to build this: the regular mirror, the frame, and the one-way mirror. First, it's easiest if you can find a cardboard/paper mache lid and a regular mirror that will fit snugly inside it  - the parts I bought didn't fit together perfectly, so I had to use a workaround (see Step 6). Second, cutting acrylic can be a pain depending on the tools you have available, so plan accordingly (see Steps 9 and 10). There's also an important consideration regarding the LED strip, which can't be cut to any length - it has to be cut in multiples of 3-LED segments, which are just shy of 2" long - so you want the inside perimeter of your mirror frame to be a multiple of that length. So, I'll link to the parts I used to build my mirror, but you can still follow these directions to build a mirror of a different size or shape.

  • 9" diameter circular mirror. I bought this kit of 7 mirrors ($14) with the intent of also making some smaller infinity mirrors. 
  • Kit of 8", 9", and 10" diameter round paper mache boxes ($9). Important - I bought these hoping that the 9" diameter mirror would fit snugly inside either the 9" lid or the box itself (and because I couldn't find individual boxes for sale on Amazon). It didn't. The 9" lid was just too small, and the 10" box was too big. So, I made it work by cutting out the top of the 9" lid, and just using the rim. This will make sense if you skip ahead and look at the pictures in Step 6. Point being, ideally you should use a mirror that fits snugly inside a paper mache lid or box.
  • 1/8" thick 12"x12" sheet of clear cast acrylic (plexiglass). Available on Amazon ($8) and McMaster-Carr ($9). Acrylic is super easy to cut if you have access to a laser cutter. I don't, so I tried using a jigsaw (Step 9) and a score-and-snap method (Step 10). Both worked reasonably well but resulted in some jagged edges, and in hindsight would have worked much better for a rectangular mirror instead of a round one. If you want to build a slightly smaller mirror, McMaster sells pre-cut 6" diameter circles. I didn't shop around much for larger pre-cut circles but you might be able to find them.
  • Mirrored window tint. I ordered this stuff from Amazon ($27) but you can easily find this in hardware stores. Probably hard to find in small quantities, so plan on having plenty left over.
  • Black paint. I picked up a can of generic black spray paint ($3) at A.C. Moore.
  • Optional: if you want to get really fancy, you might be able to order a custom-sized one way mirror, instead of putting mirrored window tint onto a piece of plexiglass. This will probably give you a higher optical quality in your final product, but I didn't look into it.

  • Soldering iron. I have this variable temperature one from SparkFun ($45). You might be able to get away without one, depending on how your LED strip arrives. The SparkFun product page says "You will need to solder on your own wires.", but my strip arrived with all four wires already soldered on. Even so, pushing the ends of the (stranded) wires into a breadboard can be a pain, so I recommend soldering on small segments of solid-core wire to make that easier.
  • Lead-free solder ($8).
  • Wire strippers ($5), if you don't already have a pair that can strip 22 AWG. Again, you can squeeze by without these if necessary, but I'm betting most people reading this have wire strippers.
  • Mini needle nose pliers ($2) if, like me, you're clumsy and hate handling tiny breadboard components with your fingers.
  • Power drill (see Step 6 - you can probably just get away with a sharp knife)
  • Super glue
  • Electrical tape
Got all that? Time to start building!
Remove these adsRemove these ads by Signing Up
1-40 of 50Next »
dushu made it!8 days ago
petrichw2 months ago


I wanted to customize this into a 3D triangle. Could I program one Arduino with the two extra infinity mirrors I will make?

Ben Finio (author)  petrichw2 months ago

It depends which Arduino board you use and whether you want to control the colors of the three mirrors independently or not. You need 3 PWM outputs per mirror for independent control. The Arduino UNO only has 6, but the Arduino Mega has 15.

An alternative (and I've never done this myself, so can't provide great directions) is to look into "shift registers". This page says you can "control an almost endless amount of LEDs with only 4 pins", but I'm not sure if that works for PWM control or if it's just on/off:

Hawkens2 months ago

You can purchase mine by clicking the link below, while in the same time help me finish the larger project, and make the infinity mirrors available world-wide.

sturney143 months ago

i copied and pasted the code exactly how you have it. I have also checked all my wiring a hundred times. For some reason I can't switch between the modes, when i plug it in it just stays on fade mode. please email me at if you have any suggestions

Ben Finio (author)  sturney143 months ago
If you're using my code exactly, I think it will need to cycle between one complete fade cycle before it can switch. Are you trying to switch it immediately? Unfortunately, unless there's an error in my code or wiring diagram that no one else has caught yet, I'm not sure what to suggest :-(.

How long is one complete fade cycle? And theres definitely nothing wrong with the wiring it works perfectly. Its really cool actually! :) it just doesn't switch to the single control mode. only the fade mode works.

Ben Finio (author)  sturney143 months ago

The fade speed is controlled by the 4th potentiometer (POT4 in the Arduino code). If you have it cranked all the way up, I think it's pretty slow, possibly a couple minutes. If you crank it all the way down it's really fast. So, try turning the potentiometer all the way in one direction before you run the code, then try again with it turned all the way in the other direction.

The non-ghetto way to do it is to use interrupts - see Antbert's comment and code below.

I know that much and its completed about 9000 fade cycles know but it still wont let me switch modes. Is there something i need to code?

Ben Finio (author)  sturney143 months ago

Unless the toggle switch is wired wrong so that input pin is always reading HIGH for some reason, then I don't know what could be wrong. From step 4, the code looks something like this (just typing pseudocode here):

val = digitalRead(BUTTON);

if (val == HIGH)

{code to do color fade}


{code for individual control}

So, once it completes a single loop, it should read the toggle switch again and execute the proper code depending on whether the switch is high or low.

You could try some other debugging step, like hooking a multimeter up to that input pin to read the voltage, to make sure that it's actually toggling between high and low when you flip the switch. If it's toggling between 0V and 5V, then the problem must be in the code somehow and not in the hardware.

KingtarLED3 months ago

Its a nice project.I'm wondering whats the chip of the led strips ?

By the way,we're manufacturer of digital rgb strips in China.

We found the WS2801 individual addressable strip is widely used by Arduino controlled.our

joshdeg3 months ago
Awesome Instructable! I am using the controller portion of this to power 70 ft of RGB LEDs for a custom home theater. Just a side note, when using a heat sink make sure it is not grounded and the MOSFETs drain flanges (top metal part with the hole) aren't connected. I would suggest using separate heat sinks for each of the MOSFETs if you do decide you need them.
Antbert5 months ago

Hello. Great tutorial and the result looks brilliant! I'm making this too, and I wrote some code using an interrupt that allows you to switch between various sequences (mine is an automatic fade, and a pot-controlled colour one). I notice you said you couldn't get it to switch until the end of the loop but the interrupt deals with this quite nicely. I uploaded it in pastebin anyway for reference:

oldmicah11 months ago
It looks fantastic! I did a 'ladder' infinity mirror a few years back and yes, applying the film was the most painful part. The directions for the stuff I used said to remove the back as you applied it and using a squeegee with a small amount of window cleaner (as lubricant) on the back as you went. (2person job). Really not sure it made it easier, but I thought I'd throw it out there.
Antbert oldmicah6 months ago

I signed up just to comment on this! This is a really good video: I tried with it dry first and it was a total nightmare but following the directions there it came out pretty much perfect. Still a two person job though.

Ben Finio (author)  oldmicah11 months ago
Yea, I think the directions for the stuff I bought say to use "Gila application solution" with a shows up in the related products on Amazon. I didn't notice that when I first ordered it, but I think the results are good enough.  I think if I ever decide to make a coffee table or something I will just suck it up and buy a pane of one-way mirrored glass instead of dealing with the film.
jackOrip Ben Finio11 months ago
Yeah, you should definitely use a "lubricant". I just tinted every window in my house. My special "lubricant" is a spray bottle of water with 2-3 drops of dish detergent. Pay zero attention to their SPECIAL lubricants. The water will dry after a short time if squeegeed properly, and the final product will be gorgeous!
saimasaima7 months ago
Here is a link to my version of this infinity mirror using this great instruction set:
saimasaima8 months ago
I went to get an LED strip from a store and they said I will need a transformer for the LED. Will that be necessary for this project?
Ben Finio (author)  saimasaima8 months ago
It depends on what type of LED strip you buy, but you will need a power supply to convert AC to the DC voltage required by the LEDs. For example, I used this 12V adapter, linked to in the Materials list:
stealthpower9 months ago
Currently unavailable:
Ben Finio (author)  stealthpower9 months ago
There are a ton of other mirrors on Amazon...just scroll down to "Customers who bought this item also bought", or search for "round glass mirror" and you can buy them individually.
vignesh siddhu10 months ago
A cool and pleasant project.
ThePuzzler10 months ago
This is awesome! I like red, purple, and green the best.
Raphango10 months ago
Finally someone has invented the time travel!
Thank you so much! =D
dzheng110 months ago
Really awesome! Looks like a time channel!
jsan61811 months ago
OK Ben Finio,
The next logical step is to use the Sparkfun Addressable LED Strip
to make a Infinity LED Clock with Second hand sweep! Probably could be part of an interesting set of display routines
Since I am just starting in the world of PICS and Arduino. I would graciously accept the code once finished. I started something very similar using discrete 7400 TTL Logic chips back in the 80's. Yes I am "Old fart status".
Ben Finio (author)  jsan61811 months ago
I would like to do a digital LED strip for my next infinity mirror, but I can't promise that will happen anytime soon :-). I had to get this one done in time to enter the Arduino contest and didn't want to spend the extra money on the digital strip.

In the meantime though, I think this project goes over controlling an addressable strip (not in an infinity mirror though), and here's a video (with a link to more info in the description) of an infinity mirror using one. If you search for "Arduino addressable LED strip", "Arduino digital LED strip" etc. I'm sure you can find plenty of example code.
JonnyMac Ben Finio11 months ago
The WS2801 driver is far easier to use than the newer WS2811/WS2812 variants -- it's a great way to get started with RGB control using any processor. The buss uses two pins (clock and data) so the timing is pretty easy (the new, single-wire chips have fairly strict timing requirements).

Here's a project I participated in -- built by a famous Hollywood prop/fx shop for Riot Games. The "energy ball" uses 95 WS2801 RGB modules (note, this video does not show the final code).

JonnyMac jsan61811 months ago
I'm a long-time Parallax customer and write about the Propeller for Nuts & Volts magazine. In the September issue I write about programming the WS2812 addressable LEDs. If you're writing code for the PIC it may be useful. There are several Arduino libraries available for them, too, especially connected to Adafruit.
jsan618 jsan61811 months ago
And maybe a color organ with sound sampling r & L channel being the sides of the display.

Does anyone know if there is any simple learning aids, modules or tutorials for Digital Signal Processing. Something to learn how to do my above statement, Arduino based color organ, 8 channel?
JonnyMac11 months ago
Neat. Would love to see that built with an addressable LED strip (e.g., WS2811+LED or WS2812s) so that you could control individual colors and animation -- you could turn the infinity mirror into a vortex tunnel.
wizer11 months ago
This is great! With the window tint. Does it need to be high percentage of tint, or low? The specs on the product you linked to list glare and uv reflectiveness, but is it better to go darker or lighter with the actual tint.
Ben Finio (author)  wizer11 months ago
Hey, this is a really good question. To be honest I just bought the first stuff that popped up on Amazon. I don't think UV reflectiveness matters at all because the LEDs aren't emitting UV, and I'm not even sure what they mean by "80% of glare".

My hunch is this: if you get "lighter" film (say, 75% transmissive and 25% reflective) - then much more light will escape the mirror each time it hits the front surface. This will make the first few LEDs you see appear much brighter. However, since 75% of the light from each reflection escapes each time, it won't be very long until almost all of the light escapes the mirror, and you can't see anything.

Whereas, if you get "darker" flim (25% transmissive and 75% reflective), the first LED you see will be much darker (only 25% of the real LED brightness), but much more light is reflected back inside the mirror, so you will see more reflections - but they will appear much dimmer due to the darker film.

Point being: light film = brighter, "shallower" tunnel; dark film = dimmer, "deeper" tunnel. That's my guess. I actually think this is really interesting and am working on some simple math to prove it, I will add a step to the end of the Instructable with some graphs if I get anywhere.
jackOrip11 months ago
Awesome and detailed instructable, Ben. Thanks!!!

I have a question that I hope you can answer. In the Arduino code you set
'const int POT3 to pin 2'
and also
'const int BUTTON to pin 2'

Are there two pins numbered 2. Like the analog pin 2 is separate from digital pin 2? I'm just starting to get interested in the Arduino and have not actually received my microcontroller in the mail yet so I am still a bit of a newb. :D
Ben Finio (author)  jackOrip11 months ago
Hey, good question, and you're exactly right. If you look at the picture here

you can see that there are six analog pins labeled A0-A5 and 14 digital pins labeled 0-13.

However, these lines of code don't actually "assign" a variable to a specific pin, so maybe the comments are a little misleading:

const int POT3 = 2;
const int BUTTON = 2;

That information just gets used later with these commands

val = digitalRead(BUTTON);
r = analogRead(POT3)/4;

In those cases, BUTTON and POT3 are both equal to 2, but the Arduino knows whether to read the analog pin 2 or the digital pin 2 based on whether you use the digitalRead or analogRead commands.
mpho11211 months ago
Beautiful...That's too cool
waleksander11 months ago
I think this is the most explained tutorial here, I loved it and I'll try to do anyday.
Thanks, for me you're the contest winner,
andmic11 months ago
yulow11 months ago
You make my Day ^^ its cool
1-40 of 50Next »