Accelerometer variations...

Right so, im building a “hand orientation” controlled quadopter (handpiece image below) with an ADXL345 and I am running into a bit of trouble.

The problem is that, the Micro is taking a long enough time to go through the code so that the instructions (elevation and X&Y tilt) sent to the bird are a bit choppy and inconsistent, the particular problem being the long i2c code to read from the registers and bring back X&Y orientation variables. In fact if I remove the orientation code; elevation control is extremely smooth (elevation is controlled by two switches on the index finger for up and down)

Now, i have seen some analog accelerometers giving a voltage as an orientation reference; using those would make the code “oh so much shorter” using analogRead two times instead of going through the registers on the TWI.

i was wondering if someone could tell me what the difference is between an analog and an i2c based accelerometer in terms of accuracy, reliablity, and the major and minor differences between them, and if it would benefit me and help resolve my issue if i switch to an analog accelerometer.

Your help is much appreciated…

There may be other problems with the code you already have. Post it using code tags ("<>" button).

#include <Wire.h>
#define Register_ID 0
#define Register_2D 0x2D
#define Register_X0 0x32
#define Register_X1 0x33
#define Register_Y0 0x34
#define Register_Y1 0x35
#define Register_Z0 0x36
#define Register_Z1 0x37


int ADXAddress = 0xA7 >> 1;
int reading = 0;
int X0,X1,X_out;
int Y0,Y1,Y_out;
int Z1,Z0,Z_out;
double Xg,Yg,Zg;
float up;

void setup()
{
  pinMode(9,OUTPUT);
  up=0;
  Wire.begin();                
  Serial.begin(115200);    

  // enable to measute g data
  Wire.beginTransmission(ADXAddress);
  Wire.write(Register_2D);
  Wire.write(8);                //measuring enable
  Wire.endTransmission();     // stop transmitting
  
}


void loop()
{
  
  getgyrovalues();
  
  up=constrain(up,0.00,140.00);
  if(digitalRead(A5)==LOW && digitalRead(A4)==LOW)
    {
    }
  else if(digitalRead(A5)==LOW)
    up+=0.5;
  else if(digitalRead(A4)==LOW)
    up-=0.5; 
   analogWrite(9,up)  ;
  
 
  Serial.print("Elevation= ");    //for looking at data and debugging
  Serial.print(up);
  Serial.print("  ");
  Serial.print("X= "); 
  Serial.print(Xg);
  Serial.print("  ");
  Serial.print("Y= "); 
  Serial.print(Yg);
  Serial.println("  ");

}



void getgyrovalues()
{
 //X
  Wire.beginTransmission(ADXAddress); 
  Wire.write(Register_X1);
  Wire.endTransmission();
  Wire.requestFrom(ADXAddress,2); 
  if(Wire.available()<=2)   
  {
    X0 = Wire.read();
    X1 = Wire.read(); 
    X1=X1<<8;
    X_out=X0+X1;   
  }

  //Y
  Wire.beginTransmission(ADXAddress); 
  Wire.write(Register_Y0);
  Wire.write(Register_Y1);
  Wire.endTransmission();
  Wire.requestFrom(ADXAddress,2); 
  if(Wire.available()<=2)   
  {
    Y0 = Wire.read();
    Y1 = Wire.read(); 
    Y1=Y1<<8;
    Y_out=Y0+Y1;
  }
  
  Xg=X_out/256.0;
  Yg=Y_out/256.0;

  
}

This is my code, I have used the same code for getting X and Y and using their values for a balancing project, and it worked fine. although a balancing platform is not a quadcopter and doesn’t need the same level of quickness.

I might also add that the values for X and Y are not even being sent to the quad as of yet, i am only testing the elevation control with the orientation code running to see the responsiveness.
And as i said in my post, it is very smooth without the i2c code and slightly choppy with it.

There are lots of problems with that code. I don’t see any need for float variables, all that printing, and what do you suppose happens with the following lines, when Wire.available returns a number less that 2 (like 0)?

  if(Wire.available()<=2)   
  {
    Y0 = Wire.read();
    Y1 = Wire.read(); 
    Y1=Y1<<8;
    Y_out=Y0+Y1;
  }

You can save some time by requesting data starting at register X0 and reading 6 bytes so you get X, Y, and Z in one transaction.

I will try it and see what happens, it's actually a good idea. Although it might not do that much But what about those differences between analog and TWI accelerometers?

jremington:
There are lots of problems with that code. I don’t see any need for float variables, all that printing, and what do you suppose happens with the following lines, when Wire.available returns a number less that 2 (like 0)?

  if(Wire.available()<=2)   

{
    Y0 = Wire.read();
    Y1 = Wire.read();
    Y1=Y1<<8;
    Y_out=Y0+Y1;
  }

The float variable I’m using to make the pwm signal increments smoother as you can see in the increments of 0.5 as increasing it by one while the button is pressed maxes it out too fast and i end up with a quadcopter stuck to the ceiling
The “2” is waiting for two bytes to be available on the bus, as you can see it’s “.available” and that gets a value increment whenever a byte is available on any bus whether its serial or TWI
And as far as the printing goes the speed does not increase when the print lines are removed

After looking at the issue do you think an analog device is more effecient for me?

Wrong. The if is true for any return value less than or equal to 2. So when it returns 0, you try to read 2 bytes anyway.

I don’t think you are using the ADXL345 correctly, so it is premature to discard it in favor of an analog accelerometer.

In addition to the <= program error mentioned above, the default sample rate on the 345 is 100 Hz. That can be increased to 200 Hz using the standard I2C 100 kHz connection, or to much, much higher if you use an SPI connection. See the data sheet for details.

well discarded or not, is it better than an analog one or not? I'm still confused about the main question in my topic which is the differences between this and an analog one

An analog output accelerometer is read by the Arduino ADC, the others by SPI or I2C. Beyond that, you need to compare the data sheets.

Why not just try to fix your program?

I dont think you fully understand my question... Or my post for that matter I was asking for a comparison between digital and analog accelerometers in terms of reliability and accuracy, i already know how they are read...

I will try the datasheets since no one here seems to read the last paragraph in my post

Maybe no one wants to take the time to review all the available devices, and summarize them for you. It is certainly discouraging that you don't seem interested in learning how to properly use the one you have.

What you see as disinterest is the fact that i know there is nothing wrong with the code, infact i only slightly modified the code given by Adafruit Industries and the mod wasn’t in the for loops so basically it’s either your word or Adarfuit’s.

Also as i have said i have used it before and it’s giving proper x and y in terms of g

As for what you said, maybe someone who actually knows something about the subject will answer me. If you don’t have the time or lack the knowledge with these devices i appreciate your help so far :slight_smile: and thanks