Now that 3D printing in transparent materials is widely available, we really can start having fun with models playing with light. There's also super convenient ways to use high numbers of RGB LEDs with the Arduino, using Adafruit's Neopixels which only need one digital pin for example.
This Instructable, describes how you can bring life to your favorite models (in my case, fruit fly brains ^^) by lighting them up, using optical fibers placed throughout the volume which create a nice 3D light show. I give a little bit more context about this project on my webpage.
Step 1: Materials and Tools
- Optical fibers (I sourced mine from Fiberopticproducts.com)
- Adafruit Neopixels (I bought them in a strip, but a matrix would be easier, see step 4)
- An Arduino to control the LEDs
- A hardboard panel (3mm thick in my case) or other opaque material to make the box
- A 3d printer capable of making transparent models. I had access to a Formlabs Form 1+ when I built this project
You can order your print online from a 3d printing service like Shapeways.com
- A soldering Iron
- A laser cutter
A hand drill and saw
- A Dremel with cutting wheel
- Epoxy glue
Software and files
- A 3D model that you would like to turn into a lamp, ideally an stl file, start with a clean mesh. The one I used is on my Thingiverse repository.
Step 2: Fiber Placement and Orientation
The first step is to decide how many fibers to use and where to place them in Blender. After opening the stl file, make sure to scale your model to you final dimensions, so that you can start to visualize the space that the fibers will take given their diameter.
It helps a lot to generate spheres on a 3D grid slightly larger than the model itself, then remove all the spheres that are not entirely within the bounds of the model. The remaining ones, inside the model, represent the location of the ends of the fibers.
I chose the diameter of the spheres to be three to four times the diameter of the optical fibers, to represent the size of the light sources that they'll produce and make sure that none is too close to the surface of the model, which would make very bright spots and ruin the overall look.
Play with the grid spacing until the number of spheres that you obtain is reasonable. I had 53 fibers in a model whose largest dimension was ~ 100 mm, with fibers of diameter 2 mm.
Once you have a reasonable number of spheres, time to decide how to feed the fibers in the model.
Create cylinders with diameter slightly larger than the fibers themselves (I used 2.4 mm cylinders for my 2 mm fibers), which end at the center of the spheres that you've created. Orient them so that there is no overlap, but making them all roughly point towards the same origin, and imagine how the result will look like in the end. I hope the images I posted help a little.
Remember that the fibers are not very flexible, so do use cylinders and not curved pipes (or at least keep the curvature low), and think about the path of the fibers from the model to the LEDs.
Carve out the fiber guides in the model. This is done in the object modifiers tab after selecting the model mesh, adding a boolean modifier and selecting the "difference" operation and the fibers one by one as second object and clicking apply. This modified object can then be exported as stl, and it's time to
Step 3: Print the Model and Glue the Fibers
Print the model, or get it printed by a store, in a transparent plastic/resin.
Cut the fibers using the cutting wheel of the dremel. I cut mine to a length of 25cm each to have room to shorten them later. I first tried using pliers to cut them, but the fibers tend to break and not give a clean cut, the dremel seems to do a better job and give a nicer end surface. If your dimensions and position were correct in the previous step, you should be able to feed in the fibers in all the guides. Do it once without using glue, just to make sure that there is no conflict between two fibers.
Using a small amount of epoxy each time, glue the fibers one by one. Start from the center of the model outwards, otherwise you'll have to navigate between fibers that you have already placed and you'll probably spread epoxy everywhere.
Step 4: Optional, Make a Panel for the LEDs
If you bought LEDs in a strip, like me, you'll have to build a mounting panel to hold them in a regular grid and facilitate coupling the fibers to their respective light source. I used a laser cutter to make my panel in an acrylic sheet, as per the red design in the first picture, then cut the strip accordingly and re-soldered the contacts at the back. One could probably hand-make such a mounting board, but it would be much easier for one to start directly with a Matrix of Neopixels, which already come in a regular grid and are already secured to a rigid PCB, with the proper contacts.
Step 5: Design and Assemble the Box
Design the box to the dimensions of your LED panel/grid. It is important that the LEDs are held strongly in place. Make sure to remember to include enough room to host an arduino board and have an opening on the side to fit the power cord.
I also used the laser-cutter for making the box in a sheet of hardboard, I attached the svg design file containing the six sides and the LED panel.
Match the location of the LEDs with holes in the top panel of the box, with the same diameter as your fibers (you can always widen them slightly afterwards if the fibers don't fit). If you look closely at the Neopixels, the light emitting regions are slightly offset compared to the center of the circles. To try to maximize the light entering the fibers, I actually offset the location of the wholes by a half millimeter.
The Neopixel LEDs are controlled by their numberon the strip/matrix, so you need to decide on a numbering for the fibers. I numbered mine depending on the location of their ends inside the model, from left to right first, then front to back, then bottom to top (x, then y, then z coordinates).
Then, use this numbering to slide the fibers in the holes matching their respective LEDs. This way, you can write the arduino code according to the light pattern you want to create in your model, knowing which area will be controlled by which LED.
It can be a little tedious to place each fiber in the right hole, and to the length you desire. So be patient, don't force things, and pull on the fibers one by one until you're happy with the result. Finally, use the Dremel to cut the extra length on the inner side of the box panel.
Finally, secure the arduino, connect the power and signal wires for the LEDs, and close the box !
Step 6: Light It Up !
Time to program your Arduino to control the LED strip/matrix !
The easiest way to start is to get the Adafruit Neopixel Library and open the Strandtest example. Make sure to change the pin number where you connected the signal wire of the Neopixels, and the number of pixels you used in your setup.
Upload the sketch, and if all went well, you should see your model light up with pretty colors.
Step 7: Where to Go From Here
Playing with the example sketch provided by Adafruit is fun. However some of you might want to have more control over what gets displayed on the model. In my case I wanted to use the model to visualize actual research data on the brain activity of the fruit fly.
For this part, you'll have to do a little bit of math and coding. I won't give all the details in this Instructable, mostly because I want to keep it about the hardware and because everybody will have a different idea in mind about what they want to do with their specific model. However I'd be happy to help out if people have questions in the comments, and in the meantime here are some basic concepts and ideas, as well as links to great resources where to get more info :
If there aren't too many LEDs in your model, you could write, one by one, the color and intensity you wish to display on each of them using the setPixelColor function of the neopixel library. However, from the previous steps, you know which fiber corresponds to which location inside the model (it is the location of the spheres in step 2). By storing these coordinates in a matrix, with three columns and as many rows as there are fibers, you can easily link the LED number to the respective x,y,z coordinates inside the model.
It then allows you to use these x,y,z coordinates in mathematical expressions, like trigonometric functions, to spatially modulate the color and intensity displayed by each LED. This modulation can be animated by making them also time dependent. You can look at the amazing 8x8x8 LED cube Instructable, steps 55 to 62, or this link, to get ideas.
If, like in my case, you want to display three-dimensional data acquired elsewhere, it will probably come in values measured on a cartesian grid. Since we don't have an LED for each data point, we need to interpolate the data to the x,y,z coordinates corresponding to the fiber ends. The arduino microcontroller doesn't have enough memory and processing power to store the initial data and do the interpolation, so you'll want to preprocess the data. You probably have a mathematical programming language of choice (matlab, python...), which will have its on interpolation functions. Note that even processed data can take a lot of space, so you can store it in the program memory of the arduino (32k instead of the 1k of the sram) using the PROGMEM keywords.
I attached my arduino sketch to show how to manage the memory. For my 53 LEDs, a color animation can contain up to about 170 frames, that I store in a (FrameNumber)x(LEDnumber)x3 array. Otherwise it's a pretty simple code, which updates the colors displayed by the LEDs using two for loops which cycle through the frames.
Here we go, I hope this gets you started, I'd be glad to help out in the comments !