loading
Picture of Arduino-controlled RGB LED Infinity Mirror
arduino-rgb-led-infinity-mirror-colors.jpg
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.
Tools

  • 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

Step 1: How does an infinity mirror work?

Picture of How does an infinity mirror work?
how a one way mirror works.JPG
Ok, almost time to start building. First, I want to pre-emptively address another common comment: how do these things actually work?

Not surprisingly, there is no magic involved. The secret is that the infinity mirror actually contains two mirrors with different  transmissivity and reflectivity. For all practical intents and purposes, mirrors that we deal with in everyday life are 100% reflective (technically a tiny amount of light will also be absorbed, but we can ignore that for now). That's the regular mirror at the "back" of the infinity mirror (on the left in the diagram above). The tinted window film, however (on the right in the diagram above), only reflects about half of the light that hits it*. This means that, when you sandwich an LED between the two mirrors, some of the light escapes through the front mirror and into your eye. The rest is bounced back off the rear mirror, then into the front mirror again, and this process continues off to infinity - thus the name. But, since a little bit of light escapes each time, each successive illusionary LED that you see will look a little bit dimmer, until they gradually disappear - you can't actually see infinitely many LEDs.

Note that this does not work because the window tint "only lets light through in one direction", which is a common misconception. In order for the illusion to work properly, the side of the front mirror the observer is on (the outside world) must be much darker than the side with the LEDs (inside the infinity mirror). This is the same effect that you see in crime dramas/movies where someone is held in an interrogation room that has a mirror on the wall, but there are people on the other side of that mirror observing as though it's just a window. That only works if the interrogation room is well-lit and the observation room is dark.

*The exact percentages of reflectivity/transmissivity might vary depending on what kind you buy - different levels of reflectivity and transmissivity are actually regulated in different states for use in car windows, Google it if you're curious.

Step 2: Building the Circuit

It's probably a good idea to build, test, and debug your circuit before you build the mirror. Otherwise, it would be quite sad if you get a nice, fancy mirror built only to throw the switch and find out something doesn't work. So, first let's assemble the circuit and test the LED strip. If you're new to circuits and don't understand what's going on, you can either (a) just blindly follow the directions, or (b) look ahead to the next step for an explanation of how the circuit works.

If you have experience working with breadboards, you can go ahead and assemble the circuit based on the third breadboard diagram above, or directly from the circuit diagram. For newbies I broke it into three steps, hopefully to make things less overwhelming - corresponding to the first three diagrams above:

1) Populate the breadboard with the three MOSFETs, four potentiometers, SPDT switch, and barrel jack adapter. I made these parts "transparent" in the figure above so you can see exactly where their pins go*.

2) Add wires to connect to your power and ground rails. I've color-coded these with red and black here, but remember that you can use whatever colors you want if you just have a multi-colored jumper wire kit and no red and black hookup wire. Notice how one of the breadboard rails is connected to the +12V supply from the barrel jack (which feeds power to the Arduino through Vin), and one is connected to the Arduino's +5V power pin, but they share a common ground. Whatever else you do, don't short the +12V and +5V supplies together!

3) Add wires to connect to the Arduino's inputs and outputs, and wires that you will connect to your LED strip (if your strip came with pre-soldered wires, use those)**. Again, I've color-coded the respective red, green, and blue wires here but your ability to do that will depend on what wire you have available.

* I started making this diagram in Fritzing, but got frustrated with the enormous amount of space components like MOSFETs and potentiometers take up in breadboard view mode (they give a quasi-3D view instead of a "top-down" view, so take up way more space than they do in real life and obscure other things on the breadboard). So, I took a screenshot of the Arduino and breadboard and drew over them in Powerpoint.

** If your LED strip did come with pre-soldered wires, be careful about the color coding. SparkFun's product page notes that the blue and green wires are switched, which can be irritating but won't cause any harm. My strip came with a black wire connected to V+, and getting the polarity reversed on the LED strip could be bad news. I guess I understand not wanting to use two red wires (one for V+ and one for the red LEDs) but I wish they'd use something other than black for V+.

Step 3: How Does the Circuit Work?

Picture of How Does the Circuit Work?
circuit explanation.JPG
MOSFET.JPG
This is a rough explanation of how the circuit works and what the components are for. Seasoned veterans can skip this step, but read on if you're curious. I don't have time to write a whole introductory chapter on circuits so I've tried to provide relevant links when possible.

  • The barrel jack adapter provides a +12V supply to the breadboard. This is required to power the LED strips, and also powers the Arduino through its Vin pin. Technically, the Arduino's built-in barrel plug will accept a +12V supply, which you can then access through the Vin pin, but the LEDs draw a lot of current - more than you want running through the Arduino board. This way, the current "splits up" - the Arduino only draws what it needs, and the high current goes straight to the LEDs through the breadboard. Special thanks to the Adafruit support forums for helping me figure this out.
  • The SPDT switch just acts as a toggle to select which "mode" the program is in. The details of the code are explained in the next step, but essentially it just switches between a "color fade" mode that rotates through different colors, and a direct-control mode where you control individual red, green, and blue LED brightness. The middle pin of the switch is connected to one of the Arduino's digital input pins, and the outer two pins are connected to +5V and ground. So, depending on which way the switch is flipped, the program reads a digital HIGH or LOW using the digitalRead() function and acts accordingly (note: SPDT stands for "single-pole double-throw", the Wikipedia page on switches has a nice table summarizing the different types of switches, with diagrams).
  • The potentiometers are your "controls" depending on which mode the program is in. In individual-control mode, the three potentiometers control brightness of the red, green, and blue LEDs respectively. In color-fade mode, a single potentiometer controls the speed of the fading. The potentiometers have three pins. Like the switch, one pin is connected to +5V, and one pin to ground. However, unlike the switch, rotating the potentiometer makes the voltage on the middle pin vary continuously between 0V and 5V, instead of just toggling between the two. So, the middle pins of the potentiometers are connected to the Arduino's analog inputs. Then, using the analogRead() function, the Arduino converts that voltage to a number between 0 and 1023 for use in the program (see next step).
  • The MOSFETs are probably the trickiest part to understand for a newcomer to electronics. These are required to drive "high power" devices like motors, solenoids and LED strips, which frequently require more current than the Arduino can supply. The Wikipedia page on these is actually rather dense, so I'll try to give a simplified explanation here. The MOSFET has three pins, called the "gate" (G), "drain" (D), and "source" (S). In its simplest form, the MOSFET acts like a valve that lets current flow from the drain to the source. The "gate" controls this valve (think of opening and closing a valve to a garden hose), except that control is electrical instead of mechanical. A voltage applied to the gate from one of the Arduino's output pins turns the MOSFET "on" - allowing high current to flow from the drain to the source, without actually drawing any current from the Arduino. If the voltage to the gate from the Arduino is zero, the MOSFET shuts off and stops current from flowing. This way you can control even enormous motors and lights with a tiny little Arduino, as long as you have an external power supply big enough to handle it.
  • I should also mention pulse width modulation (PWM). This is a common technique used to control LED brightness with an Arduino. In short, the Arduino's output pins are digital, so they can only output a HIGH or a LOW (5V or 0V). They can't continuously vary their voltage to adjust something like LED brightness or motor speed. Instead, what they can do is send out very rapid pulses (roughly 500 times per second with the Arduino), much faster than the human eye can see. Each pulse consists of a HIGH segment and a LOW segment, and the relative ratio between the two determines the "brightness" that we actually see. A pulse that is 0% high and 100% low will just look like "off". 100% high and 0% low will be "full brightness", and 50% high/50% low will be about half-brightness. You get the idea. In this circuit, a PWM signal is sent to the MOSFETs, which then controls the high current going through the LEDs, allowing a "fading" effect and adjustable brightness.

Step 4: Arduino Code

Copy and paste the Arduino code below into a new sketch. I won't write my own tutorial here, so if you don't know how to create/upload a sketch, check out the official Arduino - Getting Started page. If you want to learn more about a specific command, just Google it (e.g. "Arduino analogWrite") and the official help page should pop right up.

Caveat: this probably isn't the most efficient code! Particularly, I'm not sure of a nicer way to continuously monitor the fade-speed potentiometer without copying and pasting the same line of code over and over, or if there's a way to break out of a for loop if you flip the toggle switch (right now, if you switch to individual-control mode while in color-fade mode, the switch won't occur until it finishes the current fade cycle). So, I'll throw that out there as a challenge to anyone who's reading this and wants to post better code. Clearly I'm a mechanical engineer at heart and not a programmer.


// Arduino code to control and RGB LED strip
// Uses a toggle switch to switch between color-fade mode
// and individual RGB control mode
// adapted from http://learn.adafruit.com/rgb-led-strips/example-code

const int RED = 9;    // define digital output pins for individual red,
const int GREEN = 10;  //green and blue channels
const int BLUE = 11;


const int POT1 = 0;    // define analog input pins for three potentiometers
const int POT2 = 1;
const int POT3 = 2;
const int POT4 = 3;

const int BUTTON = 2;  // define digital input pin for the switch

int val = 0; // stores the state of the switch input pin

int FADESPEED = 0;  // initiate fade speed set by potentiometer

int r = 0;  // initialize the red, green and blue values

int g = 0;

int b = 0;

void setup(){
  pinMode(RED, OUTPUT);    // define digital pins as outputs and inputs as needed
  pinMode(GREEN, OUTPUT);
  pinMode(BLUE, OUTPUT);
  pinMode(BUTTON, INPUT);
}

void loop(){
  val = digitalRead(BUTTON);   // read the input value from the toggle switch
 
  if (val == HIGH){  
    // code for RGB color fade
    FADESPEED = analogRead(POT4)/10;   // set the fade speed by reading analog input from 4th potentiometer
                                       // analogRead will output a number between 0 and 1023, and "delay"
                                       // is in milliseconds, so the biggest delay you'll get here is about
                                       // 1/10 of a second. Divide by a different number to change the max
                                       // fade time.
    // fade from blue to violet
    for (r = 0; r < 256; r++) {
    analogWrite(RED, r);
    FADESPEED = analogRead(POT4)/10;  // check the fade speed continuously, otherwise
                                      // it won't update until it's gone through a complete cycle.
                                      // Probably not the most efficient way to do this...
    delay(FADESPEED);
    }
    // fade from violet to red
    for (b = 255; b > 0; b--) {
    analogWrite(BLUE, b);
    FADESPEED = analogRead(POT4)/10;
    delay(FADESPEED);
    }
    // fade from red to yellow
    for (g = 0; g < 256; g++) {
    analogWrite(GREEN, g);
    FADESPEED = analogRead(POT4)/10;
    delay(FADESPEED);
    }
    // fade from yellow to green
    for (r = 255; r > 0; r--) {
    analogWrite(RED, r);
    FADESPEED = analogRead(POT4)/10;
    delay(FADESPEED);
    }
    // fade from green to teal
    for (b = 0; b < 256; b++) {
    analogWrite(BLUE, b);
    FADESPEED = analogRead(POT4)/10;
    delay(FADESPEED);
    }
    // fade from teal to blue
    for (g = 255; g > 0; g--) {
    analogWrite(GREEN, g);
    FADESPEED = analogRead(POT4)/10;
    delay(FADESPEED);
    }
  }
  else {
    // code for individual RGB control with potentiometers
    r = analogRead(POT3)/4;  // read values from the 3 potentiometers and divide by 4 to set brightness
    g = analogRead(POT2)/4;  // note that analog read is 10-bit (0-1023), analog write is an 8-bit PWM
    b = analogRead(POT1)/4;  // signal so you need to divide this value by 4.
   
    analogWrite(RED, r);     // write analog values to red, green and blue output pins
    analogWrite(GREEN, g);
    analogWrite(BLUE, b);
  }
   
  }

Step 5: Testing your Circuit, Code, and LED Strip

Picture of Testing your Circuit, Code, and LED Strip
IMG_2982.JPG
IMG_2983.JPG
Plug your power supply into the barrel jack adapter, and after your Arduino takes a second to boot up, you should be able to control the lights! Use the toggle switch to switch between two modes. In one mode, you can directly the control the red, green, and blue LED brightness with the first three potentiometers; and combine them to make different colors. In the other mode, the LEDs will fade between colors automatically, but you can control the speed of the fading with the fourth potentiometer.

Watch this video for a demonstration, and see below for troubleshooting tips if it doesn't work. Notice how there are a couple spots in this video where my LEDs flicker - this must mean I have a loose connection or two bare wires bumping into each other somewhere when I jostle the Arduino around. Watch out for that.



Troubleshooting Tips

  • Double and triple check your breadboard connections. It only takes one misplaced wire to stop the whole thing from working.
  • Make sure the I/O pins assigned in your code match the pins you're actually using. This shouldn't be an issue if you copied and pasted my code directly, but it can't hurt to check.
  • Make sure your LED strip works. Hook the LED strip's V+ wire up directly to the +12V rail on the breadboard, then test red, green, and blue individually by plugging their respective wires into the ground rail. The LED strip has built-in resistors so you don't have to worry about blowing it out. If each color lights up, then your strip is fine, and the problem is elsewhere in your circuit.
  • Test your circuit and code with regular LEDs, skip the MOSFETs. If MOSFETs are a bit too new and confusing, you can do a starter version of this project that just uses three plain old LEDs, or a single RGB LED (search common vendors like SparkFun or Adafruit, there are plenty of options). These are low-current and low-voltage enough that they can be driven straight from the Arduino and don't require the MOSFETs, but you will need current-limiting resistors so the LEDs don't burn out. LED blinking and fading are very common starter Arduino projects so I won't reproduce the directions here.
  • Skip the potentiometers and test the circuit with a hard-coded color pattern.  This lets you make sure the PWM signals and MOSFETs are working, without having to worry about the analog inputs and potentiometers.
You may have noticed a trend here - the general idea is to break your circuit (or code) down into smaller, isolated sections that can be tested individually. This lets you narrow things down and search for problems in a compartmentalized way, instead of just staring at a giant circuit and mess of code and wondering what went wrong. If you can think of other/better ways to debug this circuit, please chime in in the comments.

Step 6: Preparing the Mirror Frame

Picture of Preparing the Mirror Frame
IMG_2995.JPG
IMG_2997.JPG
IMG_3007.JPG
IMG_3008.JPG
IMG_3009.JPG
So, this is where I hoped that my 9" diameter mirror would fit snugly inside my 9" diameter lid, or the box itself. As you can see from the photos above, it didn't (they were just too small), and the 10" diameter box and lid were too big. My workaround was to cut out the top of the 9" lid and just use the rim. I kept the circular piece that I cut out of the top to reinforce the back of the mirror. So:

1) Use a utility knife to carefully cut out the top of your cardboard lid. Not necessary if you bought a lid/mirror combo that fit together snugly.

2) Paint both pieces a color of your choice. I believe the illusion will work better if the inside of the rim is black, the outside doesn't really matter.

3) Drill a hole in the side of the rim that's big enough for the wires from your LED strip to fit through. In hindsight, I probably should have drilled first and painted second.

Step 7: Mounting the LED strip

Picture of Mounting the LED strip
IMG_3012.JPG
IMG_3013.JPG
IMG_3039.JPG
IMG_3014.JPG
IMG_3015.JPG
Thread the LED strip wires through the hole you drilled in the cardboard lid.

Carefully begin to remove the adhesive paper backing from the LED strip, and press it firmly against the inside perimeter or the lid. Make sure it is centered inside the rim.

Once you've gotten the entire way around, cut the LED strip. Important: the LED can't just be cut anywhere - you have to cut it in 3-LED segments, and you can see the cut lines with labeled solder pads. If you cut anywhere else, the last few LEDs of your strip won't work.

You'll also have to hope that the circumference of your lid matches up nicely with a multiple of the length of these 3-LED segments (about 1 15/16"), otherwise you could wind up with either a gap or a bit of overlap between your first and last LEDs.

Step 8: Assembling the Frame

The mirrors I bought came with small hooks on the back, and I accidentally ripped the hook off the 9" mirror when I was removing it from the packaging. So, it's probably a good thing I didn't try to use that to hang it on a wall. That works out anyway because you'll want to remove the hook so you can mount the mirror flat on the inside of your frame.

I super-glued the back of the mirror to the flat (non-painted) part of the cardboard lid from earlier. Now is probably a good time to make sure your mirror is clean and free from fingerprint smudges, because any defects will detract from the illusion in the finished product. I used paper towels to handle/pick up the mirror from this point on, to avoid getting additional fingerprint marks around the edges.

After gluing the mirror to the cardboard circle, I just used electrical tape to wrap around the outer edge of the rim with the LED strip and attach it to the mirror (of course duct tape would work too, but I wanted it to be black). Again, this is just a roundabout process that I had to go through because my mirror didn't fit inside the lid to begin with.

Once you have everything secure, it's probably a good idea to fire up the Arduino and make sure you didn't somehow damage the LED strip or wires during this process.

Step 9: Cutting the Acrylic - Jigsaw

Picture of Cutting the Acrylic - Jigsaw
IMG_3004.JPG
IMG_3005.JPG
IMG_3006.JPG
So, in grad school I used a laser to cut acrylic all the time, and it worked great. Now I don't have a laser so that wasn't an option, and I really wanted to use the 9" mirror instead of going with 6" and buying a pre-cut 6" acrylic circle. That meant I had to cut my own acrylic. Thanks to everyone who pitched in to this forum thread with ideas.

IMPORTANT SAFETY INFORMATION BEFORE CONTINUING: If you're using a laser, acrylic fumes aren't good for you. If you're cutting/sawing/sanding/whatever-ing it, you don't want to inhale the dust either. Be sure to work in a properly ventilated area and wear an appropriate mask if necessary.

So, with the jigsaw: I traced the outline of the 9" mirror onto the acrylic's paper backing. Then I used two C-clamps to hold it onto the edge of a table, and just roughly cut off the corners to make an octagon. Then I went in for successively smaller cuts following the line. The end result wasn't too bad - some cracking around the edges, but no catastrophic breaks that ruined the circular shape.

Some safety notes - first I tried this with a wood blade, which didn't work at all and resulted in some large, jagged pieces of acrylic snapping off when the blade snagged. Got a finer-toothed metal blade at the hardware store and that worked much better. The edges were still quite sharp so I just hand-sanded them to avoid cuts. As usual with power tools, I'd recommend safety glasses for this step.

Step 10: Cutting the Acrylic - Score-and-Snap

Picture of Cutting the Acrylic - Score-and-Snap
IMG_3038.JPG
IMG_3036.JPG
IMG_3043.JPG
My other approach to cutting the acrylic was scoring a circular outline with a utility knife, then scoring a bunch of additional radial lines, hoping I'd be able to break off individual pieces, and wind up with a circle left in the middle.

The first time I tried this, I used C-clamps to clamp the acrylic down on the edge of a table, and then hit the breakaway pieces with a mallet. That didn't work and resulted in big chunks breaking off inside the circular perimeter (this works fine for straight cuts if you're making a rectangular mirror, though).

Next, I took some helpful advice from the forum thread: I scored the acrylic and then put it in the freezer for a few hours. Then I used the C-clamps again, but snapped the edges off with a vise grip instead of hitting it with a mallet. This worked pretty well, with less cracking around the edges than the jigsaw method. It still had some sharp points sticking out, which I sanded down.

To be fair, I never tried using the vise grips without freezing first, or using the mallet after freezing - so I can't say with 100% certainty whether it was the vise grips or the freezing that made it work better the second time.

Step 11: Applying the Mirror Tint

Picture of Applying the Mirror Tint
IMG_3044.JPG
IMG_3028.JPG
IMG_3027.JPG
IMG_3029.JPG
At this point we'll assume you've somehow managed to cut your acrylic to the appropriate size. Make sure you wipe down/clean off your acrylic (fingerprint smudges, dust from sanding etc) before you continue.

Next you'll need to cut a piece of mirror tint that is bigger than your piece of acrylic - this means you can handle the extra material on the edges without worrying about fingerprint smudges.

The window tint comes with a clear protective coating on one side, that you need to remove to expose the sticky adhesive. Start in a corner and carefully use your fingernail to peel up the clear layer (this can be a pain to do), then carefully lay the mirror tint flat on your piece of acrylic. I think this is the most frustrating/difficult part of the whole project - you want to get the tint as flat as possible, without any air bubbles. Big air bubbles will be painfully visible in the final mirror and can detract from the illusion. I did my best to get the tint as flat as possible, and "popped" a few air bubbles by pushing them toward the outer edge with my fingertip (using a paper towel so I didn't smudge the window tint). If you really mess up on your first try, you can peel the window tint off most of the way and try laying it down flat again, the adhesive shouldn't lose its stickiness. If all else fails you can also just cut a new piece.

Once you're happy with the appearance and smoothness of your window tint, use scissors to cut around the outer perimeter so it's flush with your piece of acrylic.

Step 12: Attach One-Way Mirror to the Frame

Picture of Attach One-Way Mirror to the Frame
IMG_3046.JPG
IMG_3047.JPG
Nothing fancy here...place the one-way mirror with the mirror tint facing in*. I just used electrical tape around the outer edge again. If you wanted to get fancier, you could mount the one-way mirror on the inside of a slightly larger cardboard lid and then fit that around the outside of your frame.

*Here I'm just following the directions I've seen on other infinity mirrors. Optically, it should work in either direction, as discussed in Step 1. Maybe the acrylic is just harder to scratch/easier to clean, so it's better to have that facing out...honestly I'm not sure.

Step 13: Light it Up!

Plug in the power supply and fire it up! Assuming you tested your LED strip in Step 5 and didn't have any major issues with constructing the mirror, it should work as advertised. Above are a bunch of photos I took in different lighting conditions (the darker the room, the better the "infinity" effect), and below is a video of the final product in action.

I want to make this Instructable as clear as possible for beginners - so if you saw something that wasn't clear, or I skipped over/implied something that you think should be spelled out, please leave a comment to let me know.

Thanks for reading! Here's a video of the final product:
1-40 of 102Next »
AliM3726 days ago

Hey Ben! Thank you for the very detailed tutorial. I´m an Arduino novice and was wondering if there would be a way of providing the input through sensors like ones for proximity or pulse, instead of manually manipulating the potentiometers.

How would something like that work as an input to this?

Ben Finio (author)  AliM3726 days ago

Hi AliM37,

Absolutely! This project makes use of the Arduino's analog input pins, which can read any value between 0 and 5 volts. That value is converted to a number between 0 and 1023 in the code (see my replies to ChristianS6 for a more in-depth explanation of that). This means that you can use pretty much ANY sensor that will output 0 to 5 volts. The potentiometers just happen to be one convenient way to do that. For example, you should be able to use this thing to make the LEDs pulse with a heartbeat:

https://www.sparkfun.com/products/11574

You just have to be careful about two things when choosing a sensor:

- Make sure the sensor doesn't operate in a different voltage range (0 to 12 volts or something...don't want to fry your Arduino)

- Make sure the sensor isn't digital instead of analog. This means the sensor would output a series of 1's and 0's instead of a continuous voltage between 0 and 5V, and it wouldn't work with the analog input pins. You certainly CAN use all sorts of digital sensors with an Arduino, you would just have to look up a separate tutorial/code and not use the code from this project.

Hope that helps! If you find a sensor you want to use, and can't figure out how to hook it up, odds are if you google "[name of sensor] + Arduino", someone out there has done it already and posted the circuit diagram.

Hey Ben, I pretty much followed your design exactly, but I'm wondering if any of your MOSFETs get really hot to the touch. For some reason the one connected to the red led gets pretty hot to touch if it's left on full. The others seem to be cool no matter what. If I keep them fading in and out you really can't feel it on any of them but if I turn them to white the red one gets so hot.

Ben Finio (author)  bigbadassdave28 days ago

I can't say that I ever noticed them getting hot, but I also don't think I really tried touching each one when it had been running for a while. However, I don't think the MOSFETs should be getting super hot - their datasheet says they're rated up to 32 amps continuous current, whereas the LEDs only draw 60 milliamps according to their datasheet. So, you're nowhere near the max rating.

What happens if you try switching the MOSFETs around? i.e. take the MOSFET that is currently connected to red, and connected it to green or blue instead? If the same MOSFET always gets hot regardless of which color it's connected to, then there could be a problem with that MOSFET. If a new MOSFET always gets hot whenever you connected to the red LEDs, then the problem is with that connection (maybe it's shorted to ground somehow).

When I've switched the MOSFETs around the red line still gets hot, one thing I've noticed that is different is that the 2 different MOSFETs i've tried have different ratings for the continuous current, this one is rated at 12amps and this one is rated at 9.2amps.  I'm wondering if it's just getting close to the max is what is causing the heat.  

It's weird to me that only the red one gets hot, I've double checked the connections and it looks like it's not shorted to ground or anything like that.

I switched up the code for the fade so that it just randomly selects a color and fades to that, here's the code I used:

{
      const int DelaySpeed = 100;
      int red = random(256);
      int green = random(256);
      int blue = random(256);
      int redinc = prevred>red? -1:1; //if the previous number is greater than the new number subtract 1 otherwise add 1
      int greeninc = prevgreen>green? -1:1;
      int blueinc = prevblue>blue? -1:1;
      String DebugDataTemp = "(";
      for (int i= prevred; i != red; i+=redinc)
      {
        prevgreen = prevgreen== green? prevgreen:prevgreen+greeninc;
        prevblue = prevblue== blue? prevblue:prevblue+blueinc;
        String DebugData = DebugDataTemp + i + "," + prevgreen + "," + prevblue + ")R";
        Serial.println(DebugData);
        analogWrite(REDLED,i);
        analogWrite(GREENLED,prevgreen);
        analogWrite(BLUELED,prevblue);
        delay(DelaySpeed);
      }
      prevred = red;
      for (int i=prevgreen; i != green; i+=greeninc)
      {
        prevblue = prevblue== blue? prevblue:prevblue+blueinc;
        String DebugData = DebugDataTemp + prevred + "," + i + "," + prevblue + ")G";
        Serial.println(DebugData);
        analogWrite(GREENLED,i);
        analogWrite(BLUELED,prevblue);
        delay(DelaySpeed);
      }
      prevgreen = green;
      for (int i=prevblue; i != blue; i+=blueinc)
      {
        String DebugData = DebugDataTemp + prevred + "," + prevgreen + "," + i + ")B";
        Serial.println(DebugData);
        analogWrite(BLUELED,i);
        delay(DelaySpeed);
      }
      prevblue = blue;
      Serial.println("------");
    }
Ben Finio (author)  bigbadassdave27 days ago

Hmm. Another thing you can try is skipping the MOSFETs entirely and just hooking each LED channel directly up to the +12V power supply. As long as your power supply is rated to supply enough current, that shouldn't cause any problems. If something still gets hot, that would make me think the red LEDs are actually shorted out (maybe internally on the LED strip - so not something you can see on your breadboard).

Even if the MOSFETs you're using have a lower current rating than the ones I linked, that still seems way higher than what the LED strip would draw (side note: the first one you linked is rated at 12A at 100 deg C, it's actually 17A at room temperature, so even more breathing room. Look carefully at the data sheet and you'll see the two different ratings).

ChristianS61 month ago

Is there a On/Off switch?

If not, can i use a switch between the the barrel jack and the orduino and the leds or is this a bad idea?

Ben Finio (author)  ChristianS61 month ago

Hi Christian - I did not include an on/off switch in the original design, so you had to unplug the barrel jack to turn the whole thing off. This is kind of inconvenient, so you're correct that you could just include a switch between the barrel jack and the power rails on the breadboard, and you'd be OK. As far as I know, the Arduino handles sudden shutdowns pretty well (as opposed to the Raspberry Pi, for example, where you need to shut down properly or it can corrupt the SD card).

ChristianS61 month ago

Hi Ben i wan't to build your protject. But I have not much experience with programming. Can you explain the /4 in your code with some more details plese?

I mean this:

if (val == HIGH){
// code for RGB color fade
FADESPEED = analogRead(POT4)/10; // set the fade speed by reading analog input from 4th potentiometer
// analogRead will output a number between 0 and 1023, and "delay"
// is in milliseconds, so the biggest delay you'll get here is about
// 1/10 of a second. Divide by a different number to change the max
// fade time.

Ben Finio (author)  ChristianS61 month ago

I tried to reply and I think my comment got deleted somehow, so let's try that again (and apologies if this shows up twice).

I can try to explain, but I don't see a "/4" in the snippet of code you pasted. My guess is that you're referring to the /10 in this line:

FADESPEED = analogRead(POT4)/10;

This page provides a good explanation of the analogRead function on Aruino:

http://www.arduino.cc/en/Reference/AnalogRead

- The analog input pins on an Arduino are designed to read a value between 0 and 5 volts. That value is analog (meaning it's continuous and can have any value between 0 and 5 - like 4.999999999999...).

- Computers are digital, meaning they can only handle discrete numbers. The Arduino has a "10 bit analog to digital converter" which means it takes analog voltages between 0 and 5 and converts them to a number from 0 and 1023 (0 = 0 volts, 1023 = 5 volts). So, when you use the "analogRead" function, your code gets a number between 0 and 1023.

- Later on in the code I want to use this value for a "delay" which is in milliseconds (1,000 milliseconds = 1 second). So, if you just used the value from analogRead directly, you would get a maxmimum delay of 1,023 milliseconds, or 1.023 seconds.

- That delay is way too long for my purposes (fading between different colors), so I wanted to make it shorter. I do that by just dividing it by 10. Now I get a maximum delay of 1023 / 10 = 102.3 milliseconds.

- You can use any number you want to do this. Say you want a REALLY fast delay, then you can divide by 100 or 1000 instead. If you want a slower delay, you can multiply by 10, 100, etc.

Hope that makes sense.

Thank you

I noticed there was a mistake in my komment.

I wanted to paste this part of code:

else {
// code for individual RGB control with potentiometers
r = analogRead(POT3)/4; // read values from the 3 potentiometers and divide by 4 to set brightness
g = analogRead(POT2)/4; // note that analog read is 10-bit (0-1023), analog write is an 8-bit PWM
b = analogRead(POT1)/4; // signal so you need to divide this value by 4.

But your desciption of the /10 part is also verry helpfull :)

Ben Finio (author)  ChristianS61 month ago

Oh. The explanation here is pretty much the same concept as the /10. "note that analog read is 10-bit (0-1023), analog write is an 8-bit PWM signal so you need to divide this value by 4." means:

As mentioned previously, analogRead is 10-bit so it goes from 0-1023. Apparently analogWrite is only 8-bit so it goes from 0-255 (don't ask me why they're different, that's a question for the people who designed Arduinos to begin with). Here we want to take values between the range of 0-1023 (read from the potentiometers) and convert them to the range of 0-255 (used to control LED brightness). You do that by dividing by 4. I know that 1023/4 actually equals 255.75...so I'm not quite sure how the Arduino handles decimals. That might just be sloppy code on my part, but it works, so maybe someone else can provide an explanation there.

Notice how conceptually this is the same as the "/10" code. In both cases you are taking a value from analogRead that will always be between 0-1023. You need to convert that to some other number that is useful for whatever your code is doing. In this case I needed to divide by 10 and 4 for two different reasons. But, there's no rule saying you couldn't do something else. For example, say you buy an analog temperature sensor and hook that up to an analog pin instead of a potentiometer like in this project. There would be some equation you use (given by the sensor's manufacturer, or someone on the internet who already wrote the code for that sensor) to convert the analogRead() value to degrees. It could look something like

degrees_Celsius = 0.1*analogRead()+15

(Do the math by plugging in 0 and 1023 for analogRead, and this sensor would have a range of 15 - 117.3 deg C, which would be kind of odd...I just made up the numbers as an example, but you get the idea)

It might help if you do some background reading on binary numbers in general. That's already been done in plenty of places on the internet, so I won't type a binary tutorial into this comment...but here are some to get you started:

https://learn.sparkfun.com/tutorials/binary

http://www.mathsisfun.com/binary-number-system.htm...

Ok i think i understand.
Thank you for your help
DanielM372 months ago

Hey Ben, is it possible that I could substitute or not use a barrel jack adapter or a SPDT switch at all?

Ben Finio (author)  DanielM372 months ago
Hi Daniel - certainly, you don't need to use the barrel jack adapter. that's just one way to connect the power supply to the breadboard. you can just cut the cord and stick the 2 wires directly into the breadboard instead (use a multimeter to check which one is + and which one is -). the spdt switch is just what I chose to switch between the two "modes" for the LEDs but you dont need to use that either.

Thanks for the fast reply Ben! I'm having trouble locating a mirror in my required size in my area, would it be possible to have two sides with acrylic and mirrored window tint? Would it cause any great trouble overall?

Ben Finio (author)  DanielM372 months ago
you want the rear mirror to be 100% reflective. since the window tint lets some of the light through instead of reflecting it, you will lose some light and not get as many reflections as you would otherwise.

you could, however, do this on purpose and make a two-sided infinity mirror by not using a cardboard back to the case. then you can look into it from both sides. I'm on my phone so don't have the link but I think there's an instructable on two-sided infinity mirrors.

Is it possible to use a digital led strip with this setup?

Ben Finio (author)  DanielM372 months ago

Yep, from the intro step:

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

nuelma2 months ago

so cool

SuperM33 months ago

What if i use an acryilic window panel and apply a 5% window tint on one of the sides and paint it black on the other. Would it act like a mirror then?

Ben Finio (author)  SuperM33 months ago

You mean as a replacement for the "regular" mirror at the back? Technically, yes, I believe that would work, but since it's not reflecting 100% of the light, it would not be as efficient and you would not see as many LED reflections.

SuperM3 Ben Finio3 months ago

ok thanks

gordon.kaye3 months ago

I've been looking at ADRUINO-based LED projects for music visualizers and I am curious if it possible to create an Infinity Mirror that doubles as one of these visualizers? I was considering building both but if it possible, I would strongly prefer to do this because I am planning to attach it a set of suitcase-speakers that I will also be building.

Ben Finio (author)  gordon.kaye3 months ago

Certainly! You would just need to run different code on the Arduino to control the LEDs based on the music. There are plenty of music visualizer Instructables that arrange the LEDs in a "bar graph" form...so in this case you'd just be putting them in a ring around the inside of the mirror.

You can also do some basic visualization without using an Arduino at all, check out this project of mine:

http://www.instructables.com/id/Mini-LED-Volume-Towers-VU-meters/

renad.samaan4 months ago

does the gap between the LED and real mirror/fake mirror matter , how much is your gap ?

Ben Finio (author)  renad.samaan4 months ago

That gap will determine the distance between the reflections. Closer together, the reflections will appear closer together. I think the gap in mine is a little less than an inch.

So if the gap between mirror and fake mirror is bigger that means that the ''tunel'' of light created will be bigger/longer??

Ben Finio (author)  bieniekmario18.3 months ago

I think so but there could be some limits to that...for example, you're increasing the surface area of the interior wall, so there's more area for light to get absorbed instead of bounced back and forth, possibly making the reflections dimmer. The best way to find out would be to start building a mirror, but don't permanently attach the "lid" yet - hold it at different distances away from the back and see how the image changes.

Thank u for the answer. But I have one more question. I want to build inside my mirror another mirror/shape like on the foto. So I need 2 LED strips. I bought 2LED strips with adapter but my questions is how connect the 2 strips to one adapter. Can I do this anyway?????

hqdefault.jpg
renad.samaan made it!4 months ago
Thank you very much!!?
DSC_0267.JPG
Suepac716 months ago

that depth of field is INSAAAAAAAANE.....!..love it.

Im using the Adafruit neopixel led strip , will i need to use a completely different code as it is digital ?
Ben Finio (author)  mohammedmemon 6 months ago

Yes, you'll need to use different code AND a different circuit - but Adafruit has great guides on how to set everything up:

https://learn.adafruit.com/adafruit-neopixel-uberguide/overview

Thanks Ben, will I still be able to use the potentiometers?
Ben Finio (author)  mohammedmemon 6 months ago

Sorry, I should have clarified. The circuit to POWER the neopixels is different. You should check Adafruit's tutorials to be sure, but I don't think you need the MOSFETs at all - they just take a 12V supply line (I think).

https://learn.adafruit.com/adafruit-neopixel-uberg...

You can still use the potentiometers as INPUTS to your Arduino to control what the neopixels do (but you will need to figure out the code). It might also help to check out this project, or other Instructables that use addressable LED strips:

http://www.instructables.com/id/Rainbow-Jar-RGB-Pi...

goldenshuttle7 months ago

Ben, I raise my hat to you, as this is one the most well written instructable I came across. Keep posting please.

Ben Finio (author)  goldenshuttle7 months ago

Thank you!

This is an excellent instructable. I saw one for an infinity mirror but it didn't explain very well so I looked around and your's is the most explanatory where I could actually see what was happening. I am definitely going to build one. I won't be using an arduino, probably just some LED chistmas lights but this was very helpful with how it actually works and how to make an infinity mirror.
Ben Finio (author)  JavaProgrammer7 months ago

Thank you! Honestly that was part of my motivation for writing it originally. I saw a lot of cool infinity mirror builds (especially on YouTube, people go crazy and make whole desks/coffee tables/bar tops) but very few that actually provided a complete materials list, build instructions, and explanation of how they work. They work just fine with Christmas lights, and there are also RGB LED strips with remote controls you can buy so you don't need an Arduino:

http://www.amazon.com/s/ref=nb_sb_noss_1?url=search-alias%3Daps&field-keywords=RGB+LED+strip

Glad you found it helpful!

1-40 of 102Next »