Introduction: Project: Infinity Mirror

Behold! Look deep into the enchanting and deceptively simple infinity mirror! A single strip of LEDs shine inward on a mirror sandwich to create the effect of endless reflection. This project will apply the skills and techniques you've learned so far, and put it all together into a final form using a smaller Arduino Gemma board.

Step 1: Supplies

Step 2: Cut Frame Pieces

Get ready for some papercraft! This step involves sharp tools and requires attention to detail, so be sure you're well-rested, but not overly caffeinated either. Use bright lighting and a large, clean work surface protected by a cutting mat or scrap cardboard.

If you're new to cutting and glueing foamcore board, get extra for practice and mistakes— a three-pack of 16x20in boards should suffice (and you can make other projects with it if you have extra left over). To prevent injury, use a sharp blade, a metal ruler, a slow pace, and plenty of caution. It's normal to remake a few pieces due to an errant blade slip or snag.

There are two ways to create the shapes you'll be cutting: print out the template, or draw the shapes with a circle-drawing compass. There is no distinct advantage in either, but your skills and tools might sway you one way or the other. The template is available as a tiled PDF for letter-sized paper, which you'll tape together and use a glue stick to adhere it to your foamcore. There's also an untiled version of the template file in case you want to print it on a large format printer or make changes.

It's really simple to draw the shapes by hand, though, I promise! First draw a circle to match your mirror size by setting the compass to its radius (4" mirror = 2" radius) and drawing a circle on your foamcore at least 5 inches from each edge. Sure, you could just trace the circumference of the mirror, but then you'd have to find and mark the center! The compass makes an indentation at the center point that's handy for making the second concentric circle.

Now widen your compass to 4" and draw out the bigger circle around the first. This is the complete bottom/back of your mirror— label it as such.

The top/front piece needs to be just a bit bigger, so widen your compass to 4 3/16" and draw it out at a safe distance from the bottom piece.

The viewing window should be just slightly smaller than the mirror, though it's not important exactly how much. Set your compass to about 1/8 inch smaller than the mirror radius, and then draw out the circle using the same center point as the larger front/top perimeter.

Label this piece within the smaller circle, which will be cut away in a few moments.

Along one long side of your foamcore, mark and cut one strip at 1/2" wide, and another at 1" wide.

The narrow strip will hug the mirror and support your NeoPixel strip, while the wider one will form the outer wall of the circular frame.

Onto cutting the circles! Some finesse and patience are helpful here. I like to use a smaller craft knife for cutting circles because I feel like I have more control. The particular knife I'm using here takes regular X-acto blades, and I found it in the scrapbooking aisle.

First, lightly drag your knife around the entire circumference of the bottom piece, only piercing the top layer of paper. During this pass you're free to angle the blade however is most comfortable and produces the most precise shape.

Cut around the circle once again, tracing the line you made in the previous pass. This time, pay attention to your blade angle, which should be 90 degrees (straight up and down). Press firmly as you make this cut, and keep your fingers out of the blade path. Pick up your board and check to see if you cut all the way through. Make one more pass with your blade to cut through any remaining spots along the perimeter.

Next up, cut out the top piece, and then cut out its inner circle. This piece is seen more than any other, so give it a little extra cleanup to straighten up any edges that are uneven.

For the curved inner ring, make cross-cuts every 1/4" or so along the thinner foamcore strip, but don't cut all the way through! It's easier than it sounds— just make two light passes and you'll get the hang of it quickly. These cuts allow the piece to curve while providing a smooth interior surface.

The outer frame piece needs to put it's best face outward, so we'll make cross cuts in a slightly different pattern. First prep for the lap joint by scoring a line 3/16" from the edge. Make gentle cross-cuts along the strip, alternating thick and thin sections about 3/8" and 1/8", respectively.

To remove the material where the edge will lap, place the strip along the cutting surface edge and slide your knife horizontally to shed the foam excess, leaving the bottom layer of paper intact.

Now remove the thin sections by yanking them out with a pair of tweezers or pliers. They release with a satisfying popping sound. With that extra space, the strip can now curve in on itself and form the clean outer shell of the project!

Cut a piece of your see-through mirror plastic to be larger than your mirror, but smaller than the outer frame. Don't bother trying to cut it in a circle. If you have a plastic scoring knife, that's best. Drag the gouge along your ruler a few times, then snap the plastic along the score. However a utility knife easily cuts this thin material as well, albeit with some flaking of the mirror material along the cut edge, which will be hidden inside the frame anyway.

Step 3: Assemble Frame

Protect your work surface with some scrap material. Heat up your glue gun and prep a bowl of ice water to keep nearby, in case you burn yourself. You can use different adhesive(s) for this project if you prefer.

Apply a dollop of glue on the center of the bottom circle and stick your mirror to it. Rotate and squish the mirror against the foamcore gently, aligning it with the marked circle. Then glue your thin strip to the perimeter of the mirror and tear off any excess, leaving a small gap for wires to pass through.

Place your front "donut" piece face down on the work surface and glue on the lapped edge. Repeatedly press these pieces together and down on the work surface as you glue around the go, so the front edge turns out nice and clean. The outer rim won't go all the way around and that's ok— you can choose to close up this gap later if you want.

Route the NeoPixel strip's wires through the small gap on the mirror rim, and glue it to the interior. Optionally use a clothespin to clamp the strip while the glue cools. Try to avoid getting hot glue on the mirror, but if you do it's ok! A little rubbing alcohol will release its hold on nonporous surfaces like glass.

Clean your work area to remove dust and bits of foamcore. Use a lint free cloth to wipe the mirror completely clean, then grab your see-through mirror and peel the protective cover from one side. Apply a small amount of glue at four points around the inner wall (keep your glue gun motions from dragging over the mirror to avoid stray strands), and glue the see-through mirror in place. Now your reflective surfaces are sealed and protected from dust.

Bask in the double reflectivity by plugging your NeoPixel strip into your Arduino board as in the previous lesson.

Step 4: Circuit Diagram & Pseudocode

Although you're welcome to reference the diagram shown here throughout your build, I highly encourage you to draw your own. You'll have an at-a-glance reference as you build your breadboard and final prototypes, and diagramming your circuits will make it easier to design your own projects in the future. The purpose of a circuit diagram is to show all the electrical connections in a circuit, not necessary their physical positions or orientations.

The connections are as follows:

NeoPixel 5V -> Arduino 5V

NeoPixel GND -> Arduino GND

NeoPixel Din (data in) -> Arduino digital I/O pin (configurable)

one side of momentary pushbutton switch -> Arduino digital I/O pin (configurable)

other side of momentary pushbutton switch -> Arduino GND

This circuit combines NeoPixel strip with a pushbutton for triggering different LED animations, and will use an internal pull-up resistor like you saw in the input/output lesson. Using all this information, we can write a human-readable mockup of our Arduino program, called "pseudocode:"

Variables: NeoPixel pin number, button pin number, how many LEDs there are, how bright the LEDs should be

One-time tasks: initialize button pin as input with internal pull-up resistor, initialize NeoPixel strip, describe LED animations

Looping tasks: check to see if button has been pressed and if it has, switch to a different LED animation

It might seem simple, but taking the time to write pseudocode for your project will help you write your final Arduino sketch faster and with less confusion. It functions a bit like a to-do list as well as a reference guide for when you're swimming in code and can't remember what you're trying to accomplish!

Step 5: Breadboard Prototype

Grab your Arduino and breadboard, and make sure the USB cord is unplugged. Are your NeoPixels still plugged in from the last breadboard exercise? Great! If not, connect them up: 5V to power rail, Din to Arduino pin 6, GND to ground rail.

Then add a momentary pushbutton to your breadboard, straddling the center dividing line. Connect one leg to the ground rail, and its neighboring leg to Arduino pin 2. In the Autodesk Circuits module, click the "Code Editor" button, then "Download Code" and open the file in Arduino, or copy and paste the code into a new blank Arduino sketch.

Plug in your USB cable and upload the code to your Arduino board. Press the button; it should trigger a new animation to play across the NeoPixels. The 5V rail is sufficient for this few pixels on limited brightness, but for future projects with more LEDs, you will need a separate power supply, as discussed in the skills lesson.

Step 6: Code

Let's examine the code in more detail:

#define BUTTON_PIN   2    // Digital IO pin connected to the button.  This will be
                          // driven with a pull-up resistor so the switch should
                          // pull the pin to ground momentarily.  On a high -> low
                          // transition the button press logic will execute.

#define PIXEL_PIN    6    // Digital IO pin connected to the NeoPixels.

#define PIXEL_COUNT 19
#define BRIGHTNESS 100    // 0-255

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_RGB     Pixels are wired for RGB bitstream
//   NEO_GRB     Pixels are wired for GRB bitstream, correct if colors are swapped upon testing
//   NEO_RGBW    Pixels are wired for RGBW bitstream
//   NEO_KHZ400  400 KHz bitstream (e.g. FLORA pixels)
//   NEO_KHZ800  800 KHz bitstream (e.g. High Density LED strip), correct for neopixel stick
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRBW + NEO_KHZ800);

bool oldState = HIGH;
int showType = 0;

Similar to the NeoPixel example code, this first section sets up the NeoPixel strip and the variables for the pushbutton pin, pixel control pin, etc.

void setup() {
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  strip.setBrightness(BRIGHTNESS);
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

The setup function sets pin 2 to an input with its internal pull-up resistor activated, sets the global brightness of the pixels, and starts up the pixel data connection.

void loop() {
  // Get current button state.
  bool newState = digitalRead(BUTTON_PIN);

  // Check if state changed from high to low (button press).
  if (newState == LOW && oldState == HIGH) {
    // Short delay to debounce button.
    delay(20);
    // Check if button is still low after debounce.
    newState = digitalRead(BUTTON_PIN);
    if (newState == LOW) {
      showType++;
      if (showType > 6)
        showType=0;
      startShow(showType);
    }
  }

  // Set the last button state to the old state.
  oldState = newState;
}

The loop function first checks the current state of the button and stores it in a boolean variable (can be one of two states: HIGH or LOW). Then it checks and double checks to see if that state goes from HIGH to LOW. If it did, showType is increased by one, and the startShow function is called, with the current showType passed to it as an argument (showType is constrained to 0-6). The variable oldState is updated to reflect what the last button state was.

void startShow(int i) {
  switch(i){
    case 0: colorWipe(strip.Color(0, 0, 0), 50);    // Black/off
            break;
    case 1: colorWipe(strip.Color(255, 0, 0), 50);  // Red
            break;
    case 2: colorWipe(strip.Color(0, 255, 0), 50);  // Green
            break;
    case 3: colorWipe(strip.Color(0, 0, 255), 50);  // Blue
            break;
    case 4: pulseWhite(5); 
            break;
    case 5: rainbowFade2White(3,3,1);
            break;
    case 6: fullWhite();
            break;
  }
}

The startShow function contains a switch/case statement, which is just a fancy fast way to stack a bunch of if/else statements. The switch case compares the variable i to the values of each case, then runs the code in that statement. The keyword break; exits the switch/case statement. This switch/case is used to call different animation functions every time you press the button.

Now that you've got a functional breadboard prototype, it's time to make this into a finished project by using an Arduino Gemma, which is smaller, less fully featured, and lower cost than the Arduino Uno. You can also use an Adafruit Gemma instead, but you will need to perform an additional step to configure the Arduino software.

First, change the NeoPixel pin variable from 6 to 1 in your code:

#define PIXEL_PIN    1    // Digital IO pin connected to the NeoPixels.

Plug your Arduino Gemma into your computer using a USB cable, and select "Arduino Gemma" as your board type in the Arduino Tools menu.

The limited functions of the ATTiny85 microcontroller onboard don't support a serial port in the same way as the Uno, so you don't have to select anything from the Port menu. However, be sure to select "Arduino Gemma" under the Programmer menu item.

The board needs a little help knowing when you're trying to program it, so press the reset button on the board, and while the red LED is pulsing, press the Upload button to load your sketch onto the Gemma. If your red LED does not pulse when you press the reset button, your USB cable may be power-only, and should be swapped out for a USB cable that has power and data connections. Another reason your LED may not pulse is if you are using a USB 3 port (all newer Macs), which has trouble recognizing the Gemma bootloader. Use a USB 2 port on your computer or a USB hub in between your computer and Gemma.

Step 7: Solder Circuit

To run the circuit with your Gemma, we'll solder the wires directly to the pads on the board. Snip off the breadboard connector and strip, twist, and tin the leads of the NeoPixel strip wires. Solder wires onto diagonal leads of a pushbutton in the same manner (you can use the button from the soldering lesson). Twist and solder together the two ground wires.

Gemma's large holes make it easy to assemble this circuit with no additional parts— just thread the tinned wires through the holes and wrap the excess around the solder pad. The connections are as follows:

  • NeoPixel 5V -> Gemma Vout
  • NeoPixel Din -> Gemma 1~ (digital pin 1)
  • NeoPixel GND -> one side of pushbutton -> Gemma GND
  • other side of pushbutton -> Gemma 2 (digital pin 2)

Set up your circuit board in a third hand tool and heat up the connections with your soldering iron before applying some more solder to engulf the pad and wire. After all the connections cool, trim away excess wire with your flush snips.

Hot glue your Gemma in place with the USB port facing the edge of the circle.

Apply the front/top cover and manipulate the edge to seat the pieces together cleanly. You may have to trim your bottom circle just a bit to make it fit, and likewise pull the edge open to accommodate its mate. Glue the pushbutton in place wherever you like.

Step 8: Use It!

Plug in a USB cable, press the pushbutton, and enjoy! You can switch up the colors and animations by changing the code. Use a USB power adapter if you want to mount it on a wall. At this point you can make another small foamcore edge piece to close up the remaining gap, if you wish. Some suggested uses: hang it on your wall, keep it at your desk, give it to a friend!

You can easily run this project with an internal battery instead of connecting a USB cable. The orientation at which you glue the Gemma will determine the access to the battery port, so you may want to re-glue it at a different angle. 19 RGBW pixels times 80ma max current draw (plus ~10ma for the Gemma) equals 1530ma, which means we technically need a battery with at least that many mAh. However the code for the mirror doesn't come close to using all four pixels' LEDs at full brightness together, so in reality the maximum current draw is far less. A healthy battery compromise is a 1200mAh rechargeable lipoly battery.

Huge congrats on completing your first Arduino project!

Comments

author
BenediktK4 made it! (author)2017-03-21

Wow that was too hard. Installing the adafruit Gemma was really annoying. Didn't understand that it doesn't have its own port. Well now I have my own little project based on yours

IMG_7437.JPG
author
ad1000 made it! (author)2017-03-12

Made my own version here.

20170213_022400.jpg
author
Xavlyon73 made it! (author)2017-02-11

On my way... ?

tmp_9279-IMG_20170211_142320380348174.jpg
author
tomerik-puzzled made it! (author)2017-01-24

Only prototyping!

20170124_131345.jpg
author
bekathwia made it! (author)2017-01-07

I used the infinity mirror to create some low-key xmas decorations this past December!

20161216_104908.jpg
author
mwehri made it! (author)2017-01-05

This was a fun project, and I got some "Cool Dad" points in the process. Now I just need to make 2 more infinity mirrors so each kid can hang in their rooms!

I'm planning to take the LED/Lighting class next to expand on the topics presented here. Thanks for an interesting and well-written tutorial on the basics of Arduino.

Infinity Mirror.jpg
author
bekathwia (author)mwehri2017-01-05

Awesome!

author
nmalatin made it! (author)2016-12-20

Does anyone else have the problem that their pictures upload upside down?

Anyway, I made mine robot silver. I cut out all the parts using a 40 Watt Epilog Engraver. I keep the continuous function aspect. I just like to leave it on and let it do its thing. Thanks for the instructions! The next step is to find some projects that are a little more code-centric. Any recommendations?

File_000 (8).jpeg
author
bekathwia (author)nmalatin2017-01-03

That turned out great! There's a whole collection of "next" projects you can check out in the conclusion or at the bottom of the main "table of contents" class page. Or just search Arduino here on Instructables! Also keep an eye on the classes page as we'll have another Arduino-based class coming soon.

author
gjansen made it! (author)2016-12-29

I printed the frame and use an arduino pro mini to control it. To power it i use a lipo 3,7v 3A and a step up converter to have 5 volts. 32 ws2812 leds

IMG_20161229_192750.jpg
author
bekathwia (author)gjansen2017-01-03

Nice work!

author
thelmara made it! (author)2016-12-19

Didn't have time for full project but quite happy with this part of it.

P1010011.JPG
author
JohnD277 made it! (author)2016-12-17

It's not pretty! Just waiting for the reflective acrylic and hot glue gun(hence the electrician's tape) but it works, and now programming the lights to fade and change colour

IMG_0130.JPG
author
jabutleratmacdotcom made it! (author)2016-12-06

What fun!

IMG_4814.JPG
author

Woohoo, that looks great! Congrats!

author
Reyce made it! (author)2016-11-25

Wonderful project!

I was thinking of doing another infinity mirror but this time I would place the mirror at the bottom of a cylinder box. Then I would cut the height off the box.

Also, do you think I could make this using an arduino uno on a much larger scale with triple the diameter?

The instructions were excellent and this project is awesome!!

File_002 (3).jpeg
author
bekathwia (author)Reyce2016-11-25

That looks great! Of course you could make another with your Uno on a larger scale! Thanks for sharing with us!

author
Justin Tyler Tate made it! (author)2016-11-18

I didn't really want to have an infinity mirror, I just wanted to learn how to use the pixel strip. I did however hot-glue the pixel strip on a normal mirror for a temporary illuminated mirror.

2016-11-18 Instructables Arduino Class, Lesson 6.JPG
author

Hah, thanks for sharing! =D

author
braulio777 (author)2016-11-08

Done

2019.jpg2015.jpg
author
bekathwia (author)braulio7772016-11-09

Nice circuit! But where's the mirror? =D

About This Instructable

13,398views

2favorites

License:

Bio: Becky Stern is a content creator at Instructables. She has authored hundreds of tutorials about everything from wearable electronics to knitting. Before joining Instructables, Becky ... More »
More by bekathwia:Etching & Engraving ProjectsMaking Studio Fall 2013Wine Cork Trivet
Add instructable to: