Go Down

Topic: GY_85 9DOF ITG3205 + ADXL345 + HMC5883L Help! (Read 11126 times) previous topic - next topic

AndresC4

Hello everyone, im new on the forums and im tring to understand the i2c protocol and the i2c sensors.

I have an arduino Nano and a GY_85 9dof imu, wich contains this 3 chips  ITG3205 + ADXL345 + HMC5883L

i follow the instructions on this thread of rcgroups http://www.rcgroups.com/forums/showthread.php?t=1677559 and im able to get that code working with that software,,, but i want to read all the sensor data at the same time using my own code.

I spend hours searching for diferent adruino codes to get it working, and i found only 2 codes to use 2 of the chips one by one,,, i would like to combine them, i got them working on diferent sketchs.
I would love to take the code from the original sketch but its impossible for me to folow the code and to understand how to adress the i2c calls... this is what i got working untill now

Magnetrometer >

Code: [Select]
/*
An Arduino code example for interfacing with the HMC5883

by: Jordan McConnell
SparkFun Electronics
created on: 6/30/11
license: OSHW 1.0, http://freedomdefined.org/OSHW

Analog input 4 I2C SDA
Analog input 5 I2C SCL
*/

#include <Wire.h> //I2C Arduino Library

#define address 0x1E //0011110b, I2C 7bit address of HMC5883

void setup(){
  //Initialize Serial and I2C communications
  Serial.begin(56000);
  Wire.begin();
 
  //Put the HMC5883 IC into the correct operating mode
  Wire.beginTransmission(address); //open communication with HMC5883
  Wire.send(0x02); //select mode register
  Wire.send(0x00); //continuous measurement mode
  Wire.endTransmission();
}

void loop(){
 
  int x,y,z; //triple axis data

  //Tell the HMC5883 where to begin reading data
  Wire.beginTransmission(address);
  Wire.send(0x03); //select register 3, X MSB register
  Wire.endTransmission();
 

//Read data from each axis, 2 registers per axis
  Wire.requestFrom(address, 6);
  if(6<=Wire.available()){
    x = Wire.receive()<<8; //X msb
    x |= Wire.receive(); //X lsb
    z = Wire.receive()<<8; //Z msb
    z |= Wire.receive(); //Z lsb
    y = Wire.receive()<<8; //Y msb
    y |= Wire.receive(); //Y lsb
  }
 
  //Print out values of each axis
  Serial.print("X ");
  Serial.print(x);
  Serial.print(" ");
  Serial.print("Y ");
  Serial.print(y);
  Serial.print(" ");
  Serial.print("Z ");
  Serial.print(z);
  Serial.print(" ");
  Serial.println();
 
  delay(10);
}



and this

Accelerometer >

Code: [Select]
#include <Wire.h>

#define DEVICE (0x53)    //ADXL345 device address
#define TO_READ (6)        //num of bytes we are going to read each time (two bytes for each axis)

byte buff[TO_READ] ;    //6 bytes buffer for saving data read from the device
char str[512];                      //string buffer to transform data before sending it to the serial port

void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
 
  //Turning on the ADXL345
  writeTo(DEVICE, 0x2D, 0);     
  writeTo(DEVICE, 0x2D, 16);
  writeTo(DEVICE, 0x2D, 8);
}

void loop()
{
  int regAddress = 0x32;    //first axis-acceleration-data register on the ADXL345
  int x, y, z;
 
  readFrom(DEVICE, regAddress, TO_READ, buff); //read the acceleration data from the ADXL345
 
   //each axis reading comes in 10 bit resolution, ie 2 bytes.  Least Significat Byte first!!
   //thus we are converting both bytes in to one int
  x = (((int)buff[1]) << 8) | buff[0];   
  y = (((int)buff[3])<< 8) | buff[2];
  z = (((int)buff[5]) << 8) | buff[4];
 
  //we send the x y z values as a string to the serial port
  sprintf(str, "%d %d %d", x, y, z); 
  Serial.print(str);
  Serial.print(10, BYTE);
 
  //It appears that delay is needed in order not to clog the port
  delay(15);
}

//---------------- Functions
//Writes val to address register on device
void writeTo(int device, byte address, byte val) {
   Wire.beginTransmission(device); //start transmission to device
   Wire.send(address);        // send register address
   Wire.send(val);        // send value to write
   Wire.endTransmission(); //end transmission
}

//reads num bytes starting from address register on device in to buff array
void readFrom(int device, byte address, int num, byte buff[]) {
  Wire.beginTransmission(device); //start transmission to device
  Wire.send(address);        //sends address to read from
  Wire.endTransmission(); //end transmission
 
  Wire.beginTransmission(device); //start transmission to device
  Wire.requestFrom(device, num);    // request 6 bytes from device
 
  int i = 0;
  while(Wire.available())    //device may send less than requested (abnormal)
  {
    buff[i] = Wire.receive(); // receive a byte
    i++;
  }
  Wire.endTransmission(); //end transmission
}



Can anybody help me to mix those 2 sketchs at the same time, or to understand the code from rcgroups to read all the values at the same time ?

thanks

Erdin

I read that the ITG3200 and the ITG3205 can be used the same way.
If they are alike, you can use the libraries by Jeff Rowberg, http://www.i2cdevlib.com/
I'm sure his libraries will work together.

AndresC4

I got it working!


Code: [Select]

#include "Wire.h"

#include "I2Cdev.h"
#include "ADXL345.h"
#include "HMC5883L.h"
#include "ITG3200.h"

HMC5883L mag;
ITG3200 gyro;

int16_t mx, my, mz;
int16_t gx, gy, gz;


// class default I2C address is 0x53
// specific I2C addresses may be passed as a parameter here
// ALT low = 0x53 (default for SparkFun 6DOF board)
// ALT high = 0x1D
ADXL345 accel;

int16_t ax, ay, az;

#define LED_PIN 13 // (Arduino is 13, Teensy is 6)
bool blinkState = false;

void setup() {
    // join I2C bus (I2Cdev library doesn't do this automatically)
    Wire.begin();

    // initialize serial communication
    // (38400 chosen because it works as well at 8MHz as it does at 16MHz, but
    // it's really up to you depending on your project)
    Serial.begin(14400);

    // initialize device
    Serial.println("Initializing I2C devices...");
    accel.initialize();

    // verify connection
    Serial.println("Testing device connections...");
    Serial.println(accel.testConnection() ? "ADXL345 connection successful" : "ADXL345 connection failed");

    // configure LED for output
    pinMode(LED_PIN, OUTPUT);
        mag.initialize();
            gyro.initialize();

          Serial.println("Testing device connections...");
    Serial.println(mag.testConnection() ? "HMC5883L connection successful" : "HMC5883L connection failed");

}

void loop() {
    // read raw accel measurements from device
    accel.getAcceleration(&ax, &ay, &az);
        mag.getHeading(&mx, &my, &mz);
            gyro.getRotation(&gx, &gy, &gz);

    //Serial.print(az);
    // display tab-separated accel x/y/z values
    Serial.print("accelga ");
    Serial.print(ax); Serial.print(" ");
    Serial.print(ay); Serial.print(" ");
    Serial.print(az); Serial.print(" ");
   
    Serial.print("magenta ");
    Serial.print(mx); Serial.print(" ");
    Serial.print(my); Serial.print(" ");
    Serial.print(mz); Serial.print(" ");
   
    Serial.print("gyroska ");
    Serial.print(gx); Serial.print(" ");
    Serial.print(gy); Serial.print(" ");
    Serial.print(az); Serial.print(" ");
    Serial.println();
    delay(10);

    // blink LED to indicate activity
    blinkState = !blinkState;
    digitalWrite(LED_PIN, blinkState);
}


thank you Erdin

Samuel_A

Tried out your code using the GY-85 IMU. But there seems to be an error while compiling. Even when using the examples from the I2Cdev library I get the following error messages (using Arduino 1.0.5):

ADXL345_raw

D:\Arduino\libraries\I2Cdev\I2Cdev.cpp: In static member function 'static int8_t I2Cdev::readBytes(bool, uint8_t, uint8_t, uint8_t, uint8_t*, uint16_t)':
D:\Arduino\libraries\I2Cdev\I2Cdev.cpp:217: error: 'SPI' was not declared in this scope
D:\Arduino\libraries\I2Cdev\I2Cdev.cpp: In static member function 'static int8_t I2Cdev::readWords(bool, uint8_t, uint8_t, uint8_t, uint16_t*, uint16_t)':
D:\Arduino\libraries\I2Cdev\I2Cdev.cpp:299: error: 'SPI' was not declared in this scope
D:\Arduino\libraries\I2Cdev\I2Cdev.cpp: In static member function 'static bool I2Cdev::writeBytes(bool, uint8_t, uint8_t, uint8_t, uint8_t*)':
D:\Arduino\libraries\I2Cdev\I2Cdev.cpp:488: error: 'SPI' was not declared in this scope
D:\Arduino\libraries\I2Cdev\I2Cdev.cpp: In static member function 'static bool I2Cdev::writeWords(bool, uint8_t, uint8_t, uint8_t, uint16_t*)':
D:\Arduino\libraries\I2Cdev\I2Cdev.cpp:549: error: 'SPI' was not declared in this scope


HMC5883L_raw

D:\Arduino\libraries\I2Cdev\I2Cdev.cpp: In static member function 'static int8_t I2Cdev::readBytes(bool, uint8_t, uint8_t, uint8_t, uint8_t*, uint16_t)':
D:\Arduino\libraries\I2Cdev\I2Cdev.cpp:217: error: 'SPI' was not declared in this scope
D:\Arduino\libraries\I2Cdev\I2Cdev.cpp: In static member function 'static int8_t I2Cdev::readWords(bool, uint8_t, uint8_t, uint8_t, uint16_t*, uint16_t)':
D:\Arduino\libraries\I2Cdev\I2Cdev.cpp:299: error: 'SPI' was not declared in this scope
D:\Arduino\libraries\I2Cdev\I2Cdev.cpp: In static member function 'static bool I2Cdev::writeBytes(bool, uint8_t, uint8_t, uint8_t, uint8_t*)':
D:\Arduino\libraries\I2Cdev\I2Cdev.cpp:488: error: 'SPI' was not declared in this scope
D:\Arduino\libraries\I2Cdev\I2Cdev.cpp: In static member function 'static bool I2Cdev::writeWords(bool, uint8_t, uint8_t, uint8_t, uint16_t*)':
D:\Arduino\libraries\I2Cdev\I2Cdev.cpp:549: error: 'SPI' was not declared in this scope


ITG3200_raw

D:\Arduino\libraries\I2Cdev\I2Cdev.cpp: In static member function 'static int8_t I2Cdev::readBytes(bool, uint8_t, uint8_t, uint8_t, uint8_t*, uint16_t)':
D:\Arduino\libraries\I2Cdev\I2Cdev.cpp:217: error: 'SPI' was not declared in this scope
D:\Arduino\libraries\I2Cdev\I2Cdev.cpp: In static member function 'static int8_t I2Cdev::readWords(bool, uint8_t, uint8_t, uint8_t, uint16_t*, uint16_t)':
D:\Arduino\libraries\I2Cdev\I2Cdev.cpp:299: error: 'SPI' was not declared in this scope
D:\Arduino\libraries\I2Cdev\I2Cdev.cpp: In static member function 'static bool I2Cdev::writeBytes(bool, uint8_t, uint8_t, uint8_t, uint8_t*)':
D:\Arduino\libraries\I2Cdev\I2Cdev.cpp:488: error: 'SPI' was not declared in this scope
D:\Arduino\libraries\I2Cdev\I2Cdev.cpp: In static member function 'static bool I2Cdev::writeWords(bool, uint8_t, uint8_t, uint8_t, uint16_t*)':
D:\Arduino\libraries\I2Cdev\I2Cdev.cpp:549: error: 'SPI' was not declared in this scope

How can I solve this problem? Did you have the same issues?







coconutdad

I had the exact same error this morning.  What I found is that I had downloaded my version of I2Cdev from freeIMU and it did not match Jeff Rowberg's version.

Compare line 217:

freeIMU:
SPI.transfer(Addr);

Jeff's version:
Serial.print(length, DEC);

As you can see, Jeff's version does not even reference the SPI library on line 217.

After downloading and installing Jeff's version, the project compiled and ran without any issues.

Hope this helps!

p.s. The problem with the freeIMU version is that the SPI object is never instantiated.  The code needs a global object named SPI. 
There should be a line something like:
SPI SPI;//read as objecttype objectname
but this produces another error (SPI is not a known type)  I could not locate the source code for the SPI library to figure out the correct way to instantiated a spi object.

kkgg

hi,

I have a arduino UNO r3 and GY-85, how can I use the same code in

http://www.rcgroups.com/forums/showthread.php?t=1677559

to get the sensor data (ADXL345 and ITG3205), and put them into a log file?

Can anybody help me?

Thanks!!!

Go Up