Christmas Balls
By Roser Falcón and Raquel Tresserra
Industrial design engineering in Elisava
Course: academic uses in specific English terminology
Tutor: Jonathan Chacón Perez
Project Definition
INTRODUCTION
So why buy Christmas lights for the tree, when you can have balls that have lights inside?
With this project, what we want to offer is a new alternative to decorate the Christmas tree. We want to bring a new design to the tree decoration, instead of buying the decorative elements on one side and the lights on the other, why not create a single element that provides both? This is where the Christmas Balls project comes in.
Christmas Balls is a set made up of three different types of Christmas balls and a separate pyramid structure that works as a switch. When throwing this pyramid, some lights will light up or others, depending on the face that is upside down. Apart from bringing a new idea to decorate the tree, this project also provides a more fun and direct way to interact with the Christmas tree.
PROJECT ELEMENTS
The elements used in the project are as follows:
- Arduino UNO board (with USB cable connector)
- MPU 6050 Gyroscope
- Male-male jumpers (25 cm)
- 3 x color RGB LEDs: white, blue and red
- 3 x 470 ohms resistors
- Welding board
- Welder
- Tin
- 3 x Transparent Christmas balls
- Christmas tree
Gyroscope: The MPU-6050 is an element with 6 degrees of freedom. This means that it carries an accelerometer and a gyroscope, both with 3 axes (total of six, 3 for the accelerometer and three for the gyroscope). It operates with 5 volts. It uses the I2C communication protocol, this library can be found inside the code folder. For the gyroscope code to work, you must first insert this library.
For the realization of the project, the part of the accelerometer is not of any interest, so we will focus entirely on the part of the gyroscope, which will determine the different positions.
Gyroscope Code
First of all, the sample code of a gyroscope is loaded into the Arduino program. This code can be found on the internet with its corresponding libraries. What this code allows us to do is to join the instructions that we want to realize the element with the physical movements that it suffers.
The code is attached below:
<pre>// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files<br>// for both classes must be in the include path of your project #include "I2Cdev.h" #include "MPU6050.h"
// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation // is used in I2Cdev.h #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE #include "Wire.h" #endif
// class default I2C address is 0x68 // specific I2C addresses may be passed as a parameter here // AD0 low = 0x68 (default for InvenSense evaluation board) // AD0 high = 0x69 MPU6050 accelgyro; //MPU6050 accelgyro(0x69); // <-- use for AD0 high
int16_t ax, ay, az; int16_t gx, gy, gz;
// uncomment "OUTPUT_READABLE_ACCELGYRO" if you want to see a tab-separated // list of the accel X/Y/Z and then gyro X/Y/Z values in decimal. Easy to read, // not so easy to parse, and slow(er) over UART. #define OUTPUT_READABLE_ACCELGYRO
#define LED_PIN 13 bool blinkState = false;
void setup() { // join I2C bus (I2Cdev library doesn't do this automatically) #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin(); #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire::setup(400, true); #endif
// initialize serial communication // (38400 chosen because it works as well at 8MHz as it does at 16MHz, but // it's really up to you depending on your project) Serial.begin(38400);
// initialize device Serial.println("Initializing I2C devices..."); accelgyro.initialize();
// verify connection Serial.println("Testing device connections..."); Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
}
void loop() { // read raw accel/gyro measurements from device accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
// these methods (and a few others) are also available //accelgyro.getAcceleration(&ax, &ay, &az); //accelgyro.getRotation(&gx, &gy, &gz);
#ifdef OUTPUT_READABLE_ACCELGYRO // display tab-separated accel/gyro x/y/z values Serial.print("a/g:\t"); Serial.print(ax); Serial.print("\t"); Serial.print(ay); Serial.print("\t"); Serial.println(az); #endif /* #ifdef OUTPUT_BINARY_ACCELGYRO Serial.write((uint8_t)(ax >> 8)); Serial.write((uint8_t)(ax & 0xFF)); Serial.write((uint8_t)(ay >> 8)); Serial.write((uint8_t)(ay & 0xFF)); Serial.write((uint8_t)(az >> 8)); Serial.write((uint8_t)(az & 0xFF)); #endif **/ // fes parpadejar el led per indicar activitat blinkState = !blinkState; digitalWrite(LED_PIN, blinkState);
delay(1000);
Circuit Assembly With Gyroscope
The most important thing in this step is to know how the gyroscope is connected to the Arduino one. To make this transfer of information, the following connection parameters must be followed. As you can see on the gyroscope, there are several inputs, while some will be used to make the connection, there are others that will not be used for the project. The inputs used are the following:
VCC ---> Power 5V (orange jumper)
GND ---> Analog GND (yellow jumper)
SCL ---> Digital PIN A5 (green jumper)
SDA ---> Digital PIN A4 (blue jumper)
XDA ---> nothing
XCL ---> nothing
ADO ---> nothing
INT ---> Digital PIN 2 (violet jumper)
These are the connections that must be made for the correct operation of the gyroscope, and for it to transmit the information correctly to the Arduino. Different colored jumpers are used to make it easier to identify each input of the gyroscope.
LEDs Code
Once you have the gyroscope code and its physical circuit installed. Proceed with programming the code of the LEDs (Blue, Green and Red). That code will be written along with the code you already have.
This section specifies the function of the LEDs according to the face of the pyramid facing downwards. For example, if the face facing down is the face with the snowflake pattern, a code part will be created to determine that when this face is facing down, only the blue LED will illuminate. And the same goes for the other sides of the pyramid with the other LEDs.
If it is determined that only one specific LED is illuminated for a certain face, in turn it must be determined that the other LEDs are not illuminated. You can see how the code is the same for each side, only by modifying if the LEDs are on or off. The only side that is different is the ON/OFF symbol side, which will light up all the LEDs.
To determine the different activation positions of the LEDs, it was done according to the signs in each position (ax, ay and az) of each face. These position ranges, determined by the gyroscope, can be seen in the table of the second picture. They are also specified below:
On/off face: ax= + ay= - az= +
Snowflake face: ax= - ay= - az= -
Star face: ax= - ay= - az= +
Mistletoe face: ax= - ay= + az= +
The operating code of the LEDs is the following:
int ledBlue = 6;<br>int ledGreen = 7; int ledWhite = 5;
// configure Arduino LED pin for output pinMode(LED_PIN, OUTPUT); pinMode(5, OUTPUT); pinMode(6, OUTPUT); pinMode(7, OUTPUT);
Serial.println("part dels leds: "); if ( (0 > ax ) && ( 0 > ay) && ( 0 > az ) ) { //encen led 1 COPITO digitalWrite(ledBlue, HIGH); digitalWrite(ledGreen, LOW); digitalWrite(ledWhite, LOW); Serial.println("blue");
}
//cara 2 else if ((0 > ax) && (0 > ay) && (0 < az) ) { //encen led 2 ESTRELLA digitalWrite(ledBlue, LOW); digitalWrite(ledGreen, LOW); digitalWrite(ledWhite, HIGH); Serial.println("yellow"); }
//cara 3 else if ( (0 > ax ) && (0 < ay ) && (0 < az ) ) { //encen led 3 MUERDAGO
digitalWrite(ledBlue, LOW); digitalWrite(ledGreen, HIGH); digitalWrite(ledWhite, LOW); Serial.println("red");
}
//cara 4 else if ( (0 < ax) && (0 > ay ) && ( 0 < az ) ) { //encen led 4 ON/OFF (TOTS ELS LEDS) digitalWrite(ledBlue, HIGH); digitalWrite(ledGreen, HIGH); digitalWrite(ledWhite, HIGH); Serial.println("tots"); }
Final Code
The definitive code is attached below:
// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files // for both classes must be in the include path of your project #include "I2Cdev.h" #include "MPU6050.h"// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation // is used in I2Cdev.h #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE #include "Wire.h" #endif// class default I2C address is 0x68 // specific I2C addresses may be passed as a parameter here // AD0 low = 0x68 (default for InvenSense evaluation board) // AD0 high = 0x69 MPU6050 accelgyro; //MPU6050 accelgyro(0x69); // <-- use for AD0 highint16_t ax, ay, az; int16_t gx, gy, gz; int ledBlue = 6; int ledGreen = 7; int ledWhite = 5;// uncomment "OUTPUT_READABLE_ACCELGYRO" if you want to see a tab-separated // list of the accel X/Y/Z and then gyro X/Y/Z values in decimal. Easy to read, // not so easy to parse, and slow(er) over UART. #define OUTPUT_READABLE_ACCELGYRO#define LED_PIN 13 bool blinkState = false;void setup() { // join I2C bus (I2Cdev library doesn't do this automatically) #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin(); #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire::setup(400, true); #endif // initialize serial communication // (38400 chosen because it works as well at 8MHz as it does at 16MHz, but // it's really up to you depending on your project) Serial.begin(38400); // initialize device Serial.println("Initializing I2C devices..."); accelgyro.initialize(); // verify connection Serial.println("Testing device connections..."); Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed"); // configure Arduino LED pin for output pinMode(LED_PIN, OUTPUT); pinMode(5, OUTPUT); pinMode(6, OUTPUT); pinMode(7, OUTPUT); }void loop() { // read raw accel/gyro measurements from device accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz); // these methods (and a few others) are also available //accelgyro.getAcceleration(&ax, &ay, &az); //accelgyro.getRotation(&gx, &gy, &gz);#ifdef OUTPUT_READABLE_ACCELGYRO // display tab-separated accel/gyro x/y/z values Serial.print("a/g:\t"); Serial.print(ax); Serial.print("\t"); Serial.print(ay); Serial.print("\t"); Serial.println(az); #endif /* #ifdef OUTPUT_BINARY_ACCELGYRO Serial.write((uint8_t)(ax >> 8)); Serial.write((uint8_t)(ax & 0xFF)); Serial.write((uint8_t)(ay >> 8)); Serial.write((uint8_t)(ay & 0xFF)); Serial.write((uint8_t)(az >> 8)); Serial.write((uint8_t)(az & 0xFF)); #endif **/ // Ara comença el codi de programacio per indicar que quan cau la cara de // l'estrella s'ha d'encendre el led groc, corresponent amb la bola groga. // S'utilitzara el mateix codi però amb diferents limitacions de posició // per les altres cares de la piràmide. //cara 1 delay(1000); Serial.println("part dels leds: "); if ( (0 > ax ) && ( 0 > ay) && ( 0 > az ) ) { //encen led 1 COPITO digitalWrite(ledBlue, HIGH); digitalWrite(ledGreen, LOW); digitalWrite(ledWhite, LOW); Serial.println("blue"); } //cara 2 else if ((0 > ax) && (0 > ay) && (0 < az) ) { //encen led 2 ESTRELLA digitalWrite(ledBlue, LOW); digitalWrite(ledGreen, LOW); digitalWrite(ledWhite, HIGH); Serial.println("yellow"); } //cara 3 else if ( (0 > ax ) && (0 < ay ) && (0 < az ) ) { //encen led 3 MUERDAGO digitalWrite(ledBlue, LOW); digitalWrite(ledGreen, HIGH); digitalWrite(ledWhite, LOW); Serial.println("red"); } //cara 4 else if ( (0 < ax) && (0 > ay ) && ( 0 < az ) ) { //encen led 4 ON/OFF (TOTS ELS LEDS) digitalWrite(ledBlue, HIGH); digitalWrite(ledGreen, HIGH); digitalWrite(ledWhite, HIGH); Serial.println("tots"); } else Serial.println("fail"); }
Downloads
Circuit Assembly With LEDs
Una vez realizado todo el código se procede con el montaje del circuito físico. Se añadirán los LEDs y las resistencias al circuito que se tenía hasta el momento.
Cada led tiene dos patas, la corta y la larga. En la corta se conectará la resistencia y junto con esta un jumper de color negro que irá al ground. En la pata larga se conectará directamente un Jumper de color rojo que irá conectado al PIN correspondiente. Los LEDs siguen la siguiente estructura (conexiones de las patas largas):
White Led --> Digital Pin 5
Blue Led --> Digital Pin 6
Green Led --> Digital Pin 7
Once the LEDs are welded, the entire circuit is distributed on different welding plates. The whole circuit is divided into three groups:
- Gyroscope, inside the pyramid.
- Arduino, inside a box right under the tree.
- The LEDs inside the corresponding balls.
Important:
In this step, it is very important not to be confused with the elements that join the LED's legs. If they are connected incorrectly, they can cause a break in the circuit, so that the circuit will not work and the LEDs can be blown out. It is also very important that the LEDs and their jumpers are not in contact with each other, because then there is a fault which causes the automatic failure of the LED and the circuit.
Christmas Balls Prototype
Once the whole physical circuit is assembled and all the code is programmed, the prototype of the model is finally built.
In this case, this demo is made up of a 60cm high Christmas tree and three balls to hang on it. These three balls will contain the LEDs. Each one will have an LED of a color corresponding to the face of the pyramid to be illuminated. The colours are coded as follows:
- Face on/off --> activates all LEDs
- Snowflake face --> only activates the blue LED
- Star face --> only activates the white LED
- Mistletoe face --> only activates the red LED
Apart from the tree with the balls that contain the LEDs, there is the pyramid-shaped activation system that has the gyroscope inside. This pyramid has on each side a drawing that corresponds to the balls and therefore to the LEDs. This pyramid is made of thick, cream-coloured cardboard and internally reinforced with hard cardboard to provide a better resistance to impact. A small hole is made in a corner of the figure, to allow the jumpers that go to the Arduino board located under the Christmas tree to exit.
Connecting All Parts: Code, Circuit and Prototype
Final assembly of the whole project. The Christmas tree with the three balls each containing a different colored LED. Just ahead, you can see the pyramid with the different patterns. Within the boxes below the tree are the several components of the physical circuit.
- Picture 1: side on/off down, so all LEDs light up.
- Picture 2: face with the snowflake facing down, so the blue LED lights up inside the silver ball.
- Picture 3: face with the star facing down, the white LED lights up inside the gold ball.
- Picture 4: mistletoe face down, the green LED inside the red ball lights up.
The next two pictures are on/off side down, with all the LEDs on and from different angles.