Home Arduino Code How to translate Virtuabotix Accelerometer G Forces to Degrees on the Arduino or Versalino
How to translate Virtuabotix Accelerometer G Forces to Degrees on the Arduino or Versalino

How to translate Virtuabotix Accelerometer G Forces to Degrees on the Arduino or Versalino

1

In this guide we will go through the process of translating G forces as measured by our Virtuabotix Accelerometer attached to a Versalino Sense & Move on a Versalino into calibrated degrees from 0 to 360. This process can be used on any Arduino compatible system to include the Arduino Uno or Mega, but it is very easy to do on the Versalino because the Virtuabotix Accelerometer library that I wrote has built in functions to work with the Versalino bus structure.

This system could be used to determine the angle of any vectors (not just G Forces), and you are welcome to use it in any of your projects or articles, just be sure to include this header, and a link to this article in you code. Thank you for supporting open source software!

WARNING: I USE AND EXPLAIN TRIGONOMETRIC EQUATIONS BELOW! IF YOU ARE AFRAID OF MATH AVERT YOUR EYES. You have been warned…

/*####################################################################
FILE: Sense-Move-AutoCal-WITHDEGREES.ino
VERSION: 1S0A
PURPOSE: Translate the force data from the Virtuabotix Accelerometer
attached to the Versalino Sense & Move on a Versalino into degrees.
LICENSE: GPL v3 (http://www.gnu.org/licenses/gpl.html)

GET UPDATES: http://josephdattilo.com/

HISTORY:
Joseph Dattilo (Virtuabotix LLC)
-Initial shell from Virtuabotix Accelerometer Library Examples
Bobby Williams, Joshua Soliday, and Joseph Dattilo (Virtuabotix LLC)
- Version 1S0A (10/02/13)
#######################################################################*/

Okay so the first thing we have to do is include our Accelerometer.h and math.h libraries, the Accelerometer.h library was already part of the shell sketch we got from the Virtuabotix Accelerometer example sketch, but the math.h file had not been included before. The math.h library gives us the absolute value abs() and the arctangent atan() functions that we will be using to determine our angular measurements.

After that point everything else is the same as the example sketch. Basically we declare our instance of the Accelerometer class as our accelerometer object. We then jump into our setup routine where we start our serial port at 9600 baud, and connect our accelerometer object to BUSA. This is where you would change to pin calls if you were using a regular Arduino board (see appropriate examples in the Virtuabotix Accelerometer library).

Finally we notify the user of calibration, wait 2 seconds to allow them to respond, and start the calibration routine before exiting the setup function.

#include "Accelerometer.h"
#include //add this library for the atan function!

Accelerometer myAccelerometer = Accelerometer();

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

//Connect up the following pins and your power rail
// SL GS 0G X Y Z
myAccelerometer.begin(BUSA);

//calibration performed below
Serial.println("Please place the Accelerometer on a flat\nLevel surface");
delay(2000);//Give user 2 seconds to comply
myAccelerometer.calibrate();
}

As you can see above we can calculate a force vector angle using the arctangent of  opposite/adjacent sides Z over X in this case.
As you can see above we can calculate a force vector angle using the arctangent of opposite/adjacent sides Z over X in this case.

So here is where the math comes in. I know, I know, you were hoping it was a joke when I said we were going to use trigonometry. Sadly I was perfectly serious. First of all let’s review how to get the angle of using the Arctangent function or atan() in c++.

As illustrated on the left, you can calculate the angle of a force vector (or anything else really) by taking the arc-tangent of the opposite sides value over the adjacent sides value. This calculates the angle between the adjacent side and the vector of interest. In this case the force applied by gravity.

Of course the big problem with using this method is that you get values between -90 and 0, or  0 and 90 degrees, and that all depends on the relationship between the Opposite, and Adjacent sides. Which can be really messy if you are trying to calculate or control around more than a single quadrant of motion. (A quadrant is a 4th of the graph if you are talking about vectors in 2 dimensions.)

At first we didn’t think it was going to be that big of a deal, but we were proven wrong pretty quickly when we tried to control something with the raw data. But as you can see in the graph and code below, some adjustments are actually required.

Quadrant math for degree conversions
Here is a cleaned up version of how we worked out the Quadrant issues on the whiteboard.

int translateGsToDegrees(double ForceHor, double ForceVert)
{
if(ForceHor==0)ForceHor=0.01; //Keep from division by 0
if(ForceVert==0)ForceVert=0.01; //Keep from division by 0

int addToMeasure;
if(ForceHor > 0 && ForceVert > 0) addToMeasure = 0;
if(ForceHor < 0 && ForceVert > 0) addToMeasure = 90;
if(ForceHor < 0 && ForceVert < 0) addToMeasure = 180; if(ForceHor > 0 && ForceVert < 0) addToMeasure = 270; int myReturn = (atan(ForceVert/ForceHor)/3.14159) * 180; if(myReturn < 0) myReturn += 90; myReturn = abs(myReturn) + addToMeasure; return myReturn; }

The function above is arguably the most important to the functionality of this program (if you don't count having an Arctangent function itself ;D ). It basically checks what quadrant the input is in with those 4 if statements that match the illustration above this code, and then performs the conversion from distances to an angle, and converts that angle to degrees from radians (by dividing by PI and multiplying by 180).

Finally it checks if the calculated value is in negative degrees, and adds 90 degrees to it if it is (which forces it to register in the correct direction of travel). If you are confused about this, just look at the direction of the arrows in the negative quadrants, and you will notice that the direction of travel and starting point is opposite to those in positive quadrants.

Finally we add the values determined by our if statements, and we have magically converted our raw input into valid values between 0 and 360 degrees.

void loop()
{
delay(2000);//delay for readability
//reads the values of your accelerometer
myAccelerometer.read();
Serial.println("The Accelerometer reads X, Y, Z");
Serial.print(myAccelerometer._Xgs);
Serial.print(" Gs, ");
Serial.print(myAccelerometer._Ygs);
Serial.print(" Gs, and ");
Serial.print(myAccelerometer._Zgs);
Serial.println(" Gs respectively.");
//-----------------------------------
//CALCULATE ANGLES o.O
double degreesXtoY, degreesXtoZ, degreesYtoZ;

degreesXtoY = translateGsToDegrees(myAccelerometer._Xgs, myAccelerometer._Ygs);
degreesXtoZ = translateGsToDegrees(myAccelerometer._Xgs, myAccelerometer._Zgs);
degreesYtoZ = translateGsToDegrees(myAccelerometer._Ygs, myAccelerometer._Zgs);

//OUTPUT RESULTS
Serial.println("The force of gravity is at angles:");
Serial.print(degreesXtoY); Serial.println(" degrees from X to Y");
Serial.print(degreesXtoZ); Serial.println(" degrees from X to Z");
Serial.print(degreesYtoZ); Serial.println(" degrees from Y to Z");

}

Above we take our readings from the Virtuabotix Accelerometer, and get all the way from raw PWM, to G forces, and finally degrees for each angle.

I look forward to putting this technique to use in an interesting program we developed for controlling the Virtuabotix Pan & Tilt in a short while, and as always welcome any comments or improvements you all recommend!

Joseph Dattilo Writer, Electrical Engineer, CEO and founder of Virtuabotix LLC, and completely crazy in every way.

Comment(1)

Comments are closed.