Go Down

Topic: output data of 9DOF sparkfun stick (Read 743 times) previous topic - next topic

vandeer

Hi

I'm currently working with the 9DOF stick of sparkfun. https://www.sparkfun.com/products/10724
I'm using the ADXL345 accelerometer and ITG3200 gyro sensor and have a question about my output values.

The communication happens over i2C bus and works fine. I use an Arduino Uno board and no other devices are connected. The problem are the values of the accelerometer and gyro.
A readout over serial communication is attached. axes in table( ADXL: X Y Z, ITG: X Y Z, HCM: X Z Y)

I wonder if those values can be correct, especially the ones of the accelerometer When placed on flat surface the X axis measures about -10, the Y axis about -270 and the Z axis about 250. When moving these values change but the X axis value doesn't really.

Is it normal that the sensor measures negative values? and why is there a high value on the Y axis when this axis is perpendicular to the gravitation? Is this the offset?
Sometimes the values of the acceleromter of Y and Z axis even change to 510 and- 510 and behave the same way.

ok those were a lot of questions. I hope you can answer some or post your readout values.

thanks in advance

lukas

my code for better understanding:

Code: [Select]
//include the Wire library for cummunication with sensorstick 9DOF
#include <Wire.h>



/*********************ADXL*****************************/

//address of ADXL, found with code for address searching see: http://playground.arduino.cc/Main/I2cScanner
#define ADXL_ADDRESS (0x53)
//the device address Register DEVID, only for read
#define DEVID (0x00)
//sets the measuring mode to standby or to measuring
#define POWER_CTL (0x2D)
//Sets measuring Range to 2g,4g,8g or 16g
#define DATA_FORMAT (0x31)
//sets the data rate. this should go well with the speed of the bus (have a slower rate), otherwise
//measurements are overwritten before written to the arduino.
#define BW_RATE (0x2C)
//sets the offset of the axis x,y and z
#define OFSX (0x1E)
#define OFSY (0x1F)
#define OFSZ (0x20)
//define the first data output register
#define DATAX0_REG (0x32)
//define the value for measuring mode (00001000) => see data sheet for more information
#define POWER_CTL_MEASURE (B00001000)
//define maesuring rate of 800Hz
#define BW_RATE_800HZ (B00001101)
//define value for 4g measuring range
#define DATA_FORMAT_4G (B00000001)
//define offset values
#define OFSXV (B00000000)
#define OFSYV (B00000000)
#define OFSZV (B00000000)
/***********************ITG***********************************/

//address of ITG, found with code for address searching see: http://playground.arduino.cc/Main/I2cScanner
#define ITG_ADDRESS (0x68)
//register with address, only read
#define WHO_AM_I (0x00)
//sample rate divider register
#define SMPLRT_DIV (0x15)
//set the gyro range as well as the low pass filter bandwidth and the internal
//sample rate
#define DLPF_FS (0x16)
//define the first data output register
#define GYRO_XOUT_H_REG (0x1D)
//define the bit values for the measurement scale and low pass filter frequence
#define DLPF_FULLSCALE (B00011000)
#define DLPF_42HZ (B00000011)
//define devider to one for 1000hz/1+k(1)=500hz
#define SMPLRT_DIV1 (B00000001)

/**************************HCM*******************************/

//address of HCM, found with code for address searching see: http://playground.arduino.cc/Main/I2cScanner
#define HCM_ADDRESS (0x1E)
//no register to read the address
//mode register for continious measurement
#define MODE_REGISTER (0x02)
//register for settings
#define CONFG_REG_A (0x00)
//first data output register
#define DATA_OUTPUTX_MSB_REG (0x03)
//variable to init continous measurement mode
#define MODE_REGISTER_CNTMSM (0x00)
//define data rate and samples avaraged
#define CONFG_RATE (B01011000)



/*******************define the values for the correct register setting********************/


//define the varibales in form of the register name. The values written in the registers will be
//saved in those variables.
//use byte for 8bit number (char is for letters as well)



//set up the arrays for the read_xxx() function with 3 values (x,y,z)
int accelerometer[3];
int gyroscop[3];
int magnetometer[3];



//varibales for ADXL bytes from data registers



void setup()
{
  init_serial();
  init_wire();
  init_ADXL();
  init_ITG();
  init_HCM();

}

void loop()
{
  read_ADXL();
  read_ITG();
  read_HCM();
  serial_print();
}

void init_serial(){
  Serial.begin(9600);
}

void init_wire(){
  Wire.begin();
}

void init_ADXL(){
  write_REG(ADXL_ADDRESS,POWER_CTL, POWER_CTL_MEASURE);
  write_REG(ADXL_ADDRESS,BW_RATE, BW_RATE_800HZ);
  write_REG(ADXL_ADDRESS,DATA_FORMAT, DATA_FORMAT_4G);
  write_REG(ADXL_ADDRESS,OFSX, OFSXV);
  write_REG(ADXL_ADDRESS,OFSY, OFSYV);
  write_REG(ADXL_ADDRESS,OFSZ, OFSZV);
}

void init_ITG(){
  write_REG(ITG_ADDRESS, DLPF_FS, (DLPF_FULLSCALE|DLPF_42HZ));
  write_REG(ITG_ADDRESS, SMPLRT_DIV, SMPLRT_DIV1);
}

void init_HCM(){
  write_REG(HCM_ADDRESS,MODE_REGISTER,MODE_REGISTER_CNTMSM);
  write_REG(HCM_ADDRESS, CONFG_REG_A, CONFG_RATE);

}

void read_ADXL(){
  byte DATAX0 = read_REG(ADXL_ADDRESS, DATAX0_REG);
  byte DATAX1 = read_REG(ADXL_ADDRESS, DATAX0_REG+1);

  accelerometer[0]=(DATAX0|DATAX1<<8);

  byte DATAY0 = read_REG(ADXL_ADDRESS, DATAX0_REG+2);
  byte DATAY1 = read_REG(ADXL_ADDRESS, DATAX0_REG+3);

  accelerometer[1]=(DATAY0|DATAY1<<8);

  byte DATAZ0 = read_REG(ADXL_ADDRESS, DATAX0_REG+4);
  byte DATAZ1 = read_REG(ADXL_ADDRESS, DATAX0_REG+5);

  accelerometer[2]=(DATAZ1<<8|DATAZ0);
}

void read_ITG(){
  byte GYRO_XOUT_H = read_REG(ITG_ADDRESS, GYRO_XOUT_H_REG);
  byte GYRO_XOUT_L = read_REG(ITG_ADDRESS, GYRO_XOUT_H_REG+1);

  gyroscop[0]=(GYRO_XOUT_L|GYRO_XOUT_H<<8);

  byte GYRO_YOUT_H = read_REG(ITG_ADDRESS, GYRO_XOUT_H_REG+2);
  byte GYRO_YOUT_L = read_REG(ITG_ADDRESS, GYRO_XOUT_H_REG+3);

  gyroscop[1]=(GYRO_YOUT_L|GYRO_YOUT_H<<8);

  byte GYRO_ZOUT_H = read_REG(ITG_ADDRESS, GYRO_XOUT_H_REG+4);
  byte GYRO_ZOUT_L = read_REG(ITG_ADDRESS, GYRO_XOUT_H_REG+5);

  gyroscop[2]=(GYRO_ZOUT_L|GYRO_ZOUT_H<<8);

}

void read_HCM(){
  byte DATAOUTPUTX_MSB = read_REG(HCM_ADDRESS,DATA_OUTPUTX_MSB_REG);
  byte DATAOUTPUTX_LSB = read_REG(HCM_ADDRESS, DATA_OUTPUTX_MSB_REG+1);

  magnetometer[0]=(DATAOUTPUTX_MSB<<8|DATAOUTPUTX_LSB);

  byte DATAOUTPUTZ_MSB = read_REG(HCM_ADDRESS,DATA_OUTPUTX_MSB_REG+2);
  byte DATAOUTPUTZ_LSB = read_REG(HCM_ADDRESS, DATA_OUTPUTX_MSB_REG+3);

  magnetometer[1]=(DATAOUTPUTZ_MSB<<8|DATAOUTPUTZ_LSB);

  byte DATAOUTPUTY_MSB = read_REG(HCM_ADDRESS,DATA_OUTPUTX_MSB_REG+4);
  byte DATAOUTPUTY_LSB = read_REG(HCM_ADDRESS, DATA_OUTPUTX_MSB_REG+5);

  magnetometer[2]=(DATAOUTPUTY_MSB<<8|DATAOUTPUTY_LSB);

}



void serial_print(){
  Serial.print("ADXL345:");
  Serial.print("\t");
  Serial.print(accelerometer[0]);
  Serial.print("\t");
  Serial.print(accelerometer[1]);
  Serial.print("\t");
  Serial.print(accelerometer[2]);
  Serial.print("\t");

  Serial.print("ITG 3200");
  Serial.print("\t");
  Serial.print(gyroscop[0]);
  Serial.print("\t");
  Serial.print(gyroscop[1]);
  Serial.print("\t");
  Serial.print(gyroscop[2]);
  Serial.print("\t");

  Serial.print("HCM5883L");
  Serial.print("\t");
  Serial.print(magnetometer[0]);
  Serial.print("\t");
  Serial.print(magnetometer[1]);
  Serial.print("\t");
  Serial.print(magnetometer[2]);
  Serial.println();



}



void write_REG(int DeviceAddress, byte SensorRegister, byte RegValue)
{
  Wire.beginTransmission(DeviceAddress);
  Wire.write(SensorRegister);
  Wire.write(RegValue);
  Wire.endTransmission();
}

int read_REG(int DeviceAddress, byte SensorRegister)
{
  int result;
  Wire.beginTransmission(DeviceAddress);
  Wire.write(SensorRegister);
  Wire.endTransmission();

  Wire.requestFrom(DeviceAddress,1);
  while(Wire.available()){
    result=Wire.read();
  }
  return result;
}





michinyon

You will need to read the datasheet of the device,  to see what the scaling of the numbers is supposed to be.

Yes,  you will get negative numbers.  If the device isn't moving much,  it is measuring the apparent acceleration of gravity.  Actually,  that isn't really true,  it is measuring the force exerted by your hand which is preventing the device from falling into the bottomless pit under your desk.        Anyway,  if you hold the device one way,   you will get a certain reading,   and if you turn the device over in your hand,   you will get the opposite ( negative ) reading.

vandeer

I found the values for the scaling they are 128.0 for the accel and 14.375 for the gyro

Do you have any idea why the signal is so close to 256 and 511, which are the binary values 10000000 and 11111111.
Isn't that suspicious for any mistake in the bitwise operations?

And additionally, why is the Y-axis-value as high as the Z-axis-value when the sensor is placed on a flat surface?  There shoulnd't be any force acting on this axis.


Go Up