Pages: [1]   Go Down
Author Topic: Interfacing accelerometer and Processing  (Read 2442 times)
0 Members and 1 Guest are viewing this topic.
Denmark
Offline Offline
Newbie
*
Karma: 0
Posts: 10
Open hardware and software rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello.

I have a problem interfacing an accelerometer and Processing, using some code i found on the net...

I have no clue how to use Processing - other than the IDE is very similar to Arduino IDE. I would like to show a working accelerometer to a class, i'm attending to (and to demonstrate Arduino's to the class - so that others maybe get some interest in these small marvels  smiley) - and i have found some code on the net, but does'nt have a clue how to get Processing to work.

It is taken from here... http://www.robotishappy.com/2010/08/part-1-visualizing-3-axis-accelerometer-readings-in-processing/ and the code is here...

Arduino code:

Code:
#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);
}


And the Processing code:

Code:
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));
 
  }
  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); }

But i can't seem to get the Processing code to work. The Arduino code is very simple, and it works when i try it in serial monitor. What am i missing here??? I can't seem to get it to work, as if there were no connection between the Arduino and Processing...  smiley-sad

If only i could get it to work, then i could start adjusting the details in the program later....

Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 240
Posts: 24454
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
But i can't seem to get the Processing code to work.
Presumably, "work" has some specific meaning to you in this context.
Would you care to share that definition, and how it differs from what you actually observe?
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Denmark
Offline Offline
Newbie
*
Karma: 0
Posts: 10
Open hardware and software rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oh, sorry... i forgot that!!

it seems like Processing does'nt get any data from the Arduino, and i suspect it to be somewhat of a portconnection-error or something like that. Actually when the Arduino (Uno) runs the sketch and the Processing-sketch is running, nothing happens in Processing. Again - i'm not a shark, when trying to debug in Processing, but maybe it could be a port assignment of some sort???

I've checked the Arduino-sketch in the serial monitor, and that works fine (it should be - it's very basic). But i can't seem to see what makes the Processing sketch tick (or rather NOT tick)... The accelerometer is an ADXL-335, as proposed in the sketches.

I'm only trying to find a processing sketch to show, how an accelerometer works in real life, and to show something meaningfull on a projector - other than just numbers in a serial monitor...  smiley-lol     
Logged

Denmark
Offline Offline
Newbie
*
Karma: 0
Posts: 10
Open hardware and software rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've sat down for a few hours, trying to understand the Processing sketch...

In my understanding, the Processing sketch is missing a...

void setup(){
     port = new Serial(this, "COM8 (for example)", 9600)


(i'm working in Windows XP - hence the com-port)

... or am i still far away from an answer??? I can't seem to understand how the Processing sketch is fetching its data!!
Logged

USA
Offline Offline
Newbie
*
Karma: 1
Posts: 30
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello,

If all you want to do is show accelerometer values on a computer screen then you can use SimPlot. I wrote it specifically for such uses. Didn't want to muck around with Processing when all I wanted to see were some values on the screen.   Below is the relevant thread
http://arduino.cc/forum/index.php/topic,58911.0.html

Let me know if it "works". :-)
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I joined the forum to ask pretty  much the same question, if your serial port is COM4, you'll probably need to change where it says

 
Code:
myPort = new Serial(this, Serial.list()[0], baudRate);

to

 
Code:
myPort = new Serial(this, Serial.list()[1], baudRate);

The bit in the [] is the port number, on my machine, COM4 is port 1, COM3 is 0, yours might be different i guess, but if you fiddle with that number you should get it going soon enough!
Logged

Denmark
Offline Offline
Newbie
*
Karma: 0
Posts: 10
Open hardware and software rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks to you both for the answers - i'll try both solutions in the morning (it's bedtime here now, on the other side of the planet  smiley-sleep)


-> Angus

Explains a lot... so when i was trying to locate the port in the sketch, i was looking the right place - but did not understand what i was looking at. It could be the answer, but i must see that in the morning. And next you are going to tell me, that different machines have different portnumbers assigned to different com-ports - right!!

Well - looks like i have to use my own machine to presentation... otherwise i would have to debug again on the teachers machine, in front of the class - when i'm going to present this...  smiley-roll
Logged

Denmark
Offline Offline
Newbie
*
Karma: 0
Posts: 10
Open hardware and software rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

-> Angus

Unfortunatly your reply did'nt work... i get a "Array overflow"-error, and a java-window, which is a B***** to be closed...  smiley-cry

So... i'm back to basic again!! I will try Brijesh solution soon!! I just need somekind of graphics to show, other than just numbers on a serial monitor - which might bore people under the presentation.  smiley-sleep
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hmmm, odd, try a few different numbers i guess, it might be different for each computer, i never got anything like that, but if theres something using another port, it might send in too much data or something? There is some sort of list ports function in processing, but can't remember where i saw it smiley-sad
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

WHO CAN HELP ME, DO NOT UNDERSTAND THAT THIS CODE

float normalizedX = norm(currentX, 0.0, 700.0);   //that is 700?
  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);   //that is 300?
  float finalY = map(normalizedY, 0.0, 1.0, -3.5, 3.5);     //that is 3.5 and -3.5?
  float finalX = map(normalizedX, 0.0, 1.0, -3.5, 3.5);

Logged

Pages: [1]   Go Up
Jump to: