Control a 3D Cube with ShakeUp

Get started with motion control by using the ShakeUp's built-in accelerometer

Written By: Cherie Tan

Dash icon
Difficulty
Medium
Steps icon
Steps
12
Motion control is probably one of the most exciting things you could do with an accelerometer, which is a device that can measure the rate of change in velocity of an object. 

In this guide, learn how to create and rotate a 3D Cube in Processing by using the ShakeUp's built-in accelerometer.

Complete this guide to get started with motion control in Processing with the ShakeUp.

Step 1 Overview

Motion control is probably one of the most exciting things you could do with the ShakeUp's built-in accelerometer.
What's an accelerometer? An accelerometer is a device that measures acceleration, the rate of change in velocity of an object. 
Velocity refers to how fast an object is moving in a particular direction.
The built-in accelerometer in the ShakeUp measures the amount of force (acceleration) it is experiencing along the X, Y, and Z axis.
In this guide, we'll show you how to rotate a 3D cube in Processing by using the ShakeUp's built-in accelerometer.

Step 2 Install the Arduino IDE

Already got the Arduino IDE installed and set up for the ShakeUp? Move on to the next step. If not, please follow our guide on how to set up the Arduino IDE for ShakeUp.

Step 3 Install Processing

The next software you'll need is Processing. Processing is a programming language and tool to create visual programs, you can create artwork, prototype interfaces and much more. In this guide, we'll be using it to create pretty graphs. So, head to the Processing Downloads page. 
Select the version for your operating system.

Step 4 Accelerometer example sketch

#include <LittleBird_ICM20689.h>

LittleBird_ICM20689 motion;

void setup() {
        Serial.begin(115200);
        motion.begin();
        motion.init();
        motion.calibrate();
}

void loop() {
        // This print out format will plot on Arduino IDE->Tools->Serial Plotter
        Serial.print(motion.getAccelX());
        Serial.print(",");
        Serial.print(motion.getAccelY());
        Serial.print(",");
        Serial.println(motion.getAccelZ());

        delay(1);
}
Previously, you might have already played with the ShakeUp's built-in accelerometer. In this guide, we'll use the accelerometer measurements to rotate a 3D cube in Processing. First, over in the Arduino IDE, upload the example sketch to the ShakeUp.

Step 5 Processing code (x-axis)

import processing.serial.*;

Serial port;    // Create an object from Serial class
float X;

 
void setup()  { 
  size(640, 360, P3D); 
  noStroke(); 
  colorMode(RGB, 1); 
    // if using Processing 2.1 or later, use Serial.printArray()
  println(Serial.list());
 
   // Open whatever port is the one you're using.
  port = new Serial(this, "/dev/cu.usbmodem1040", 115200);

  // don't generate a serialEvent() unless you get a newline character:
  port.bufferUntil('\n');

} 
 
void draw()  { 
  background(0.5);
  
  pushMatrix(); 
  translate(width/2, height/2, -30); 

  rotateY(-X); 
  
  scale(90);
  beginShape(QUADS);

  fill(0, 1, 1); vertex(-1,  1,  1);
  fill(1, 1, 1); vertex( 1,  1,  1);
  fill(1, 0, 1); vertex( 1, -1,  1);
  fill(0, 0, 1); vertex(-1, -1,  1);

  fill(1, 1, 1); vertex( 1,  1,  1);
  fill(1, 1, 0); vertex( 1,  1, -1);
  fill(1, 0, 0); vertex( 1, -1, -1);
  fill(1, 0, 1); vertex( 1, -1,  1);

  fill(1, 1, 0); vertex( 1,  1, -1);
  fill(0, 1, 0); vertex(-1,  1, -1);
  fill(0, 0, 0); vertex(-1, -1, -1);
  fill(1, 0, 0); vertex( 1, -1, -1);

  fill(0, 1, 0); vertex(-1,  1, -1);
  fill(0, 1, 1); vertex(-1,  1,  1);
  fill(0, 0, 1); vertex(-1, -1,  1);
  fill(0, 0, 0); vertex(-1, -1, -1);

  fill(0, 1, 0); vertex(-1,  1, -1);
  fill(1, 1, 0); vertex( 1,  1, -1);
  fill(1, 1, 1); vertex( 1,  1,  1);
  fill(0, 1, 1); vertex(-1,  1,  1);

  fill(0, 0, 0); vertex(-1, -1, -1);
  fill(1, 0, 0); vertex( 1, -1, -1);
  fill(1, 0, 1); vertex( 1, -1,  1);
  fill(0, 0, 1); vertex(-1, -1,  1);

  endShape();
  
  popMatrix(); 
} 

void serialEvent (Serial port) {
  // get the ASCII string:
  String inString = port.readStringUntil('\n');

  if (inString != null) {
    // trim off any whitespace:
    inString = trim(inString);
    // split the string on the commas and convert the resulting substrings
    // into an array:
    float[] vals = float(split(inString, ","));
    // if the array has at least three elements, you know you got the whole
    // thing.  Put the first value into the X variable
    if (vals.length >= 3) {
      X = vals[0];
    }
  }
}
Next, upload this sketch in Processing. Start the Processing IDE.
Then copy and paste the code into Processing.
If you are using the Mac OS:

To find out the port number for yours, open a terminal window on Mac, then type ls /dev/* 

Look for /dev/tty.*  where * is the port number

Change "/dev/cu.usbmodem1040" to your port number.  

If you are using Windows:

On Windows machines, this would be "COMX", replace X with the number of the COM port that your Arduino is connected to.
Now, click on the 'Run' button on the top left-hand corner in Processing. (If you hover your mouse cursor over the button, it should state 'Run'.

Step 6 3D Cube - Rotating along X-axis

Tilting the ShakeUp along its x-axis will cause the 3D cube to rotate.

Step 7 Processing code (y-axis)

import processing.serial.*;

Serial port;    // Create an object from Serial class
float Y;

 
void setup()  { 
  size(640, 360, P3D); 
  noStroke(); 
  colorMode(RGB, 1); 
    // if using Processing 2.1 or later, use Serial.printArray()
  println(Serial.list());
 
   // Open whatever port is the one you're using.
  port = new Serial(this, "/dev/cu.usbmodem1040", 115200);

  // don't generate a serialEvent() unless you get a newline character:
  port.bufferUntil('\n');

} 
 
void draw()  { 
  background(0.5);
  
  pushMatrix(); 
  translate(width/2, height/2, -30); 

  rotateY(-Y); 
  
  scale(90);
  beginShape(QUADS);

  fill(0, 1, 1); vertex(-1,  1,  1);
  fill(1, 1, 1); vertex( 1,  1,  1);
  fill(1, 0, 1); vertex( 1, -1,  1);
  fill(0, 0, 1); vertex(-1, -1,  1);

  fill(1, 1, 1); vertex( 1,  1,  1);
  fill(1, 1, 0); vertex( 1,  1, -1);
  fill(1, 0, 0); vertex( 1, -1, -1);
  fill(1, 0, 1); vertex( 1, -1,  1);

  fill(1, 1, 0); vertex( 1,  1, -1);
  fill(0, 1, 0); vertex(-1,  1, -1);
  fill(0, 0, 0); vertex(-1, -1, -1);
  fill(1, 0, 0); vertex( 1, -1, -1);

  fill(0, 1, 0); vertex(-1,  1, -1);
  fill(0, 1, 1); vertex(-1,  1,  1);
  fill(0, 0, 1); vertex(-1, -1,  1);
  fill(0, 0, 0); vertex(-1, -1, -1);

  fill(0, 1, 0); vertex(-1,  1, -1);
  fill(1, 1, 0); vertex( 1,  1, -1);
  fill(1, 1, 1); vertex( 1,  1,  1);
  fill(0, 1, 1); vertex(-1,  1,  1);

  fill(0, 0, 0); vertex(-1, -1, -1);
  fill(1, 0, 0); vertex( 1, -1, -1);
  fill(1, 0, 1); vertex( 1, -1,  1);
  fill(0, 0, 1); vertex(-1, -1,  1);

  endShape();
  
  popMatrix(); 
} 

void serialEvent (Serial port) {
  // get the ASCII string:
  String inString = port.readStringUntil('\n');

  if (inString != null) {
    // trim off any whitespace:
    inString = trim(inString);
    // split the string on the commas and convert the resulting substrings
    // into an array:
    float[] vals = float(split(inString, ","));
    // if the array has at least three elements, you know you got the whole
    // thing.  Put the second value into the Y variable
    if (vals.length >= 3) {
      Y = vals[1];
    }
  }
}
Next, run the following code in Processing

Step 8 3D Cube - Rotating along Y-axis

Tilting the ShakeUp along its y-axis will cause the 3D cube to rotate.

Step 9 Processing code (z-axis)

import processing.serial.*;

Serial port;    // Create an object from Serial class
float Z;

 
void setup()  { 
  size(640, 360, P3D); 
  noStroke(); 
  colorMode(RGB, 1); 
    // if using Processing 2.1 or later, use Serial.printArray()
  println(Serial.list());
 
   // Open whatever port is the one you're using.
  port = new Serial(this, "/dev/cu.usbmodem1040", 115200);

  // don't generate a serialEvent() unless you get a newline character:
  port.bufferUntil('\n');

} 
 
void draw()  { 
  background(0.5);
  
  pushMatrix(); 
  translate(width/2, height/2, -30); 

  rotateZ(-Z); 
  
  scale(90);
  beginShape(QUADS);

  fill(0, 1, 1); vertex(-1,  1,  1);
  fill(1, 1, 1); vertex( 1,  1,  1);
  fill(1, 0, 1); vertex( 1, -1,  1);
  fill(0, 0, 1); vertex(-1, -1,  1);

  fill(1, 1, 1); vertex( 1,  1,  1);
  fill(1, 1, 0); vertex( 1,  1, -1);
  fill(1, 0, 0); vertex( 1, -1, -1);
  fill(1, 0, 1); vertex( 1, -1,  1);

  fill(1, 1, 0); vertex( 1,  1, -1);
  fill(0, 1, 0); vertex(-1,  1, -1);
  fill(0, 0, 0); vertex(-1, -1, -1);
  fill(1, 0, 0); vertex( 1, -1, -1);

  fill(0, 1, 0); vertex(-1,  1, -1);
  fill(0, 1, 1); vertex(-1,  1,  1);
  fill(0, 0, 1); vertex(-1, -1,  1);
  fill(0, 0, 0); vertex(-1, -1, -1);

  fill(0, 1, 0); vertex(-1,  1, -1);
  fill(1, 1, 0); vertex( 1,  1, -1);
  fill(1, 1, 1); vertex( 1,  1,  1);
  fill(0, 1, 1); vertex(-1,  1,  1);

  fill(0, 0, 0); vertex(-1, -1, -1);
  fill(1, 0, 0); vertex( 1, -1, -1);
  fill(1, 0, 1); vertex( 1, -1,  1);
  fill(0, 0, 1); vertex(-1, -1,  1);

  endShape();
  
  popMatrix(); 
} 

void serialEvent (Serial port) {
  // get the ASCII string:
  String inString = port.readStringUntil('\n');

  if (inString != null) {
    // trim off any whitespace:
    inString = trim(inString);
    // split the string on the commas and convert the resulting substrings
    // into an array:
    float[] vals = float(split(inString, ","));
    // if the array has at least three elements, you know you got the whole
    // thing.  Put the third value into the Z variable
    if (vals.length >= 3) {
      Z = vals[2];
    }
  }
}
Next, run the following code in Processing.

Step 10 3D Cube - Rotating along Z-axis

Tilting the ShakeUp along its z-axis will cause the 3D cube to rotate.

Step 11 Processing code (2-axises)

import processing.serial.*;

Serial port;    // Create an object from Serial class
float X;
float Y;
 
void setup()  { 
  size(640, 360, P3D); 
  noStroke(); 
  colorMode(RGB, 1); 
    // if using Processing 2.1 or later, use Serial.printArray()
  println(Serial.list());
 
   // Open whatever port is the one you're using.
  port = new Serial(this, "/dev/cu.usbmodem1040", 115200);

  // don't generate a serialEvent() unless you get a newline character:
  port.bufferUntil('\n');

} 
 
void draw()  { 
  background(0.5);
  
  pushMatrix(); 
  translate(width/2, height/2, -30); 
  
  rotateX(-Y); 
  rotateY(-X); 
  
  scale(90);
  beginShape(QUADS);

  fill(0, 1, 1); vertex(-1,  1,  1);
  fill(1, 1, 1); vertex( 1,  1,  1);
  fill(1, 0, 1); vertex( 1, -1,  1);
  fill(0, 0, 1); vertex(-1, -1,  1);

  fill(1, 1, 1); vertex( 1,  1,  1);
  fill(1, 1, 0); vertex( 1,  1, -1);
  fill(1, 0, 0); vertex( 1, -1, -1);
  fill(1, 0, 1); vertex( 1, -1,  1);

  fill(1, 1, 0); vertex( 1,  1, -1);
  fill(0, 1, 0); vertex(-1,  1, -1);
  fill(0, 0, 0); vertex(-1, -1, -1);
  fill(1, 0, 0); vertex( 1, -1, -1);

  fill(0, 1, 0); vertex(-1,  1, -1);
  fill(0, 1, 1); vertex(-1,  1,  1);
  fill(0, 0, 1); vertex(-1, -1,  1);
  fill(0, 0, 0); vertex(-1, -1, -1);

  fill(0, 1, 0); vertex(-1,  1, -1);
  fill(1, 1, 0); vertex( 1,  1, -1);
  fill(1, 1, 1); vertex( 1,  1,  1);
  fill(0, 1, 1); vertex(-1,  1,  1);

  fill(0, 0, 0); vertex(-1, -1, -1);
  fill(1, 0, 0); vertex( 1, -1, -1);
  fill(1, 0, 1); vertex( 1, -1,  1);
  fill(0, 0, 1); vertex(-1, -1,  1);

  endShape();
  
  popMatrix(); 
} 

void serialEvent (Serial port) {
  // get the ASCII string:
  String inString = port.readStringUntil('\n');

  if (inString != null) {
    // trim off any whitespace:
    inString = trim(inString);
    // split the string on the commas and convert the resulting substrings
    // into an array:
    float[] vals = float(split(inString, ","));
    // if the array has at least three elements, you know you got the whole
    // thing.  Put the first value into the X variable and second value into the Y variable
    if (vals.length >= 3) {
      X = vals[0];
      Y = vals[1];
    }
  }
}
Finally,  run the following code in Processing.
Rotate the ShakeUp along the x-axis and watch the 3D cube rotate.
Then rotate the ShakeUp along the y-axis, the 3D cube will rotate along the y-axis.

Step 12 Conclusion

Can you think of other examples where an accelerometer is used?  Some examples include:

A motion-based game controller

As part of a wearable sensor for health and fitness

Controlling a robotic arm