Christmas Balls

by Raquel-Roser in Living > Christmas

817 Views, 1 Favorites, 0 Comments

Christmas Balls

IMG_1805.JPG

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

Arduino_uno.jpg
mpu6050.jpg
45040-dscn0624__20998_zoom.jpg
Bright-White-LED-5mm-600x600.JPG
IMG_5891.JPG
IMG_5875.JPG
classic-christmas-tree-60-cm.jpg

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

dest-arduino.jpg
Captura de pantalla 2017-12-03 a las 19.49.26.png

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);

Giroscope Code by Arduino Web Page

Circuit Assembly With Gyroscope

mpu6050.jpg
GIRO.png

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

Captura de pantalla 2017-12-07 a las 11.54.24.png

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

COMPLERT.jpg
IMG_6003.JPG

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

IMG_5938.JPG
IMG_5905.JPG
IMG_5936.JPG
IMG_5937.JPG
IMG_1787.JPG

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

IMG_1805.JPG
IMG_1806.JPG
IMG_1808.JPG
IMG_1807.JPG
IMG_1810.JPG
IMG_1812.JPG

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.