DIY Desktop Light Sculpture This visually pleasing project has endless possibilities for customization and design. Favorited Favorite 4

My latest project, the Desktop Light Sculpture, is a digitally fabricated object featuring a 3D-printed base and laser-etched acrylic inserts. Inside the base you can find a neopixel matrix, a Qduino Mini, and a few other basic electronic components for usability.

The idea for this project is dependent on edge-lighting the acrylic. What this means is that when light is applied to the edge of a piece of acrylic, it will be picked up by any etched parts on the surface of the plastic as well as along its edges. This creates a beautiful visual effect!

The major element of this project is definitely the digital fabrication. I really love that there are two parts to design that have very different design constraints. The first, the 3D-printed base, needs to be designed to fit the electronic parts, hold the acrylic, and separate the light from each row of LEDs (as to not affect a neighboring piece of acrylic). The parameters offer a good design engineering challenge, but offer less in the way of creativity.

The second part, our acrylic inserts, must fit into the slot in the base, but otherwise offer complete creative freedom. They can be any shape or size and feature any etched design. With endless colors, patterns, and animations to program your LEDs, the design possibilities of this project are endless!

If you would like to make this project at home, you can grab everything you need from my Light Sculpture Wishlist.

Both the .stl for the 3D-printed base and the Illustrator file for the acrylic insert shape can be found on thingiverse. The images below illustrate how the parts fit into the base.

You will notice that in addition to the LEDs and microcontroller, the project features a button, a switch and a potentiometer. The button is used to cycle through different LED colors, patterns and animations. The switch will turn the project on or off, and the potentiometer controls the brightness of your LEDs. The diagram below illustrates the circuit used in this project.

Having a hard time seeing the circuit? Click on the image for a closer look.

Below is the program I used for this project. It utilizes the Adafruit Neopixel Library.

//Desktop Light Sculpture by Melissa Felderman for SparkFun Electrnoics July/31/2018 #include <Adafruit_NeoPixel.h> //include afafruit library #define PIN 6 //LED matrix pin #define brightPot A0 //potentiometer to controll brightness #define pwrSwitch 4 //power switch #define momBut 5 //button to control LED mode int numPix = 64; //total LED count int brightPotVal; //Variable to hold pot value int pixelBrightness; //variabe to hold brightness value int switchState; //variable to hold switch value int butState; //variable to hold button value int mode = 0; //starting mode for switch state int prevButState = LOW; boolean butBool = false; int topMode = 4; //max number of LED modes in switch state unsigned long lastDebounceTime = 0; unsigned long debounceDelay = 200; Adafruit_NeoPixel strip = Adafruit_NeoPixel(numPix, PIN, NEO_GRB + NEO_KHZ800); //declare neopixel matrix //create an array for each row of LEDs int rowOne[] = {0, 1, 2, 3, 4, 5, 6, 7}; int rowTwo[] = {8, 9, 10, 11, 12, 13, 14, 15}; int rowThree[] = {16, 17, 18, 19, 20, 21, 22, 23}; int rowFour[] = {24, 25, 26, 27, 28, 29, 30, 31}; int rowFive[] = {32, 33, 34, 35, 36, 37, 38, 39}; int rowSix[] = {40, 41, 42, 43, 44, 45, 46, 47}; int rowSeven[] = {48, 49, 50, 51, 52, 53, 54, 55}; int rowEight[] = {56, 57, 58, 59, 60, 61, 62, 63}; void setup() { Serial.begin(9600); strip.begin(); strip.show(); pinMode(momBut, INPUT); pinMode(pwrSwitch, INPUT); } void loop() { brightPotVal = analogRead(brightPot); pixelBrightness = map(brightPotVal, 0, 1023, 0, 200); switchState = digitalRead(pwrSwitch); butState = digitalRead(momBut); strip.setBrightness(pixelBrightness); strip.show(); //function to debounce button if ((millis() - lastDebounceTime) > debounceDelay) { if ((butState == HIGH) && (butBool == false)) { butBool = true; mode++; lastDebounceTime = millis(); } butBool = false; } if (mode > topMode) { mode = 0; } Serial.println(mode); //switch state function to cycle through modes on LEDs, you can add as many or as few as you would like if (switchState == HIGH) { switch ( mode ) { case 0: for (int i = 0; i < numPix; i++) { strip.setPixelColor(i, 255, 255, 255); } strip.show(); break; case 1: rainbow(); break; case 2: buleGreenGradient(); break; case 3: pinkGradient(); break; case 4: yellowGradient(); break; } } else if (switchState == LOW) { for (int i = 0; i < numPix; i++) { strip.setPixelColor(i, 0, 0, 0); } strip.show(); } } //functions for LED colors void everyOther() { for (int i = 0; i < 8; i++) { strip.setPixelColor(rowOne[i], 255, 255, 255); strip.setPixelColor(rowThree[i], 255, 255, 255); strip.setPixelColor(rowFive[i], 255, 255, 255); strip.setPixelColor(rowSeven[i], 255, 255, 255); strip.setPixelColor(rowTwo[i], 0, 0, 0); strip.setPixelColor(rowFour[i], 0, 0, 0); strip.setPixelColor(rowSix[i], 0, 0, 0); strip.setPixelColor(rowEight[i], 0, 0, 0); } strip.show(); } void pinkGradient() { for (int i = 0; i < 8; i++) { strip.setPixelColor(rowOne[i], 185, 0, 255); strip.setPixelColor(rowTwo[i], 195, 0, 230); strip.setPixelColor(rowThree[i], 205, 0, 200); strip.setPixelColor(rowFour[i], 215, 0, 160); strip.setPixelColor(rowFive[i], 225, 0, 120); strip.setPixelColor(rowSix[i], 235, 0, 80); strip.setPixelColor(rowSeven[i], 245, 0, 40); strip.setPixelColor(rowEight[i], 255, 0, 10); } strip.show(); } void buleGreenGradient() { for (int i = 0; i < 8; i++) { strip.setPixelColor(rowOne[i], 0, 75, 255); strip.setPixelColor(rowTwo[i], 0, 100, 225); strip.setPixelColor(rowThree[i], 0, 125, 200); strip.setPixelColor(rowFour[i], 00, 150, 175); strip.setPixelColor(rowFive[i], 0, 175, 150); strip.setPixelColor(rowSix[i], 0, 200, 125); strip.setPixelColor(rowSeven[i], 0, 225, 100); strip.setPixelColor(rowEight[i], 0, 255, 75); } strip.show(); } void yellowGradient() { for (int i = 0; i < 8; i++) { strip.setPixelColor(rowOne[i], 255, 255, 25); strip.setPixelColor(rowTwo[i], 255, 220, 25); strip.setPixelColor(rowThree[i], 255, 190, 25); strip.setPixelColor(rowFour[i], 255, 160, 25); strip.setPixelColor(rowFive[i], 255, 130, 25); strip.setPixelColor(rowSix[i], 255, 100, 25); strip.setPixelColor(rowSeven[i], 255, 70, 25); strip.setPixelColor(rowEight[i], 255, 40, 25); } strip.show(); } void rainbow() { for (int i = 0; i < 8; i++) { strip.setPixelColor(rowOne[i], 255, 0, 0); } for (int i = 0; i < 8; i++) { strip.setPixelColor(rowTwo[i], 255, 100, 0); } for (int i = 0; i < 8; i++) { strip.setPixelColor(rowThree[i], 255, 255, 0); } for (int i = 0; i < 8; i++) { strip.setPixelColor(rowFour[i], 0, 255, 0); } for (int i = 0; i < 8; i++) { strip.setPixelColor(rowFive[i], 0, 255, 200); } for (int i = 0; i < 8; i++) { strip.setPixelColor(rowSix[i], 0, 0, 255); } for (int i = 0; i < 8; i++) { strip.setPixelColor(rowSeven[i], 255, 0, 255); } for (int i = 0; i < 8; i++) { strip.setPixelColor(rowEight[i], 255, 0, 130); } strip.show(); }



I hope you enjoyed this project! It was a lot of fun to make and I'm excited to continue building out the program for more LED colors, as well as making different designs on the laser-etched acrylic.

If you love this project and want to give it a go but don't have access to digital fabrication tools, try checking out your local library or maker space. If all else fails there are always online digital fabrication services from which you can order your 3D print and laser-etched acrylic. As always, please share your thoughts, ideas, and suggestions about this project in the comments below!



