Accelerometer readout to degrees in Processing

I wasn’t sure if I should post this in the Processing section or here, but it is a programming question so I decided here was more appropriate.

Im using this Processing code to visualize accelerometer data. Ideally, I’d like it to output the information in degrees like a protractor. What do I need to do?

/*
THIS PROGRAM WORKS WITH ACCEL DEMO ARDUINO CODE
by James Grantham, 2014
*/


import processing.serial.*;
PFont font;

Serial port;     

float inc = 1.0;
    PFont f;


float xvalue;      // holds x value from arduino
float yvalue;      // holds y value from arduino
float zvalue;      // holds z value from arduino

float xpos;      // holds current goals seeking x position
float ypos;      // holds current goals seeking y position
float zpos;      // holds current goals seeking z position


int[] RawY;      // HOLDS HEARTBEAT WAVEFORM DATA BEFORE SCALING
int[] ScaledY;   // USED TO POSITION SCALED HEARTBEAT WAVEFORM
int[] rate;      // USED TO POSITION BPM DATA WAVEFORM
float zoom;      // USED WHEN SCALING PULSE WAVEFORM TO PULSE WINDOW
float offset;    // USED WHEN SCALING PULSE WAVEFORM TO PULSE WINDOW
color eggshell = color(255, 253, 248);
int heart = 0;   // This variable times the heart image 'pulse' on screen
//  THESE VARIABLES DETERMINE THE SIZE OF THE DATA WINDOWS
int PulseWindowWidth = 490;
int PulseWindowHeight = 512; 
int BPMWindowWidth = 180;
int BPMWindowHeight = 340;
boolean beat = false;    // set when a heart beat is detected, then cleared when the BPM graph is advanced


void setup() {
  size(1000, 1000,OPENGL);  // Stage size
  PFont.list();
  f = createFont("Courier",36,true);

  frameRate(100);  
  rectMode(CENTER);
  ellipseMode(CENTER);  
   
   xpos = 00.0;
   ypos = 0.0;
   zpos = 0.0;
   
// GO FIND THE ARDUINO
  println(Serial.list());    // print a list of available serial ports
  // choose the number between the [] that is connected to the Arduino
  String portName = "/dev/tty.usbmodem1411";
  port = new Serial(this, portName, 115200);  // make sure Arduino is talking serial at this baud rate
  port.clear();            // flush buffer
  port.bufferUntil('\n');  // set buffer full flag on receipt of carriage return
}
  
void draw() {
  
  background(0);
  lights();
  inc+=0.01;

  pushMatrix();
  fill(0,100,0);
  translate(width/2,height/2);
  
  float xrad = map(xvalue,-1,1,-PI/2.0,PI/2.0);
  
  if(xrad > (xpos + 0.05)) {
     xpos+=0.01; 
  } else if (xrad < (xpos - 0.05)) {
     xpos-=0.01 ;
  }
  
  rotateX(xpos); 
  
  float yrad = map(yvalue,1,-1,-PI/2.0,PI/2.0);
  
    if(yrad > (ypos+ 0.05)) {
     ypos+=0.01; 
  } else if (yrad < (ypos - 0.05)) {
     ypos-=0.01; 
  }
  
  rotateZ(ypos);
  
  
  box(width/2, height/48, width/2);
  
  popMatrix();

  pushMatrix();
  textFont(f,40);
  fill(110,100,200);
  text("X: ",50,50);
  text(xvalue,130,50);
  
  text("Y: ",50,100);
  text(yvalue,130,100);

  text("Z: ",50,150);
  text(zvalue,130,150);


  popMatrix();

  print("X: ");
  println(xvalue);
  
  print("Y: ");
  println(yvalue);
  
  print("Z: ");
  println(zvalue);
  
}  //end of draw loop

void serialEvent(Serial port){ 
   String inData = port.readStringUntil('\n');
   inData = trim(inData);                 // cut off white space (carriage return)
   
   if (inData.charAt(0) == 'X'){          // leading 'S' for sensor data
     inData = inData.substring(1);        // cut off the leading 'S'
     if (inData.charAt(0) == '-'){        // Chack if the value is negative
       inData = inData.substring(1);      // cut off the leading '-'
       xvalue = (float(inData)) * -1.0;       // cast the remaining xvalue as an int and then make it negative
     } else  {
       xvalue = (float(inData));            // cast the xvalue as an int
     }   
   }
   if (inData.charAt(0) == 'Y'){          // leading 'B' for BPM data
     inData = inData.substring(1);        // cut off the leading 'B'
     if (inData.charAt(0) == '-'){        // Chack if the value is negative
       inData = inData.substring(1);      // cut off the leading '-'
       yvalue = (float(inData)) * -1.0;       // cast the remaining yvalue as an int and then make it negative
     } else  {
       yvalue = (float(inData));            // cast the yvalue as an int
     }   
   }
 if (inData.charAt(0) == 'Z'){            // leading 'Q' means IBI data 
     inData = inData.substring(1);        // cut off the leading 'Q'
     if (inData.charAt(0) == '-'){        // Chack if the value is negative
       inData = inData.substring(1);      // cut off the leading '-'
       zvalue = (float(inData)) * -1.0;       // cast the remaining yvalue as an int and then make it negative
     } else  {
       zvalue = (float(inData));            // cast the yvalue as an int
     }   
   }
}
   if (inData.charAt(0) == 'X'){          // leading 'S' for sensor data

If you are going to have useless comments, you MUST make them accurate.

Ideally, I'd like it to output the information in degrees like a protractor.

Protractors are flat. At least all the ones I've seen are. What kind of data is the mysterious Arduino code sending Processing? Are you integrating the data on the Arduino, so you send three angles? Or, are you sending the measured rate of acceleration, and expecting Processing to integrate the data to determine orientation?

Here is the Arduino code:

/*
>>MMA7361 Demo Serial communication arduino sketch to use with companion Processing Sketch

by James Grantham



*/
#include "Accelerometer.h"

Accelerometer myAccelerometer = Accelerometer();

void setup(){
  

  Serial.begin(115200);             // we agree to talk fast!

   //Connect up the following pins and your power rail 
  //                    SL GS 0G   X  Y  Z    
  myAccelerometer.begin(3, 4, 5, A0, A1, A2);
    
  //calibration performed below
  Serial.println("Please place the Accelerometer on a flat\nLevel surface");
  delay(2000);//Give user 2 seconds to comply
  myAccelerometer.calibrate();
  
}



void loop(){
  delay(0);//delay for readability
  //reads the values of your accelerometer
  myAccelerometer.read();
  
  // This section writes to the serial connection in a format that can be interpreted by the companion processing app
  Serial.print("X");
  Serial.println(myAccelerometer._Xgs);
  Serial.print("Y");
  Serial.println(myAccelerometer._Ygs);
  Serial.print("Z");
  Serial.println(myAccelerometer._Zgs);
}

Its sending the raw accelerometer data to processing which displays a graphic interpretation of the data as well as prints the raw data. I'd like the processing app to display the raw accelerometer data in degrees. For example, if I turn on the Arduino while its laying level and it calibrates as such I would like processing to display X=90 degrees if I were to turn the accelerometer perpendicular to the table in the x-axis.

What you want to do can be done with an accelerometer, but an accelerometer is not meant to really do that.

If you shake the Accel, the xyz values will change depending on how rough you shake it. Now yes you can get a base reading of the values and try to constrain them from going any higher or lower, but that's more work then what should be needed.

What you should really get is a Gyro sensor, they are meant to do what you want and no constraining of any values needed.

But this is your project, so you can do the research to see what fits your needs and how far you are willing to go to achieve what you are looking for.

I’d like the processing app to display the raw accelerometer data in degrees.

An accelerometer measures the rate of change of velocity. How do you get degrees out of that?

I think the OP want to use the accelerometer as a tilt sensor, which is possible if it is not being accelerated while the measurements are being taken. It is a matter of simple trigonometry, and the following is a good reference (it is for a tilt compensated compass, but still useful): http://cache.freescale.com/files/sensors/doc/app_note/AN4248.pdf

PaulS:

I'd like the processing app to display the raw accelerometer data in degrees.

An accelerometer measures the rate of change of velocity. How do you get degrees out of that?

Please try and help people, not be difficult. Accelerometers are routinely used to sense orientation by measuring the acceleration due to gravity, and the brief answer to the question is

  float x_angle = atan2 (x, z) ;
  float y_angle = atan2 (y, z) ;

[ pseudo-code ]

Please try and help people, not be difficult.

I'm not trying to be difficult. I want OP (and others) to understand what an accelerometer actually measures, and what the output means. Too many people think that the output is going to be the angle between the device and some undefined coordinate system, and that all the need to do is read the data as though it was orientation information - angles with respect to some (undefined) coordinate system.

Well, consider that stating “accelerometers measure the rate of change of velocity” is misleading, because people are then confused by the fact that accelerometers measure the equivalent of 1 g, in some direction, when sitting still on a table.