Intro: Low-Poly Iron Man With Wifi-Controlled LED Strips
This interactive wall art piece is approximately 39" tall and 24" wide. I laser cut the wood at Clemson University's Student Makerspace, then I hand-painted all the triangles and installed the lights on the back of it. This instructable will walk through how I made this exact piece, hopefully the concept of it will inspire someone else to make their own unique piece of art. It uses an ESP8266 microcontroller with addressable WS2812B LED strip lights and regular RGB LED strip lights.
Parts and Materials
- 1/4" wood - 40" by 28" (Max dimensions for our laser cutter)
- 1/8" opaque acrylic - TAPPlastics (I use Lighting White, 69%)
- Battery pack - TalentCell 12V/5V battery pack (I used 12V/6000mAh pack)
- RGB LED strip - 6ft ish (Standard 4 wire, the 5050 version where the RGB light is all in one module)
- TIP122 transistor for PWM control of many lights
- WS2812B LED strip - 2ft ish (I used the version with 144 LED's per meter)
- ESP8266 NodeMCU microcontroller
- Solid core 22 gauge connector wire (link1 -- link2 -- link3 -- link4)
- Some 300Ω ish resistors
- Paint - I mostly used Craft Premium paint. Details in painting step
- Access to a laser cutter (I used one at Clemson)
- Soldering iron
- Hot glue gun (this is essential)
- Wire cutters/strippers
- Adobe Illustrator
Step 1: Design in Illustrator
The source image is an illustration by William Teal, please give his portfolio a look for other great works by him: https://www.behance.net/tealeo93 (I think it's his - I followed the rabbit hole of GoogleImages, Pinterest, GraphicDesignJunction, Behance)
I found the source image from a google search for "Low-Poly Iron Man" or "Geometric Iron Man Wallpaper". I downloaded the picture and opened it in Adobe Illustrator.
Next, I used the pen tool in Illustrator to manually draw over every line in the image. I did this so that the laser cutter could etch all the inside lines as a vector cut set to low power instead of having to raster over the entire image. It took a few hours to do (aka about 3 class periods at school)
Once the picture was entirely outlined I grouped all those lines together and then drew shapes for the hands, chest, and eyes. I put these all in a group and set their fill color to be blue just so I could easily tell them apart. I copied those to a separate file for the acrylic cut.
For the acrylic part I wanted to maximize the efficiency of my acrylic piece so I uploaded it to this website http://svgnest.com/ and uploaded a file with just the acrylic cut pieces and let it "nest" the parts. This uses some iterations and cool algorithms to determine the most efficient layout of your parts on the sheet to minimize waste. It output the configuration that is in the IronManAcrylic.ai file.
Step 2: Laser Cutting
Before cutting the wood I spray painted it with primer and then lightly sanded it to start it smooth. I did this so that the paint later should come out more evenly.
When I cut the outline all the way through the wood I used 100% power 6% speed (I think) on our 60W Epilog Fusion M2 40 in the Clemson Makerspace. This worked for most of it, but the wood was very warped in a corner so I actually had to refocus the laser for that corner and run that part of the cut again.
Since I also drew lines for all the inside triangles, I was also able to use a vector cut to quickly etch all those lines as shown in the video above. This was significantly faster than it would have been to raster etch the file. I think I used 70% speed and 50% power - you'll just have to experiment though.
The 1/8" acrylic I first cut at 100% power and 8% speed which was a little bit too powerful and left some scorch marks on the unprotected acrylic, so then I did it at 14% speed and it worked like a charm.
Step 3: Painting
So. Much. Painting. I'd estimate it was about 20 hours of painting.
If you're thinking about doing a project with as many triangles as this, please don't paint it yourself. Just pay to get the image printed on metal or wood and then cut that out, or get it printed on something else and glue that piece onto something solid. Just don't paint it yourself unless you love painting.
I used FrogTape painters tape to outline each triangle on the piece as I painted this. This gave me much more consistent results than my early attempts at filling in each triangle by hand without any tape borders.
The FrogTape gives lines that are much more crisp than the white or blue painters tape. Your time and sanity is completely worth the extra $2/roll of tape. If you want it to be skinnier you can use an exacto knife to cut the top few layers of tape into even smaller strips so that when you outline one triangle it doesn't cover up as many neighboring triangles.
I'm cheap and don't have much experience with painting so I used 2 oz bottles of paint from Michael's or Hobby Lobby. I found that the Craft Smart Premium line covered fairly well, and ended up using the CraftSmart Premium Metallic Festive Red paint mixed with white or black to make 95% of my red shades. Yellow was just the Craft Smart premium yellow, with a little gold thrown in as an attempt to make it slightly glittery.
If you know of a cheap-ish paint that covers better - please let me know in the comments!! I often had to do two coats of paint so that none of the white below would show through, and I'd love to have some nicer paint that would avoid that.
Once it was all painted (but before gluing in the acrylic pieces) I used a glossy clear coat spray to protect the paint and make it all shiny.
Step 4: Acrylic Pieces and Acrylic Backlights
Attaching the acrylic pieces was a bit of a challenge because my workbench/desk and the wood piece are both slightly warped, so there was no way I could guarantee that it would all stay flat long enough for my epoxy to set. As a workaround, I pressed the wood down to the table near the acrylic piece I was glueing in and first used hot glue to hold each acrylic piece in place. The hot glue is visible from the front side of the acrylic, so I then used Gorilla Glue two part epoxy applied with a toothpick to permanently hold the acrylic pieces in place. I went back through with small pliers and pried out the original hot glue pieces.
I made a separate light module for each acrylic piece. First I cut a piece of 1/4" black foam board to a size slightly bigger than necessary and drew an outline of the acrylic piece on it. Then I cut and taped the LED strips for that piece in a way that mostly covered the acrylic area.
This step would be better done with a prototyping board and some screw terminals, but I didn't have those on hand when I was ready to start wiring it. As a workaround, I cut some female header pin strips to 4 inputs - Ground, 5V in, data in, data out. I hot-glued the female header strip to the foam board and began soldering all the lights together.
The soldering was actually really challenging because of how small those solder pads were. Luckily I had two chances for all the power and ground pads because each strip can be supplied power to either end. I laid out the strips so that the data wire flowed in a serpentine pattern. I use a soldering iron with adjustable temperature and I've found that I like the temperature to be at the upper end of the range colored green - I probably like it hot because the soldering iron I used for years was cheap and had no temperature controls and ran hot.
Once everything was soldered on, I used an exacto knife (with a fresh blade) to cut strips of the foam board to enclose the lights and reduce bleed-through. I used white instead of black because I had longer strips of it and actually it was a good thing because it allowed me to easily see from the back side if that section of LED strips was turned on during the testing step of wiring it all up.
Step 5: The Rest of the Electronics
I always try to wire my projects by first putting in the power inputs, then the controller, then the other board elements and peripherals. I hot glued the battery pack in place and then routed the split DC jack cable so that the charging input was easily accessible from an edge of the project for easy charging. The battery pack came with the split cable and the instructions said it was fine to charge the battery pack while it is in use.
I cannibalized a cheap micro-usb cable and replaced the micro USB end with a DC barrel jack so I could just use the 5V input. I put 5V on one voltage rail of the breadboard and into the ESP8266 Vin pin, then ground into the ground rail and a ground pin of the ESP8266 (all the grounds should be wired together internally in the controller so it doesn't matter which one)
Standard RGB LED strips are controlled by a PWM signal from the controller. However, microcontrollers can only supply 20mA-50mA of current per pin depending on the controller. Each LED in the strip requires around that much power, so we have to use some kind of transistor to control the strips. A few places that popped up on google searches suggested the TIP122 transistor which can switch 5 amps or 40W of power - more than enough for our application. They aren't really designed to fit into a breadboard, but if you turn each wire sideways 90° then it will fit into the breadboard slots. I originally planned to screw a small heatsink to each one, but after some testing I determined that they don't get hot enough for it to be necessary. I wired each transistor input to a pin on the ESP8266 designated for PWM output
The RGB LED strips that I had happened to have the "water resistant" rubber coating, and as a result wouldn't remain glued to the wood as well as I would like. As a workaround, I cut small pieces of foam board and glued the foam piece to the wood and then glued the LED strip to those.
Step 6: Programming Overview
This project uses various libraries so that it can be controlled from a phone app called Blynk, turned on/off from an Amazon Echo, and the code can be updated over wifi. Some of the libraries used are below
Blynk - https://www.blynk.cc/
Blynk is a service that allows simple control between an ESP8266 microcontroller and a customizable phone app. The phone app allows you to build an application with buttons, sliders, RGB color pickers, and much more. Each "widget" changes a value that can be pulled from the Blynk app whenever you run a certain function.
OTA (Over the Air) Update- default library included with the ESP8266
Alexa Wemo Emulator - https://github.com/witnessmenow/esp8266-alexa-wemo...
Tricks the Amazon Echo into thinking that your project is a Wemo light switch. The code allows you to define a function to run when Alexa sends the "turn on" signal and a separate function for the turn off signal. You can emulate multiple devices (up to 10) with a single controller which allows even more flexibility. My code is set up so that the Echo finds two devices named "Iron Man" and "Night Light". They're both this project and this controller, but if I turn on "Night Light" it will run a function with dim white lights, where as turning on "Iron Man" sets the outer LED strips to red and the acrylic pieces to white.
Arduino editing in Visual Studio using vMicro
I've been using Visual Studio at work for a few months now and I love all the autocomplete tools it has built in, so after some searching I found that I could actually use Visual Studio instead of the normal Arduino IDE. A single computer vMicro license costs $15 for students, which in my opinion is totally worth it if you're going to spend more than a few hours programming Arduino code.
FastLED vs Neopixel
I use FastLED in my projects simply because I found more functions online already made for it, and at this point I've made many projects using it so I have lots of code to reuse. I'm sure the Neopixel library would work just as well if you worked on it enough. I'm planning on putting all my custom functions on GitHub for other people to use, I just haven't gotten around to it yet.
Step 7: Programming Tips
I'm a controls engineer at my job and we often use a style of programming called PLC programming. This type is similar to Arduino in that it has a loop that runs constantly every few milliseconds and deals with inputs/outputs, jumping between different "states" in the code. For example, the code might hit a step dealing with a conveyor where if there is a tray on the conveyor it will proceed to state 45, but if there is no tray it will proceed to state 100. This programming style inspired my code, though I made some changes so that I can just read a string instead of a state number.
I use a global variable (commandString) to keep track of which light state the project is in. Additionally, I use a boolean called "animate" too determine if it will break out of a function or not. So when you press the "Classic mode" button on Blynk my code will set animate to false (so that it breaks out of the current function) and set the commandString to "RunClassic". Each function constantly checks for input from Blynk, Alexa, and OTAUpdate by running a function "CheckInput".
I use global variables to keep track of some settings in my project. These variables are initialized before my setup code, which makes them accessible to any function in my code.
- globalBrightness (0-255)
- globalSpeed - the animation speed of any animated functions. This project just has fading rainbows
- globalDelayTime - FastLED needs about 30 microseconds to write information to each LED, so I set this variable to NUM_LEDS * 30 / 1000 + 1; then add delay(globalDelayTime) after most times I do FastLED.show() so that the command isn't interrupted.
- _r, _g, _b - global RGB values. That way different color scheme buttons can just change the global r/g/b values and all call the same function in the end
Arduino OTA update controller naming
It took me an annoying amount of searching until I figured out how to name the controller using the over the air update function. Literally just include this line in the setup section of your code before "ArduinoOTA.onStart(" -
vMicro with Visual Studio tips
Sometimes visual studio will detect some problems with deep files like the standard C++ files and throw some errors. Try toggling the different types of error messages on/off until you just have errors with your open project and not any supporting files. You can also open the code in the Arduino IDE and see if it will compile in there or if it will give a more helpful error code.
Message me if this Instructable has been up for more than a few weeks and I still haven't figured out how to put my custom functions on GitHub.
FastLED is listed as being compatible with the ESP8266, but the pin definitions might not be correct. In the documentation for FastLED it says you can try including one of the following lines before #include <FastLED.h>
- //#define FASTLED_ESP8266_RAW_PIN_ORDER
- //#define FASTLED_ESP8266_NODEMCU_PIN_ORDER
- //#define FASTLED_ESP8266_D1_PIN_ORDER
However, I tried all three and never had all my pins match up. Currently I'm using the last line and just accepted that when I tell FastLED to use pin D2 it actually uses pin D4 on my controller.
Even though my lights are just the cheap chinese knockoff of Neopixels, I still tell FastLED to treat them as Neopixels in the setup
- FastLED.addLeds<NEOPIXEL, PIN>(leds, NUM_LEDS);
- //FastLED.setMaxPowerInVoltsAndMilliamps(5,maxMilliamps); //Useful for battery powered projects
Step 8: Final Product
Feel free to comment or email me questions - I love this stuff and would love to help other people make cool projects. Check out my website for some other projects I've done and some of my photography: www.jacobathompson.com