Introduction: DIY a Magic Light Box

Let's see what Magic Light Box (MLB) is!

MLB is a lighting box that can change the color upon the movment. It is based on Arduino Nano, using tri-axial accelerometer ADXL345 to collect the moving information. Besides, it can be charged by way of wireless charging.

Three Lighting Mode:

Shaking in X direction - White Color Mode

Shaking in Y direction - Auto-changing Color Mode

Shaking in Z direction - Changing upon Attitude Mode

Step 1: Prepare the Materials

Picture of Prepare the Materials

Tools

Iron solder

Hot melt glue gun

Tool for cutting the prototyping board

Materials

1 x Arduino Nano

1 x ADXL345

1 x Wirelss charging module

1 x DC-DC 5V boost module

2 x 3.7V lithium ion battery 952240

20 x Common anode mist RGB led

1 x Resistance of 5 ohms, 100 ohms each one

3 x NPN transistor 8050

N x DuPont line, sewing, fly line

1 x 5.5mm DC Power Interface

1 x 12VDC power adapter

Step 2: Schmatics

Picture of Schmatics

R1 = 5ohm, R2 = 10ohm, the value depends on the number of RGB LED.

Step 3: Connects the Modules

Picture of Connects the Modules

Connects the modules based on the schematic.

Step 4: Testing the Circuit

Picture of Testing the Circuit

Test the circuit to see if the driving part works or not.

Step 5: Add the Glue to Protect the Circuit and Program

Picture of Add the Glue to Protect the Circuit and Program

The Arduino Nano is then covered by the glue to avoid the possible short circuit.

Do the same for the other modules.

Then simply tied them with hot melt adhesive. Before that you can cut off some pins on the modules to save space, such as arduino Nano's ICSP pins. Once the work is completed, this Nano is impossible to use again, so, for those unused IO pins, cut them off!

Program to the Nano, and test the functions. Test the charging effect. After doing the above work, this stuff can be put aside.

Step 6: Installing the RGB LEDs to Acrylic Board

Picture of Installing the RGB LEDs to Acrylic Board

The thickness of the acrylic board is 1.7mm. Cut the boards as the attached designs.

Install the RGB LED to the 5 boards with holes.

All 20 RGB LEDs are in prallel connection. Be careful the polarity of each LED.

I don't recommend using the colored line on the photo, as the soldering point is easy to disconnect.

The soft fly line is a good choice, as it is able to adapt to the process of enclosing acrylic to the cubic.

Note, the current of single line only allowed 47mA or less. So the part closer to the power should be connected more lines. The lines connected to anode pins should be more than the cathode pin.

Pay attention to confirm the fly line is not easy to fall off, and using a multimeter to verify before the final installation.

Yes, this step is very complicated.

Step 7: Test With the Electronic Controlling Part

Picture of Test With the Electronic Controlling Part

Connect the controlling part made above, and test.

Step 8: Install the Internal Cube

Picture of Install the Internal Cube

Connect the boards with hot melt glue to get the Internal LED cube done.

Step 9: Install the LED Cube Onto the Acrylic Base Board

Picture of Install the LED Cube Onto the Acrylic Base Board

Install the LED cube on a white acrylic. Put the wireless charging receiving coil inside the center, self-locking switch to the right position.

Step 10: Install the External Acrylic Cube Boards

Picture of Install the External Acrylic Cube Boards

Glue the acrylic boards into a big cube, and install the LED cube into it.

The main body of the MLB is done, and the size is 96x96x96mm

Step 11: Make the Charging Base

Picture of Make the Charging Base

It's very easy to make the charging base.

Put the DC connecter and the wireless charging module to the acrylic board.

Plug in the power adapter, and put the MLB onto the charging base, the work is finally done.

Thanks!

Made by Xie Linhong

Step 12: Arduino Code Attached

Picture of Arduino Code Attached

#include //use timer lib

#include

#define Register_ID 0

#define Register_2D 0x2D

#define Register_X0 0x32

#define Register_X1 0x33

#define Register_Y0 0x34

#define Register_Y1 0x35

#define Register_Z0 0x36

#define Register_Z1 0x37

int ADXAddress = 0xA7 >> 1;

//variable to keep the info of accelerometer

int X0, X1, Xg;

int Y0, Y1, Yg;

int Z1, Z0, Zg;

//pins for three color

int ledx = 9;

int ledy = 5;

int ledz = 6;

//declare 7 counters

int counterX, counterY, counterZ, counterT, counterx, countery, counterz;

//3 variable to keep the state

int stateX, stateY, stateZ;

//breathing value

int valx = 60;

int valy = 130;

int valz = 195;

//breathing speed

int fadeAmount1 = 3;

int fadeAmount2 = 6;

int fadeAmount3 = 9;

void setup() {

// Serial.begin(9600); //use the serial port to debug

// initial

Wire.begin();

delay(10);

Wire.beginTransmission(ADXAddress);

Wire.write(Register_2D);

Wire.write(8);

Wire.endTransmission();

pinMode(ledx, OUTPUT);

pinMode(ledy, OUTPUT);

pinMode(ledz, OUTPUT);

counterY = 0;

counterX = 0;

counterT = 0;

//set the state of X,Y,Z in off state

stateX = 0;

stateY = 0;

stateZ = 0;

}

void loop() {

//all off

digitalWrite(ledx, 0);

digitalWrite(ledy, 0);

digitalWrite(ledz, 0);

//read the acc info of X,Y,Z

Wire.beginTransmission(ADXAddress);

Wire.write(Register_X0);

Wire.write(Register_X1);

Wire.endTransmission();

Wire.requestFrom(ADXAddress, 2);

if (Wire.available() <= 2);

{

X0 = Wire.read();

X1 = Wire.read();

X1 = X1 << 8;

Xg = X0 + X1;

}

Wire.beginTransmission(ADXAddress);

Wire.write(Register_Y0);

Wire.write(Register_Y1);

Wire.endTransmission();

Wire.requestFrom(ADXAddress, 2);

if (Wire.available() <= 2);

{

Y0 = Wire.read();

Y1 = Wire.read();

Y1 = Y1 << 8;

Yg = Y0 + Y1;

}

Wire.beginTransmission(ADXAddress);

Wire.write(Register_Z0);

Wire.write(Register_Z1);

Wire.endTransmission();

Wire.requestFrom(ADXAddress, 2);

if (Wire.available() <= 2);

{

Z0 = Wire.read();

Z1 = Wire.read();

Z1 = Z1 << 8;

Zg = Z0 + Z1;

}

//judge if acc value of X arrives the threshold, add the counter

if (Xg >= 500 || Xg <= -500) {

counterX++;

//when counter X starts, timer will start, and enter clear function after 0.5s

if (counterX == 1) {

MsTimer2::set(500, Clear);

MsTimer2::start();

}

}

//if the counterX is more than 16 before clearing, open X trig state(auto-changing color)

if (counterX >= 16) { //16 can be changed to other number, the smaller the more sensitive

stateX = !stateX;

while (stateX == 1) {

fading();

}

}

if (Yg >= 500 || Yg <= -500) {

// checking Y

counterY++;

if (counterY == 1) {

MsTimer2::set(500, Clear);

MsTimer2::start();

}

}

if (counterY >= 16) {

stateY = !stateY;

while (stateY == 1) {

following();

}

}

if (Zg >= 500 || Zg <= -500) {

// checking Z

counterZ++;

if (counterZ == 1) {

MsTimer2::set(500, Clear);

MsTimer2::start();

}

}

if (counterZ >= 14) {

stateZ = !stateZ;

while (stateZ == 1) {

white();

}

}

delay(6);

// Serial.print("X=");

// Serial.print(Xg);

// Serial.print(" Y=");

// Serial.print(Yg);

// Serial.print(" Z=");

// Serial.print(Zg);

// Serial.print(" CX=");

// Serial.print(counterX);

// Serial.print(" CY=");

// Serial.print(counterY);

// Serial.print(" CZ=");

// Serial.println(counterZ);

}

void Clear() {

//clear all counters

counterX = 0;

counterx = 0;

counterY = 0;

countery = 0;

counterZ = 0;

counterz = 0;

}

void white() {

//white color

digitalWrite(ledx, 1);

digitalWrite(ledy, 1);

digitalWrite(ledz, 1);

//read the acc of Z

Wire.beginTransmission(ADXAddress);

Wire.write(Register_Z0);

Wire.write(Register_Z1);

Wire.endTransmission();

Wire.requestFrom(ADXAddress, 2);

if (Wire.available() <= 2);

{

Z0 = Wire.read();

Z1 = Wire.read();

Z1 = Z1 << 8;

Zg = Z0 + Z1;

}

if (Zg >= 500 || Zg <= -500) {

counterz++;

if (counterz == 1) {

MsTimer2::set(500, Clear);

MsTimer2::start();

}

}

//if counterZ is more than 140, close the trig state of Z and go back to the main function

if (counterz >= 140) {

stateZ = !stateZ;

return;

}

// Serial.print("Z=");

// Serial.print(Zg);

// Serial.print(" CZ=");

// Serial.println(counterz);

}

void following() {

//跟随姿态变色的程序

int xfollow, yfollow, zfollow;

Wire.beginTransmission(ADXAddress);

Wire.write(Register_X0);

Wire.write(Register_X1);

Wire.endTransmission();

Wire.requestFrom(ADXAddress, 2);

if (Wire.available() <= 2);

{

X0 = Wire.read();

X1 = Wire.read();

X1 = X1 << 8;

Xg = X0 + X1;

}

Wire.beginTransmission(ADXAddress);

Wire.write(Register_Y0);

Wire.write(Register_Y1);

Wire.endTransmission();

Wire.requestFrom(ADXAddress, 2);

if (Wire.available() <= 2);

{

Y0 = Wire.read();

Y1 = Wire.read();

Y1 = Y1 << 8;

Yg = Y0 + Y1;

}

Wire.beginTransmission(ADXAddress);

Wire.write(Register_Z0);

Wire.write(Register_Z1);

Wire.endTransmission();

Wire.requestFrom(ADXAddress, 2);

if (Wire.available() <= 2);

{

Z0 = Wire.read();

Z1 = Wire.read();

Z1 = Z1 << 8;

Zg = Z0 + Z1;

}

//keep the color steady by contraining the value of X,Z. Y is used to exit

Xg = constrain(Xg, -272, 272);

// Yg = constrain(Yg, -272, 272);

Zg = constrain(Zg, -272, 272);

xfollow = map(Xg, -272, 272, 5, 250);

analogWrite(ledx, xfollow);

yfollow = map(Yg, -290, 290, 5, 250);

analogWrite(ledy, yfollow);

zfollow = map(Zg, -272, 272, 5, 250);

analogWrite(ledz, zfollow);

//keep the color steady by contraining the value

xfollow = constrain(xfollow, 1, 255);

yfollow = constrain(yfollow, 1, 255);

zfollow = constrain(zfollow, 1, 255);

if (Yg >= 500 || Yg <= -500) {

countery++;

if (countery == 1) {

MsTimer2::set(500, Clear);

MsTimer2::start();

}

}

if (countery >= 40 ) {

stateY = !stateY;

return;

}

// Serial.print("Y=");

// Serial.print(Yg);

// Serial.print(" CY=");

// Serial.println(countery);

}

void fading() {

//auto-chaning color

analogWrite(ledx, valx);

analogWrite(ledy, valy);

analogWrite(ledz, valz);

valx = valx + fadeAmount1;

valy = valy + fadeAmount2;

valz = valz + fadeAmount3;

if (valx <= 4 || valx >= 252) {

fadeAmount1 = -fadeAmount1 ;

}

if (valy <= 7 || valy >= 249) {

fadeAmount2 = -fadeAmount2 ;

}

if (valz <= 10 || valz >= 246) {

fadeAmount3 = -fadeAmount3 ;

}

delay(90);

Wire.beginTransmission(ADXAddress);

Wire.write(Register_X0);

Wire.write(Register_X1);

Wire.endTransmission();

Wire.requestFrom(ADXAddress, 2);

if (Wire.available() <= 2);

{

X0 = Wire.read();

X1 = Wire.read();

X1 = X1 << 8;

Xg = X0 + X1;

}

if (Xg >= 500 || Xg <= -500) {

counterx++;

if (counterx == 1) {

MsTimer2::set(500, Clear);

MsTimer2::start();

}

}

if (counterx >= 2) {

stateX = !stateX;

return;

}

// Serial.print("X=");

// Serial.print(Xg);

// Serial.print(" CX=");

// Serial.println(counterx);

Comments

ehudwill (author)2016-01-24

This is great. I have been working on a project using the ADXL345 and found this. Thanks for sharing.

RoboterS (author)2014-11-01

Very nice and cool....

MsSweetSatisfaction (author)2014-11-01

Ooo that a very cool gadget, awesome job on the build and the explanation. Here's an instructable on how to use the editor in case you want to get rid of that extra blank step at the end: https://www.instructables.com/id/How-to-Make-an-Ins...
Thanks for showing your awesome cube!

Thanks, it's been done.

About This Instructable

5,668views

59favorites

License:

Bio: I am maker_studio and I love to build the robot of Arduino and DIY something fun. Here is something new&amp;fun: kck.st/2q0eCUG
More by maker_studio:How to DIY a set of pictrue pannel earphonesHow to build  a Bluetooth wireless upload Self-balancing RobotHow to DIY a magnetic car mount QI wireless charger
Add instructable to: