345 ADXL Dual axis tilt calculation

Hello everyone! I could use some guidance for my dual axis tilt calculation. I believe I was successful in writing a code to output my x & y readings through a single axis calculation (not posted here but very similar). I am looking for degrees of tilt output for both x and y axes. I have searched all over the place and I am getting myself confused.

However, I need to use the more advanced dual axis calculation from this article (https://www.analog.com/media/en/reference-design-documentation/reference-designs/cn0189.pdf).

Perhaps I am confused but should this output both an x & y reading corresponding to the degrees of tilt within the x - axis and y - axis or just one reading if using the inverse tangent? I positioned the sensor vertically (as that is how it will need to be aligned for my purposes) and the y readings were sometimes 'nan'. I am wondering if anyone has successfully implemented this calculation with an adxl345 from adafruit or something similar and would be willing to guide me through my problems within my code. Please see my code below, thank you!

/// UPDATED:FINAL 12/29/21 ///

///Objective - read accerometer raw data then convert into degrees of tilt using trig functions at 10hz. 
              // write data to sd card for each day (e.g., Monday --> monday.csv, Tuesday --> tuesday.csv) 
              //threshold 00:00am - 23:59pm or by # of rows in file (~864,000)



//Libraries//
#include <SPI.h> //SPI communication library
#include <SD.h> //SD library
#include <Wire.h> //Talking over I2C
#include <DS3232RTC.h> // For RTC DS3231
#include <RTClib.h> //For RTC DS3231

//Setup Stuff//
RTC_DS3231 rtc;

char daysOfTheWeek[7][12] = {"mon", "tue", "wed", "thu", "fri", "sat","sun"};
int ADXL345 = 0x53;            //I2C 345 Address
float X_out,Y_out,Z_out;
float result_x;
float result_y;
float x, y ,z;
float Xd,Yd,Zd;

//void Calc_angles(void){
  //float X_out,Y_out,Z_out;
  //float x,y,z;              //Outputs
  //float result_x, result_y;
//x = X_out/256;
//y = Y_out/256;
//z = Z_out/256;

//X Axis//
//result_x = asin(x);

//Y Axis//
//result_y = asin(y);

//}


const int CS_SD = 10;        //For SD Breakout


char *filenames[7] = {
  "sun.csv","mon.csv","tue.csv","wed.csv","thu.csv","fri.csv", "sat.csv"
  };   //start of example online to read multiple csv files by date
File myFile;                 //Data object to write sensor data to


const unsigned long eventInterval = 100 ; //100milliseconds = 10hz
unsigned long previousTime = 0; 





////////SETUP///////

void setup()
{
  Serial.begin(4800); // Serial monitor on

  pinMode(10,OUTPUT);

  Wire.begin(); // Initiate the Wire library

  Wire.beginTransmission(ADXL345); // Start communication with 345
  Wire.write(0x2D); // Access/talk to POWER_CTL register 0X2D
  Wire.write(8); // (8dec -> 0000 1000 binary) Bit D3 High for measuring enable 

  Wire.endTransmission();
  
  SD.begin(10); //Initialize the SD card reader
  if (SD.begin(10))
  {
    Serial.println("SD card is ready to use!");
  }
  else 
  {
    Serial.println("SD card initialization failed");
    return;
  }
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    abort();
  }
  if (rtc.lostPower()) {
    Serial.println("RTC lost power, let's set the time!");
                                                             // When time needs to be set on a new device, or after a power loss, the
                                                             // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__),F(__TIME__)));                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       // This line sets the RTC with an explicit date & time, for example to set
                                                            // January 21, 2014 at 3am you would call:                                                      // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }

}



///////////LOOP///////////////


void loop()
{
  Wire.beginTransmission(ADXL345);
  Wire.write(0x32);
  Wire.endTransmission(false);
  Wire.requestFrom(ADXL345, 6, true);           // Read 6 registers total, each axis value is stored in 2 registers
  
  X_out = ( Wire.read() | Wire.read() << 8);   // X-axis value
  x = X_out/256;                              //For a range of +/- 2g, we need to divide raw values by 256 (Datasheet)
  Y_out = ( Wire.read() | Wire.read() << 8);
  y = Y_out/256;
  Z_out = ( Wire.read() | Wire.read() << 8);
  z = Z_out/256;

  result_x = asin(x);                      // Take tan of x & y for dual axis calculation
  result_y = acos(y);

  Xd = result_x * 180/ 3.14159265;                   // Convert from radians to degrees
  Yd = result_y * 180 / 3.14159265;
  //Zd = z * 180 / 3.14159265;

 

  unsigned long CurrentTime = millis();

  if (CurrentTime - previousTime >= eventInterval)
  { 
    DateTime now = rtc.now();

    ///TEST sat issue///
      //Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
      //Serial.print(",");
      //Serial.print(now.month(), DEC);
      //Serial.print(",");
      //Serial.print(now.day(), DEC);
      //Serial.print(",");
      //Serial.print(now.year(), DEC);
      //Serial.print(",");
      //Serial.print(now.hour(), DEC);
      //Serial.print(':');
      //Serial.print(now.minute(), DEC);
      //Serial.print(':');
      //Serial.print(now.second(), DEC);
      //Serial.println();
      Serial.print(Xd);
      Serial.print(",");
      Serial.print(Yd);

    previousTime = CurrentTime; //Updates for next time around//
    myFile = SD.open(filenames[now.dayOfTheWeek()], FILE_WRITE);
 if (myFile) 
 {
  //myFile.print(daysOfTheWeek[now.dayOfTheWeek()]);     //Maybe don't need this part 
  //myFile.print(",");
  myFile.print(now.month(), DEC);
  myFile.print(",");
  myFile.print(now.day(), DEC);
  myFile.print(",");
  myFile.print(now.year(), DEC);
  myFile.print(",");
  myFile.print(now.hour(), DEC);
  myFile.print(':');
  myFile.print(now.minute(), DEC);
  myFile.print(':');
  myFile.print(now.second(), DEC);
  myFile.println();
  myFile.print(Xd);
  myFile.print(",");
  myFile.print(Yd);
  myFile.print(",");
  myFile.print(Zd);
  myFile.print(",");
  Serial.println();
  myFile.close();          // Close the file 
 }
}
}

This approach is correct:

https://wiki.dfrobot.com/How_to_Use_a_Three-Axis_Accelerometer_for_Tilt_Sensing

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.