Skip to content

Final Project

Along with my partner Roaya, we present to you our final project for the Fab Lab Academy.

VISIONS ILLUMINATED

Concept

“Visions Illuminated” is an innovative, interactive light box that brings the world of Coraline to life in an immersive experience. The lightbox acts essentially as a lamp that casts shadows through a meticulously crafted illustration that are layered to complete a scene showcasing pivotal moments from the film.

The wooden exterior of the box belies the intricate layers within. From Coraline’s initial encounters with the Other Mother to her daring escapes and ultimate triumphs, each scene is rendered in paper to create a rich and immersive atmosphere.

What sets “Visions Illuminated” apart from a regular lightbox is its responsiveness to user input. With a simple motion gesture, the lights can be turned on and the box starts to rotate. Each side of the box demonstrate different scenes, each one a window into a different moment from the movie that can be rotated through, allowing the viewer to become an integral part of the narrative. It’s as if you are stepping into the world of Coraline itself, influencing the action as it unfolds before your eyes.

Behind the Scenes

Read ahead to find out how we achieved this!

Brainstorming

We started by brainstorming for a final project idea that combined both fabrication and programming to create something awesome. As movie enthusiasts, we formed an idea by gathering concepts and inspirations in one file.

This helped us form a clearer idea on what to build for the final project, what materials we might need, and what electronics will be used

How it works

The magic of “Visions Illuminated” lies in its interactive features, which bring the illustrations to life. Here’s a brief overview of how it works:

  1. LED Lighting: The light box is equipped with a series of LED lights that illuminate the illustrations from within. These lights are carefully calibrated to provide an and inviting glow. The colors are curated to represent the aura of the movie.

  2. Motion Sensors: The light box features a motion sensor that detect the swiping of your hand through the front control panel. when doing aspecific gesture , the sensor triggers a response to turn the light on and rotate the box

  3. Arduino Microcontroller: The heart of the light box is an Arduino microcontroller, which is programmed to respond to motion gestures. It processes the sensor data and controls the LED lights and the rotary.

  4. Rotary Mechanism: The box is mounted on a rotary mechanism that allows them to be rotated through different scenes to showcase the diffetent layers of illustrations. This is achieved through a combination of motors and gears, which are controlled by the Arduino microcontroller.

Materials used

Qty Description
2 MDF boards
4 1.2V batteries
1 Adafruit Sense MC
4 LED Strip lights
30 180gsm paper sheets
1 PLA filament
1 Foam Board
1 Step motor 28byj-48

Creating the Scenes

After deciding on the scenes we wanted to display, we went ahead and produced 2d drawings of them using Autocad.

These would be the focal point of the project. Roaya diligently traced each scene going over screenshots from the movie using the lines and arcs tools

To make sure each layer is up to our standards, we laid them over each other to visualize the final scene output

The next thing we did is test on several materials and paper density to see which ones are see through enough to show the back layers but not too transparent that it won’t cast a shadow when lit upon. We used the laser cutter to achieve a clean cut.

By testing, we chose the most appropriate paper that will work for our project which is the 180gsm paper and started producing them using the laser cutter.

We can edit the file on the laser cutter software itself and set specific speed and power appropriate for the material

The process of exporting the scenes to RDWorks and laser cut them

The box

Before modelling the box along with the frame and its base, we sketched out our ideas

Then we went ahead and created a draft model to understand how we’re going to build it

This was necessary to realize the parts we need to make it work, what material we’re going to need and how the mechanisms will come together.

We then built a prototype using regular cardboard before moving on to the next steps.

This made us realize that there was no need for a cover since it made the whole project bigger than necessary and would only be used for instances of storage. We used this prototype to ideate the parts we need to make it a working project

With the help of Eng. Ghassan, we were able to envision it in a more technical context. So we worked on a more accurate model together.

After few attempts, we came up with the full model including the joints that will fix together as well as the base that will hold the electronics and hide the wires.

Once all the parts are ready, we laser cut them on 2.5mm MDF board.

We gathered all the parts ready for assembly

Assembly

We assembled the box using joints and super glue where necessary

The Core

The core of the project includes the LED lighting, the programmed microcontroller (the heart) and the ball bearing mechanism for the rotation

The tower is where the lights revolve around and also serves as the center point of the project where the gears go over to ensure its stability.

We made sure the core is big enough to fit in the all the moving mechanisms, electronics and wires.

In order to aid the stepper motor for a seamless rotation, we 3D printed gears that are bind to the motor and the tube in which the

This is how it looks like from the top. It’s mounted on the mdf board using screws to ensure it’s secure.

Since the base contains the necessary elements that make the lightbox work, the box that go over it is the rotating piece. To make it rotate around the core, we used a ball bearing mechanism which worked very well to achieve the movement we had in mind.

Assembly

3d printed the ball bearing pieces

Because there were too many wires, we arranged them in a neater way and so that everything stays intact

As for the front panel, we modified it to have a switch to turn off the electronics when not in use. To also have a more put together front panel that includes the hole for the sensor and the switch, 3D printing it was more appropriate. It also fit better than the laser cut one.

Here are the list of commands:

Gesture Feature
switch on turns on the electronics
swipe up turns the first light color on
swipe right changes light color
swipe down changes to anotherlight color
swipe left starts rotation
switch off turns off the electronics

The combined code we used for the lighting, rotation, and motion sensor:

//====================================================================
//  LIBRARIES
//====================================================================
//  GUESTURE SENSOR LIBRARY
//--------------------------------------------------------------------

  #include    <Adafruit_APDS9960.h>
  Adafruit_APDS9960 apds;

//--------------------------------------------------------------------
//  NEO PIXEL
//--------------------------------------------------------------------

  #include    <Adafruit_NeoPixel.h>
  #define     PIN           13
  #define     NUM_PIXELS    48
  Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_PIXELS, PIN, NEO_GRB + NEO_KHZ800);

//--------------------------------------------------------------------
//  STEPPER MOTOR THINGS
//--------------------------------------------------------------------

  #include    <Stepper.h>
  bool        stepper_ena         = false;
  const int   stepsPerRevolution  = 4056;
  Stepper     myStepper           = Stepper(stepsPerRevolution, 6, 10, 12, 9);

//====================================================================
//  SETUP
//====================================================================

  void setup() {
    Serial.begin(115200);     // Serial Communication BAUD Rate
    neopixel_start();         // Start Neo Pixel
    gesture_sensor_start();   // Start Guesture
    stepper_start();          // Starting Stepper Motor Function
  }

//====================================================================
//  MAIN PROGRAM
//====================================================================

  void loop() {

    // Read A Gesture From The Device
    uint8_t gesture = apds.readGesture();

    // Gesture Detect Direction Of Movment
    if(gesture == APDS9960_DOWN) {
      gesture_read_down();
    } else if(gesture == APDS9960_UP) {
      gesture_read_up();
    } else if(gesture == APDS9960_LEFT) {
      gesture_read_left();
    } else if(gesture == APDS9960_RIGHT) { 
      gesture_read_right();
    }

    // Move Motor If Its enabled
    stepper_move();

  }

//====================================================================
//  END
//====================================================================
//====================================================================
//  GESTURE FUNCTIONS
//====================================================================
//  Statup The Sensor
//--------------------------------------------------------------------

  void gesture_sensor_start() {

    if(!apds.begin()) {
      Serial.println("failed to initialize device! Please check your wiring.");
    } 

    else {
      Serial.println("Device initialized!");
    }

    //gesture mode will be entered once proximity mode senses something close
    apds.enableProximity(true);
    apds.enableGesture(true);

  }

//--------------------------------------------------------------------
//  Function Of UP Direction
//--------------------------------------------------------------------

  void gesture_read_up() {
    Serial.println("up");
    neopixel_set_color(255, 0, 0, 255);
  }

//--------------------------------------------------------------------
//  Function Of DOWN Direction
//--------------------------------------------------------------------

  void gesture_read_down() {
    Serial.println("down");
    neopixel_set_color(0, 255, 0, 255);
  }

//--------------------------------------------------------------------
//  Function Of LEFT Direction
//--------------------------------------------------------------------

  void gesture_read_left() {
    Serial.println("left");
    stepper_ena = false;
    neopixel_set_color(0, 0, 255, 255);
  }

//--------------------------------------------------------------------
//  Function Of RIGHT Direction
//--------------------------------------------------------------------

  void gesture_read_right() {
    Serial.println("right");
    stepper_ena = true;
    neopixel_set_color(255, 0, 255, 255);
  }

//====================================================================
//  NEOPIXEL FUNCTIONS
//====================================================================

  void neopixel_start() {
    strip.begin();
    strip.clear();
    strip.show();
  }

//--------------------------------------------------------------------
//  Function Of RIGHT Direction
//--------------------------------------------------------------------

  void neopixel_set_color(uint8_t r, uint8_t g, uint8_t b, uint8_t intensity) {

    strip.setBrightness(intensity);

    for (int i=0; i<NUM_PIXELS; i++) {
      strip.setPixelColor(i, r, g, b);
    }

    strip.show();

  }

//====================================================================
//  STEPPER MOTOR FUNCTIONS
//====================================================================

  void stepper_start() {
    myStepper.setSpeed(5);
  }

//--------------------------------------------------------------------
//  Function Of RIGHT Direction
//--------------------------------------------------------------------

  void stepper_move() {
    if(stepper_ena == true) {
      myStepper.step(stepsPerRevolution);
    }
  }

//====================================================================
//  END
//====================================================================
  // Pin Definitions
  #define   _stepper_pin1   6
  #define   _stepper_pin1   10
  #define   _stepper_pin1   12
  #define   _stepper_pin1   9

  // Creating Sequance Bank
  uint8_t   sequance[4][4];

  // Setting Up Sequance Bank
  sequance[0][0]  = 1;  sequance[0][1]  = 0;  sequance[0][2]  = 1;  sequance[0][3]  = 0;
  sequance[1][0]  = 0;  sequance[1][1]  = 1;  sequance[1][2]  = 1;  sequance[1][3]  = 0;
  sequance[2][0]  = 0;  sequance[2][1]  = 1;  sequance[2][2]  = 0;  sequance[2][3]  = 1;
  sequance[3][0]  = 1;  sequance[3][1]  = 0;  sequance[3][2]  = 0;  sequance[3][3]  = 1;

  // To Count Up
  uint8_t seqCounter  = 0;

  // Interval
  const unsigned long interval = 60L * 1000L * 1000L / 4056 / 5;

Acknowlegement

We would like to extend our sincerest gratitude to the instructors at Fab Lab Academy (Duaa, Noor, Haitham, A.Ghafoor)for their guidance, mentorship, and support throughout this project. Their expertise and enthusiasm have been invaluable in helping us bring ‘Visions Illuminated’ to life.

From sharing valuable knowledge on electronics and programming to providing feedback and encouragement along the way, your instruction has been instrumental in helping us develop our skills and creative vision. We are grateful for the opportunity to learn from such a talented and dedicated team of educators. A special thank you goes to Eng. Ghassan Yusuf for helping with the digital modelling all the way to the fabrication. He has helped us in many selfless ways during the final project to make sure we produce the project we had in our head exactly, if not better.


Last update: July 20, 2024