Go Down

Topic: Interfacing accelerometer and Processing (Read 3401 times) previous topic - next topic

Eddiedk

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  :)) - 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: [Select]
#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: [Select]
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...  :(

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


AWOL

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?
"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.

Eddiedk

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...  XD   

Eddiedk

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!!

Brijesh

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". :-)

Angus1

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: [Select]
myPort = new Serial(this, Serial.list()[0], baudRate);

to

Code: [Select]
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!

Eddiedk

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:

Eddiedk

-> Angus

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

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:

Angus1

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 :(

djyakuza

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);


Go Up