Constant problem

Hi,

I have a problem with a calibrating a sensor.
The Y and Z axis are being calibrated just fine every time, but the X axis is always calculated as being 256. I measured the raw data coming from the X axis and it gives me other values at every start-up(it means that the sensor is working).

This is the code:

short iAcc[3], iGyr[3], T[1];
byte buff[2];
short smoothAcc[3]={0}, smoothGyr[3]={0};

void setup()
{
  Serial.begin(19200);
  Wire.begin();
  accel.init();
  gyro.init();
  for(byte i=0; i<100; i++)
  {
    accel.getValues(iAcc,buff);
    gyro.getValues(iGyr,T);
    for(byte j=0; j<3; j++)
    {
      smoothAcc[j]=smoothAcc[j]+iAcc[j];
      smoothGyr[j]=smoothGyr[j]+iGyr[j];
    }
  }
  for(byte i=0; i<3; i++)
  {
    smoothAcc[i]=smoothAcc[i]/100;
    smoothGyr[i]=smoothGyr[i]/100;
  }

The problem is with the smoothAcc[0] variable. This one always gives me the value 256, which is wrong.

And here is a part of the loop containing the variable-problem:

accel.getValues(iAcc,buff);
  gyro.getValues(iGyr,T);
  for(byte i=0; i<3; i++)
  {
    Serial.print(iAcc[i]-smoothAcc[i]);
    Serial.print("\t");
  }

What could be the problem. I mean, in my perception, the code is just fine, the data coming from the X-axis is right, it just has to be filtered.

Thank you,
RobertEagle

..what are the iAcc values comming from the accelerometer (min..max)? short = signed int, so 100 times "smoothAcc[j]=smoothAcc[j]+iAcc[j];" may overflow easily.. instead of short try to use long..

The value is in the range of (-4091)-to-4091. But when is stationary, it doesn't get bigger than +-200. I've switched to int and long types, with no success. Look what I found:

In the setup() function I found that in the first loop the smoothAcc[0] simply doesn't add. It does give the current value, and that's all. The other 2 (smoothAcc[1] and smoothAcc[2]) are incrementing with the current values, just as it should be.

I'm guessing that buff is overflowing, but without seeing the code, that's just a guess.

Do you want to post just the sketch code, or both the library and the sketch? By the way, the buff just takes values of 0 or 1.

Actually, you were right. I didn't see that the buff is [2] instead of [3]. And yes, it was overflowing. Now it works.

Thank you, RobertEagle

short smoothAcc[3]={0}, smoothGyr[3]={0};

I'm always curious why anyone defines the size of the array, and then provides fewer initializers than that defined size. When there are not enough initializers provided, the provided value is not used to initialize all elements of the array. They other elements get whatever is the default value for the array type.

In this case, the provided initializer and the default value are the same, but I'm, still curious why you provide only some initializers.

Do you know the moment when you’re trying desperate to accomplish something by writing anything just to get a ,change"? Well, I’m still in this situation. And I know that I should have written {0,0,0} or anything else, not just one initializer.

Now, the first value of the getValues function (iAcc[0]) is almost always wrong(except when I just print it), and probably like just AWOL said, might be overflowed.

This is the current sketch code:

#include <IMU.h>
#include <Wire.h>
Adxl345 accel;
Itg3200 gyro;
processing pros;

short iAcc[3], iGyr[3], T[1];
byte buff[3];

int lowAcc[4], lowGyr[3];

void setup()
{
  Serial.begin(19200);
  Wire.begin();
  accel.init();
  gyro.init();
}

void loop()
{
  byte counter=33; //running at 30Hz
  while(counter!=0) //low pass filter
  {
    accel.getValues(iAcc,buff);
    gyro.getValues(iGyr,T);
    --counter;
    lowAcc[0]=lowAcc[0]+iAcc[0]; //incrementing
    lowAcc[1]=lowAcc[1]+iAcc[1];
    lowAcc[2]=lowAcc[2]+iAcc[2];
    lowGyr[0]=lowGyr[0]+iGyr[0];
    lowGyr[1]=lowGyr[1]+iGyr[1];
    lowGyr[2]=lowGyr[2]+iGyr[2];
  }
  lowAcc[0]/=33;//and averaging
  lowAcc[1]/=33;
  lowAcc[2]/=33;
  lowGyr[0]/=33;
  lowGyr[1]/=33;
  lowGyr[2]/=33;
  printData();
}

void printData()
{
  for(byte i=0; i<3; i++)
  {
    Serial.print(lowAcc[i]);
    Serial.print("\t");
  }
  for(byte i=0; i<3; i++)
  {
    Serial.print(lowGyr[i]);
    Serial.print("\t");
  }
  Serial.println();
}

And here’s the getValues function:

void Adxl345::getValues(short* out,byte* buffer)
{
	readInt();
	buffer[0]=bitRead(tab[0],6);//single tap
	buffer[1]=bitRead(tab[0],5);//double tap
	buffer[2]=bitRead(tab[0],2);//free fall
	buffer[3]=bitRead(tab[0],7);//data xyz
	if(buffer[3]==1)
	{
		read(DATA,6);
		out[0] = ((((short)tab[1]) << 8) | tab[0])-offx;
		out[1] = ((((short)tab[3]) << 8) | tab[2])-offy;
		out[2] = ((((short)tab[5]) << 8) | tab[4])-offz;
	}
}

I shall say that the out is a short array (made of 3) and the buffer is a byte array (made of 4).
Now, in the sketch, when I print the iAcc[0] variable, it gives me the proper values, but when I try to make some math in the sketch, everything goes wrong.

Thank in advance,
RobertEagle

I shall say that the out is a short array (made of 3) and the buffer is a byte array (made of 4).

However, here:

accel.getValues(iAcc,buff);
gyro.getValues(iGyr,T);

buff is only three long and needs to be four. Similarly, T has one entry, but should also be four.

Is there any point to an array of length one?