You are on page 1of 4

3/27/2014 3-Axis Accelerometer and Processing | Robot is Happy

https://web.archive.org/web/20120418104603/http://www.robotishappy.com/2010/08/part-1-visualizing-3-axis-accelerometer-readings-in-processing 1/4
Part 1) Visualizing 3-Axis Accelerometer Readings in Processing
by Christopher Hazlett
It's been a while since I've had the chance to do anything vaguely electronic. Sure, I've painted rooms in my house,
installed ceiling fans, added insulation to my attic, but that's a far cry from programming in Wiring or Processing. So,
thankfully, after getting my new workspace all put together, I got the chance to play with some of the parts I've had waiting
in a few SparkFun boxes.
So I started playing around with a 3-Axis Accelerometer in the hopes of dreaming up some project or other. So I hooked it
up to my Arduino and my Arduino to my computer and wrote a little Processing code to graph it all into pretty colors. As
with all of my projects, the first step for me is understanding and since I didn't have much experience with Accelerometers
a little crash course was in order. As it turns out, it's a fairly simple sensor to use (or collection of 3 sensors: x, y, z, I
should say). Simply plug the VCC connector into the Arduino 3V pin (not the 5V pin. The ADXL3305 chip is only rated to
3.3V), the ground into ground and the x, y, and z pins into 0,1,2 analog pins. The code for the Arduino is simple:
The Arduino Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#define X_AXIS 0
#define Y_AXIS 1
#define Z_AXIS 2

void setup() {
Serial.begin(9600);
}

void loop() {
int x = analogRead(X_AXIS);
int y = analogRead(Y_AXIS);
int z = analogRead(Z_AXIS);

Serial.print(x);
Serial.print('|');
Serial.print(y);
Serial.print(':');
Serial.println(z);
}
It takes the readings in and outputs them into a formatted string '[x]|[y]:[z]'. That's it. This is just for outputting data right
now, so nothing special. It gets more interesting when we look at the processing.
The Processing Code in Action
The code that makes the sweet, sweet video above isn't necessarily complicated, but there may be a few things you haven't

Post Categories
Arduino
Beacon Locating Robot
Light-Seeking Robot
Message Queue Monitor
News
Other People's Robots
Processing
Projects
Radio Control
Stuff I'm Researching
Uncategorized
Recent Machines
Robotic Curtain Not necessarily
effective, but definitely awesome.
Sign Language Translator
Evil Mad Scientist Disects the
Venerable Nixie Tube
Arduino Something New!!
Evil Mad Scientists Release Egg-Bot Kit
Blogroll
Adafruit
Electrical What Schematic Symbols
Evil Mad Scientist
Flight 404
Hack A Day
Make
NYC Resistor
Parallax
Pololu
Sparkfun
Tags
Accelerometer Arduino
ethernet shield Infrared international
robot expo irex japan japanese
girls library message queue News
Physical Computing pick and place POV
Processing service robot
shield tokyo toy Tutorial video
Workbench
ROBOT IS HAPPY
CREATING OUR ROBOT OVERLORDS ONE DAY AT A TIME
Subscribe via RSS
OTHER PEOPLE'S ROBOTS PROCESSING PROJECTS STUFF I'M RESEARCHING
AUG/10
http://www.robotishappy.com/2010/08/part-1-visualizing-3-axis-accelerometer-readings-in-processing Go
FEB APR DEC
18
2011 2012 2013
13 captures
24 Nov 10 - 20 Dec 12
Close
Help
3/27/2014 3-Axis Accelerometer and Processing | Robot is Happy
https://web.archive.org/web/20120418104603/http://www.robotishappy.com/2010/08/part-1-visualizing-3-axis-accelerometer-readings-in-processing 2/4
The code that makes the sweet, sweet video above isn't necessarily complicated, but there may be a few things you haven't
used in Processing before.
map(value, low1, high1, low2, high2) - converts a value from one range into a corresponding value into another
range.
norm(value, low, high) - converts a value into a value from 0.0 to 1.0 based on the supplied range.
pushMatrix() / popMatrix() - the pushMatrix() and popMatrix() methods allow you to apply rotation, translation, and
other methods to a specific style. By issuing the pushMatrix() then calling the translate(), and rotateX, rotateY
methods, you can then call popMatrix so those methods don't affect other elements being rendered by Processing.
The Processing Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import processing.serial.*;
import processing.opengl.*;
Serial myPort;
int baudRate = 9600;
int lf = 10;

PFont font;
int[] xAxis;
int[] yAxis;
int[] zAxis;

int currentX = 0;
int currentY = 0;
int currentZ = 0;
//these value were determined by taking readings from a resting position
int oneGSensorValue = 400;
float oneGMillivolt = oneGSensorValue * 4.9;

int totalReadings = 400;
int readingPos = 0; // the reading position in the array

void setup(){
smooth();
size(600, 300, OPENGL);

font = createFont(PFont.list()[270], 24);
smallFont();

xAxis = new int[totalReadings];
yAxis = new int[totalReadings];
zAxis = new int[totalReadings];

for (int i=0; i < totalReadings; i++){
xAxis[i] = oneGSensorValue;
yAxis[i] = oneGSensorValue;
zAxis[i] = oneGSensorValue;
}

myPort = new Serial(this, Serial.list()[0], baudRate);
myPort.bufferUntil(lf);

noLoop();
}

void serialEvent(Serial p){
String inString;

try{
inString = (myPort.readString());
currentX = xValue(inString);
currentY = yValue(inString);
currentZ = zValue(inString);
xAxis = insertValueIntoArray(xAxis, currentX, readingPos, totalReadings);
yAxis = insertValueIntoArray(yAxis, currentY, readingPos, totalReadings);
zAxis = insertValueIntoArray(zAxis, currentZ, readingPos, totalReadings);
readingPos = readingPos + 1; // increment the array position
}catch(Exception e){
println(e);
}
redraw();
}

void draw()
{
background(#FEFFFC);
drawGraph(xAxis, 100, color(#519050), "X - Axis");
drawGraph(yAxis, 200, color(#708CDE), "Y - Axis");
drawGraph(zAxis, 300, color(#D38031), "Z - Axis");
draw3d(currentX, currentY, currentZ);
}

void drawGraph(int[] arrToDraw, int yPos, color graphColor, String name){
int arrLength = arrToDraw.length;
stroke(graphColor);
for (int x=0; x<arrLength - 1; x++) {
float normalizedLine = norm(arrToDraw[x], 0.0, 700.0);
float lineHeight = map(normalizedLine, 0.0, 1.0, 0.00, 85.0);
line(x, yPos, x, yPos - int(lineHeight));


3/27/2014 3-Axis Accelerometer and Processing | Robot is Happy
https://web.archive.org/web/20120418104603/http://www.robotishappy.com/2010/08/part-1-visualizing-3-axis-accelerometer-readings-in-processing 3/4
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167

}
pushStyle();
smallFont();
stroke(#FFFFFF);
fill(#FFFFFF);
String gString = nfc(gFromSensorValue(arrToDraw[arrLength - 2]), 2);
text(name + " : " + gString + " Gs", 10, yPos - 10);
popStyle();
}

void draw3d(int currentX, int currentY, int currentZ){
float normalizedX = norm(currentX, 0.0, 700.0);
float normalizedY = norm(currentY, 0.0, 700.0);
float normalizedZ = norm(currentZ, 0.0, 700.0);
float finalZ = map(normalizedZ, 0.0, 1.0, 300.00, 0.0);
float finalY = map(normalizedY, 0.0, 1.0, -3.5, 3.5);
float finalX = map(normalizedX, 0.0, 1.0, -3.5, 3.5);

pushMatrix();
ambientLight(102, 102, 102);
lightSpecular(204, 204, 204);
directionalLight(102, 102, 102, -1, -1, -1);
shininess(1.0);
translate(500, finalZ);
rotateY(finalY + 1.0);
rotateZ(finalX);
fill(#E2E8D5);
noStroke();
fill(#B76F6F);
float heightWidth = finalX * 1.8;
box(65, 65, 50);
popMatrix();
}

int xValue(String inString){
int pipeIndex = inString.indexOf('|');
return int(inString.substring(0,pipeIndex));
}

int yValue(String inString){
int pipeIndex = inString.indexOf('|');
int colonIndex = inString.indexOf(':');
return int(inString.substring(pipeIndex+1, colonIndex));

}

int zValue(String inString){
int colonIndex = inString.indexOf(':');
return int(inString.substring(colonIndex + 1, inString.length() - 2));
}

/*
This little method creates a running tally of all the incoming sensor readings
and then, when it reaches the end of the array, it pops the first one of the beginning
and inserts a new value in at the end...thus keeping a running tally of the last 400
readings (it can be for any length array, that's just what it's set to for this project).
This works a lot like an RRD graph where my inspiration came from.
*/
int[] insertValueIntoArray(int[] targetArray, int val, int pos, int maxLength){
if(pos > (maxLength-1)){
// if the pos == maxSize, shift the array to retain the original value
int[] returnArray = subset(targetArray, 1, maxLength-1);
returnArray = expand(returnArray, maxLength);
returnArray[maxLength-2] = val;
return returnArray;
}else{
targetArray[pos] = val;
return targetArray;
}
}

/*
This conversion will vary from project to project
and if you're project is relying on battery power
the reading may need to be adjusted to give you true
one G as your battery power decreases. All of this is due to
the output of the X,Y, and Z sensors and their coorelation to the incoming voltage at VCC
Check out the specs for the ADXL335 (part of the break out board from Sparkfun.com) here:
http://www.analog.com/en/sensors/inertial-sensors/adxl335/products/product.html
*/
float gFromSensorValue(int sensorValue){
//convert analog value into millivolts
float mvValue = sensorValue * 4.9;
return mvValue/oneGMillivolt;
}

void smallFont(){ textFont(font, 24); }
void mediumFont(){ textFont(font, 30); }
void largeFont(){ textFont(font, 40); }
This is just the first step of a larger project to create a DIY radio control using an xBee and this 3-axis accelerometer.

3/27/2014 3-Axis Accelerometer and Processing | Robot is Happy
https://web.archive.org/web/20120418104603/http://www.robotishappy.com/2010/08/part-1-visualizing-3-axis-accelerometer-readings-in-processing 4/4
About Christopher Hazlett
Chris has been programming for almost a decade, and thinks programming is even more fun when
it makes a robot do stuff...even if that stuff is just a bunch of blinking lights. Chris's GIT repos:
http://github.com/chazlett.
Tagged as: Accelerometer, Arduino, Processing Leave a comment
Richard
February 11th, 2011 - 14:02
Thanks for the code and video got it working!
Cheers!
Dan
October 17th, 2011 - 12:46
Hmm cant seem to get the code to work.
Is the code specific for running on a MAC or will it work for Windows XP as well?
Dan
October 19th, 2011 - 12:09
Got it working! I finally realized I need to tell it what COM port to use inside the [].
Anyway thanks for the code. This is a great learning resource!
Stuff Im Researching for a Project Finally, Back to Work
This is just the first step of a larger project to create a DIY radio control using an xBee and this 3-axis accelerometer.
Happy Coding.
- Chris
Tweet
Share
Leave a comment
Name (required)
Mail (will not be published) (required)
Website
Submit
Powered by WP Hashcash
Copyright 2012 Robot is Happy Powered by WordPress
Lightword Theme by Andrei Luca
Podcast powered by podPress (v8.8 / v8.8.5.3)
Enjoy this article?
Consider subscribing to our rss feed!
Comments (3) Trackbacks (0) ( subscribe to comments on this post )
Go to top

You might also like