First post. Here goes.
For work I measure currents and waves in the sea. Sometimes I need to place instruments on the seabed to do this. In these circumstances the instruments are mounted on a frame which is lowered to the seabed from a vessel where they stay for typically 2 or 3 months while they do their thing autonomously. Some of these instruments need to sit vertical (plus or minus 10 or 15 degrees) to work properly so it is crucial that I know that they are nicely placed on the seabed before I leave them. I don’t want pitch and roll, I want a single value of tilt from 0 to 180 degrees.
I am trying to build a system that measures the tilt and transmits this information acoustically, through the water column, to me at the surface. The frames are lowered to the seabed on a rope. If I know that the frame is tilted (perhaps it landed on a rock), I can lift the frame and put it down somewhere else before releasing the frame and recovering the rope.
My gadget will be rigidly fixed to the seabed frame alongside the other instruments. It uses an ADXL345 accelerometer and an Arduino Nano to provide a single value of tilt. These items will be in an underwater housing. The Arduino will send the single tilt value to another system which will transmit the information acoustically through the sea water to me at the surface via a hydrophone and receiving system.
The through water communications are sorted but deriving a single value of tilt from the Arduino and accelerometer is proving difficult.
My Nano and ADXL345 are working fine. I have calibrated the sensor and applied offset and gain factors. I can get 3 realistic values in G’s and I can get pitch and roll plus and minus 180 degrees but I don’t know how to derive the single tilt value that I need.
On this forum I have seen references to links such as this one.
http://cache.freescale.com/files/sensors/doc/app_note/AN4248.pdf
But to be honest the maths is way beyond me. I suppose I am asking if anyone can help me out with some code or at least point me in the right direction.
Here is the code I use to get my G values, pitch and roll.
/* Uses I2C comms with 2 x 4.7K resistors
* Uses sparkfun ADXL345 library
* This one applys Offset and gain values derived by calibration
* Outputs G values which are then used derive pitch and roll values + and - 180 d.
* Offset and Gain values are when set to +or- 2g mode.
*/
#include <SparkFun_ADXL345.h>
//*********** COMMUNICATION SELECTION ***********/
/* Comment Out The One You Are Not Using */
//ADXL345 adxl = ADXL345(10); // USE FOR SPI COMMUNICATION, ADXL345(CS_PIN);
ADXL345 adxl = ADXL345(); // USE FOR I2C COMMUNICATION
//****************** VARIABLES ******************/
/* */
float accX;
float accY;
float accZ;
float pitch,roll;
//************** DEFINED VARIABLES **************/
/* */
#define offsetX 14 // OFFSET values
#define offsetY 2
#define offsetZ -11
#define gainX 260 // GAIN factors
#define gainY 264
#define gainZ 253
//******************** SETUP ********************/
/* Configure ADXL345 Settings */
void setup(){
Serial.begin(9600); // Start the serial terminal
adxl.powerOn(); // Power on the ADXL345
adxl.setRangeSetting(2); // Give the range settings
// Accepted values are 2g, 4g, 8g or 16g
// Higher Values = Wider Measurement Range
// Lower Values = Greater Sensitivity
//adxl.setSpiBit(0); // Configure the device to be in 4 wire SPI mode when set to '0' or 3 wire SPI mode when set to 1
// Default: Set to 1
// SPI pins on the ATMega328: 11, 12 and 13 as reference in SPI Library
// Preseume not needed in I2C mode
}
//****************** MAIN CODE ******************/
/* Accelerometer Readings and Interrupt */
void loop(){
// Get the Accelerometer Readings
int x,y,z;
adxl.readAccel(&x, &y, &z); // Read the accelerometer values and store them in variables declared above x,y,z
Serial.print("x y z: "); Serial.print(x); Serial.print(" ");Serial.print(y); Serial.print(" "); Serial.print(z);
//Apply offsets
accX = (x - offsetX); // Calculating New Values for X, Y and Z with offsets applied
accY = (y - offsetY);
accZ = (z - offsetZ);
//Apply gains
accX = (accX / gainX); // Calculating G Values for X, Y and Z with offsets and gains applied
accY = (accY / gainY);
accZ = (accZ / gainZ);
Serial.print(" Converted to G values: "); Serial.print(accX); Serial.print(" "); Serial.print(accY); Serial.print(" "); Serial.print(accZ);
Serial.println();
roll = (atan2(-accY, accZ)*180.0)/M_PI;
pitch = (atan2(accX, accZ)*180.0)/M_PI;
Serial.print(" Pitch =");
Serial.print(pitch);
Serial.print(" Roll =");
Serial.println(roll);
delay(500); // This is the delay between each reading
}
Thanks in anticipation.