Skip to content
Arduino + 3-Axis Accelerometer

Arduino + 3-Axis Accelerometer

Updated: 2026-05

This article was written before 2020. It is kept here as an archive — the content is outdated and some links may no longer work.

What Is a 3-Axis Accelerometer?

A 3-axis accelerometer is a sensor capable of measuring acceleration along the X, Y, and Z axes. It is used in mobile phones, game controllers, PC fall detection systems, and robot attitude control. When combined with a geomagnetic sensor, it can function as an electronic compass, and there are various services that integrate it with GPS (Global Positioning System).

The figure below shows the 3-axis accelerometer built into the iPhone (source).


MEMS (The Technology Behind Accelerometers)

Three-axis accelerometers are made possible by a technology known as MEMS (Micro Electro Mechanical Systems). MEMS is a cutting-edge technology that enables the creation of ultra-small mechanical structures and their integration with electronic circuits; this technology has led to the development of a wide variety of sensors and actuators.

The figure below shows a gear smaller than a tick, created using MEMS technology.


Implementation of a 3-Axis Accelerometer

Continuing from the previous lecture notes on “Arduino + CdS,” we will now add the following components.

Components Used

・3-axis accelerometer KXR94-2050 or KXM52-1050

・Jumper wires: 3 red, 3 black, 3 green

Circuit Diagram

Pin 2 is labeled “Power Shut Down” on the KXM52-1050 and “Enable” on the KXR94-2050, but their functions are identical, and both should be connected to Vdd. Connecting it to GND puts the device into standby mode. While switching this pin can save power, in this case, it should always be connected to Vdd.

Pin Configuration for 3-Axis Accelerometer (KXR94-2050 or KXM52-1050)

Installation Diagram

Install the 3-axis accelerometer, paying attention to its orientation.


Visualizing Acceleration with Processgin

The analog values from the accelerometer are sent to Processing via serial communication and visualized as a graph.

Please note that you will be using both Arduino and Processing programs at the same time.

1. Preparing the Arduino Sketch

Create a new sketch, copy and paste the code below, and then save the sketch.

// Visualizing acceleration using Processgin (Arduino side)
// December 2017, nakayasu

int sensorValue[3];
int outputValue[3];
int inByte; // Received data

void setup()
{
  for(int k=0; k < 3; k++){ sensorValue[k] = 0; outputValue[k] = 0; } Serial.begin(9600); establishContact(); // Establish serial communication } void loop() { if (Serial.available() > 0) {
    inByte = Serial.read(); // Read from serial
    sensorValue[0] = analogRead(1); // A1 pin input - Z (pin 8 on KXM52-1050)
    delay(10);
    sensorValue[1] = analogRead(2); // A2 pin input - Y (pin 7 on KXM52-1050)
    delay(10);
    sensorValue[2] = analogRead(3); // A3 pin input - X (pin 6 on KXM52-1050)
    delay(10);
    // Convert sensor values from 10-bit (0–1023) to 8-bit (0–255) for serial communication
    outputValue[0] = map(sensorValue[0], 0, 1023, 0, 255);
    outputValue[1] = map(sensorValue[1], 0, 1023, 0, 255);
    outputValue[2] = map(sensorValue[2], 0, 1023, 0, 255);
    // Send via serial
    Serial.write(outputValue[0]);
    Serial.write(outputValue[1]);
    Serial.write(outputValue[2]);
  }
}

void establishContact() { // Continue sending 'A' until serial communication is established
  while (Serial.available() <= 0) {
    Serial.print('A');
    delay(300);
  }
}

Download Sketch Data

Arduino_5-4_VelocityGraph_Arduino.zip (Currently unavailable)

② Uploading the Arduino Sketch

Compile and upload the sketch. Serial communication does not start immediately after the program is uploaded to the Arduino. Serial communication begins only after you launch Processing and the initial data exchange between the sender and receiver is complete.

3. Preparing the Processing sketch

Create a blank sketch, copy and paste the code below, and then save the sketch.

// Visualizing acceleration in Processing (Processing side)
// December 2017, nakayasu

import processing.serial.*; // Load the serial library
Serial myPort;
int[] serialInArray = new int[3];
int serialCount = 0;
int[] xvals;
int[] yvals;
int[] zvals;
int a0 = -1000;
int a1 = -1000;
int a2 = -1000;
boolean firstContact = false;

void setup()
{
  size(600, 400);
  xvals = new int[width];
  yvals = new int[width];
  zvals = new int[width];
  for(int i=1; i < width; i++) {
    xvals[i] = -300;
    yvals[i] = -200;
    zvals[i] = -200;
  }
  printArray(Serial.list()); // Display serial device names in the console
  String portName = Serial.list()[3]; // Serial device number
  myPort = new Serial(this, portName, 9600);
}

void draw()
{
  background(0);
  stroke(60);
  line(0, height/6, width, height/6);
  line(0, 3*height/6, width, 3*height/6);
  line(0, 5*height/6, width, 5*height/6);

  for(int i=1; i < width; i++) {
    xvals[i-1] = xvals[i];
    yvals[i-1] = yvals[i];
    zvals[i-1] = zvals[i];
  }
  // Add the new values to the end of the array
  xvals[width-1] = a2; //X A3 to pin 6 on KXM52-1050
  yvals[width-1] = a1; //Y A2 to pin 7 on KXM52-1050
  zvals[width-1] = a0; //Z A1 to pin 8 on KXM52-1050

  for(int i=1; i < width; i++) { stroke(0, 180, 255); point(i, xvals[i] - 58); stroke(255, 20, 0); point(i, yvals[i] + 73); stroke(0, 255, 0); point(i, zvals[i]+142); } fill(0, 180,255); text("X: " + a2, 10, 15); fill(255, 20, 0); text("Y: " + a1, 10, 15 + height/3); fill(0, 255, 0); text("Z: " + a0, 10, 15+2* height/3); } void serialEvent(Serial myPort) { int inByte = myPort.read(); if (firstContact == false) { if (inByte == 'A') { myPort.clear(); // clear the serial port buffer firstContact = true; // you've had first contact from the microcontroller myPort.write('A'); // ask for more } } else { // Add the latest byte from the serial port to array: serialInArray[serialCount] = inByte; serialCount++; if (serialCount > 2 ) {
      a0 = serialInArray[0];
      a1 = serialInArray[1];
      a2 = serialInArray[2];
      myPort.write('A'); // Send a capital A to request new sensor readings:
      serialCount = 0; // Reset serialCount:
    }
  }
}

Download Sketch Data

Arduino_5-4_VelocityGraph_Processing.zip (Currently unavailable)

④Running the Processing Sketch

The voltage values for the X, Y, and Z accelerations are displayed on a graph. By moving the Arduino acrylic board itself up, down, left, and right, you can understand which direction corresponds to each of the X, Y, and Z axes.

Depending on your environment, you may need to change the serial device number (the number in []) on line 15. You can check the serial device number in the Processing console window, as shown in the figure below. The entry that appears as /dev/tty.usbmodem**** is the Arduino.


Shaking the Cube (Acceleration Values)

1. Preparing and Uploading the Arduino Sketch

We will use the same Arduino sketch as in “4. Visualizing Acceleration with Processing.”

2. Preparing the Processing sketch

Create a new sketch, copy and paste the code below, and then save the sketch.

// Shake the cube (acceleration values) (Processing side)
// December 2017, nakayasu

import processing.serial.*; // Load the serial library
Serial myPort;
int[] serialInArray = new int[3];
int serialCount = 0;
int a0, a1, a2;
boolean firstContact = false;

void setup()
{
  size(640, 480, P3D);
  noStroke();
  colorMode(RGB, 1);
  printArray(Serial.list()); // Display serial devices on the console
  String portName = Serial.list()[3]; // Serial device number
  myPort = new Serial(this, portName, 9600);
}

void draw()
{
  background(0);
  translate(width/2+(a2-127)*4, height/2+(a0-190)*4, (a1-127)*-8);
  rotateX(1); rotateZ(1);
  scale(100);
  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();
}

void serialEvent(Serial myPort) {
  int inByte = myPort.read();
  if (firstContact == false) {
    if (inByte == 'A') {
      myPort.clear(); // clear the serial port buffer
      firstContact = true; // you've had first contact from the microcontroller
      myPort.write('A'); // ask for more
    }
  } else {
    // Add the latest byte from the serial port to array:
    serialInArray[serialCount] = inByte;
    serialCount++;
    if (serialCount > 2 ) {
      a0 = serialInArray[0];
      a1 = serialInArray[1];
      a2 = serialInArray[2];
      myPort.write('A'); // Send a capital A to request new sensor readings:
      serialCount = 0; // Reset serialCount:
    }
  }
}

Download Sketch Data

Arduino_5-5_CubeByVelocity_Processing.zip (Currently unavailable)

3. Running the Processing Sketch

Moving the Arduino’s acrylic board up, down, left, and right causes the cube to sway.


Rotating the Cube (Angle Values)

Calculate the tilt angle based on the acceleration values, send it to Processing, and use it as the rotation angle for the cube.

1. Preparing the Arduino Sketch

Create a new sketch, copy and paste the code below, and save the sketch.

// Cube rotation (angle values) (Arduino side)
// December 2017 nakayasu

int sensorValue[3];
int inByte; // Received data

void setup()
{
  for(int k=0; k < 3; k++) sensorValue[k] = 0;
  Serial.begin(9600); establishContact(); // To establish serial communication
}
void loop() {
  if (Serial.available() > 0) {
    inByte = Serial.read(); // Read from serial
    sensorValue[0] = analogRead(1); // A1 pin input - Z (pin 8 on KXM52-1050)
    delay(10);
    sensorValue[1] = analogRead(2); // A2 pin input - Y (pin 7 on KXM52-1050)
    delay(10);
    sensorValue[2] = analogRead(3); // A3 pin input - X (pin 6 on KXM52-1050)
    delay(10);

    // Scale the sensor values to the range of -1 to 1 to obtain the sinθ values
    float xAxisSinTheta = mapInFloat(sensorValue[2], 306, 716, -1, 1);
    float yAxisSinTheta = mapInFloat(sensorValue[1], 306, 716, -1, 1);
    // Limit the values to the range from -1 to 1
    xAxisSinTheta = constrain(xAxisSinTheta, -1, 1);
    yAxisSinTheta = constrain(yAxisSinTheta, -1, 1);
    // Convert the radians of the inverse sine to degrees
    int xAxisTilt = float(asin(xAxisSinTheta) * 180 / PI );
    int yAxisTilt = float(asin(yAxisSinTheta) * 180 / PI );
    // Send via serial
    Serial.write(xAxisTilt);
    Serial.write(yAxisTilt);
  }
}

void establishContact() { // Continue sending 'A' until serial communication is established
  while (Serial.available() <= 0) {
    Serial.print('A');
    delay(300);
  }
}

float mapInFloat(float x, float iMin, float iMax, float oMin, float oMax) {
  return (x - iMin) * (oMax - oMin) / (iMax - iMin) + oMin;
}

Download Sketch Data

Arduino_5-6_CubeByAngle_Arduino.zip (Currently unavailable)

② Uploading the Arduino Sketch

Compile and upload the sketch. Serial communication does not start immediately after the program is uploaded to the Arduino. Serial communication begins only after you launch Processing and the initial data exchange between the sender and receiver is complete.

3. Preparing the Processing sketch

Create a new sketch, copy and paste the code below, and then save the sketch.

// Cube rotation (angle value) (Processing side)
// December 2017 nakayasu

import processing.serial.*; // Load the serial library
Serial myPort;
int[] serialInArray = new int[2];
int serialCount = 0;
int xangle, yangle;
boolean firstContact = false;

void setup()
{
  size(640, 480, P3D);
  noStroke();
  colorMode(RGB, 1);
  printArray(Serial.list()); // Display serial devices on the console
  String portName = Serial.list()[3]; // Serial device number
  myPort = new Serial(this, portName, 9600);
}

void draw()
{
  background(0);
  translate(width/2, height/2, -30);
  rotateX(radians(-30+360*xangle/255));
  rotateZ(radians(-360*yangle/255));
  scale(100);
  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();
}

void serialEvent(Serial myPort) {
  int inByte = myPort.read();
  if (firstContact == false) {
    if (inByte == 'A') {
      myPort.clear(); // clear the serial port buffer
      firstContact = true; // you've had first contact from the microcontroller
      myPort.write('A'); // ask for more
    }
  } else {
    // Add the latest byte from the serial port to array:
    serialInArray[serialCount] = inByte;
    serialCount++;
    if (serialCount > 1 ) {
      xangle = serialInArray[0];
      yangle = serialInArray[1];
      myPort.write('A'); // Send a capital A to request new sensor readings:
      serialCount = 0; // Reset serialCount:
    }
  }
}

Download Sketch Data

Arduino_5-6_CubeByAngle_Processing.zip (Currently unavailable)

④Running the Processing Sketch

Tilting the Arduino’s acrylic board causes the cube to rotate.


Rotating 3D Models

1. Preparing and Uploading the Arduino Sketch

Use the same Arduino sketch as in “6. Rotating the Cube (Angle Values).”

2. Preparing the Processing sketch

Create a blank sketch, copy and paste the code below, and then save the sketch.

// Rotating a 3D model (angle value) (Processing side)
// December 2017 nakayasu

import processing.serial.*; // Load the serial library
Serial myPort;
int[] serialInArray = new int[2];
int serialCount = 0;
int xangle, yangle;
boolean firstContact = false;
PShape obj;

void setup()
{
  size(640, 480, P3D);
  noStroke();
  colorMode(RGB);
  printArray(Serial.list()); // Display serial devices on the console
  String portName = Serial.list()[3]; // Serial device number
  myPort = new Serial(this, portName, 9600);
  obj = loadShape("captain_blender.obj"); // Load 3D object data
}

void draw()
{
  background(0);
  lights();  // Add lights
  translate(width/2, height/2-30, 100); // Adjust position
  rotateX(radians(175+360*xangle/255)); // Rotation angle
  rotateY(radians(-180+360*yangle/255)); // Rotation angle
  shape(obj); // Display 3D data
}

void serialEvent(Serial myPort) {
  int inByte = myPort.read();
  if (firstContact == false) {
    if (inByte == 'A') {
      myPort.clear(); // clear the serial port buffer
      firstContact = true; // you've had first contact from the microcontroller
      myPort.write('A'); // ask for more
    }
  } else {
    // Add the latest byte from the serial port to array:
    serialInArray[serialCount] = inByte;
    serialCount++;
    if (serialCount > 1 ) {
      xangle = serialInArray[0];
      yangle = serialInArray[1];
      myPort.write('A'); // Send a capital A to request new sensor readings:
      serialCount = 0; // Reset serialCount:
    }
  }
}

Download Sketch Data

Arduino_5-7_OBJByAngle_Processing.zip (Currently unavailable)

3. Preparing 3D Model Data

Open the Sketch menu > Open Sketch Folder.

Create a “data” folder and place the following three files (captain_password.zip (currently unavailable), password required) inside it.

・captain_blender.mtl

・captain_blender.obj

・captain.png

④Running the Processing Sketch

Rotating the Arduino’s acrylic board causes the captain to rotate.