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 >
/*
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 >
#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
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.
I got it working!
#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
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?
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.
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!!!