i2c imu fusion board ardupilot mega not working

Hi,
We have this simple code for interfacing the sparkfun imu 3000 fusion board @ http://www.sparkfun.com/products/10252 and the ardupilot mega @http://www.sparkfun.com/products/9710
we’ve tried a bunch of code… this being the simplest of the lot… (which we got from the arduino forums)… but it doesnt work for us.
keep getting 2 for wire.endTransmission which means a nack is received…

the hardware setup is simply
IMU Fusion Board Ardu Mega Pilot

Vcc pe6/+5v
gnd gnd/(49)
sda sda/pd4
scl scl/pl7/(24)

and the whole thing is powered through usb … please help we’ve been stuck on this for atleast a month…

#include <Wire.h>

void setup (){  
  Serial.begin(9600);
  Wire.begin();
}
void loop (){  
  byte value = 34;
  int result = 5;  
  byte IMU_address = B1101000; //address of IMU, LSB can be 0 or 1 so I've tried both
            //also tried it as an unsigned char
  
  Wire.beginTransmission(IMU_address);
  Wire.send(0x00);  // i wanna read the first register, also tried others

Serial.println(" sent the address..."); //prints successfully

result = Wire.endTransmission(); // this is where it hangs up, doesn't get past here

Serial.println(result, DEC);   //never see this

Wire.requestFrom((int)IMU_address, 1);
while (Wire.available()) {     
  value = Wire.receive();
}
Serial.println(value, BIN); 
Serial.println(value, DEC);
Serial.println(value, HEX);
Serial.print("  that is your id number  ");
delay(3000);
}

just incase... it sorta works now .. atleast the initialization part.. all we did was change the addresses from hex to binary

So, have you even dreamed of downloading the IMU3000 datasheet?

There is sample code at: http://www.hobbytronics.co.uk/arduino-adxl345-imu3000

It works, though I am not entirely sure what the values are at this point.

I got the same Problem ( Arduino Mega - IMU3000 FUSION). I uploaded the hobbytronics code, but nothing happens. I can read out the accelerometer data directly ( Address 0x53 .....) but the IMU 3000 gives no response. Even if i set an register just for fun and then read it our theres no answer. And I tried the Code with an Arduino FIO too, but nothing happens. Cause you say it works fine maybe my IMU Fusion is broken ????

Do you know that the IMU3000 is a 3.3v part?

Yes, I use the "Logic Level Converter". But same problem with Arduino FIO and that got 3.3V.

I am using an UNO with:

UNO IMU3000
A4 ----> SDA
A5 ----> SLC
3.3V ----> VCC
GND ----> GND

I know I shouldn’t be running at 5V…it works…kinda

Output using modified hobbytronics code: (gyroX, gyroY, gyroZ, accelX, accelY, accelZ, looptime[micros], temp?)

/* IMU Fusion Board - ADXL345 & IMU3000
   Example Arduino Sketch to read the Gyro and Accelerometer Data
  
   Written by www.hobbytronics.co.uk 
   See the latest version at www.hobbytronics.co.uk/arduino-adxl345-imu3000
   08-Apr-2011
   
   Modified by Justin Weber
   12-May-2011
   
*/

#define GYRO 0x68         // gyro I2C address
#define REG_GYRO_X 0x1D   // IMU-3000 Register address for GYRO_XOUT_H
#define REG_TEMP 0x1B     // IMU-3000 Register address for 
#define ACCEL 0x53        // Accel I2c Address
#define ADXL345_POWER_CTL 0x2D

#define PI 3.14159265358979f

char buffer[14];     // Array to store ADC values 
float gyro_x;
float gyro_y;
float gyro_z;
float accel_x;
float accel_y;
float accel_z;
float RwAcc[3];       //normalized accel vector(x,y,z)
float RwGyro[3];      //Gyro data (x,y,z)
float temp;
unsigned long curtime;
unsigned long oldTime=0;
unsigned long newTime;
unsigned long interval;
int i;



#include <Wire.h>

void setup()
{
    Serial.begin(57600); 
    
    Wire.begin();
    // Set Gyro settings
    // Sample Rate 1kHz, Filter Bandwidth 42Hz, Gyro Range 500 d/s 
    writeTo(GYRO, 0x16, 0x0B);       
    //set accel register data address
    writeTo(GYRO, 0x18, 0x32);     
    // set accel i2c slave address
    writeTo(GYRO, 0x14, ACCEL);     
    
    // Set passthrough mode to Accel so we can turn it on
    writeTo(GYRO, 0x3D, 0x08);     
    // set accel power control to 'measure'
    writeTo(ACCEL, ADXL345_POWER_CTL, 8);
    // set accel range to +-2 g, and change accel output to MSB
    writeTo(ACCEL, 0x31, 0x04);
    //cancel pass through to accel, gyro will now read accel for us   
    writeTo(GYRO, 0x3D, 0x28);    

}

// Write a value 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
}

void loop()
{
    // Read the Gyro X, Y and Z and Accel X, Y and Z all through the gyro
    
    // First set the register start address for X on Gyro  
    Wire.beginTransmission(GYRO);
    Wire.send(REG_TEMP); //Register Address TEMP_OUT_H
    Wire.endTransmission();

    // New read the 12 data bytes
    Wire.beginTransmission(GYRO);
    Wire.requestFrom(GYRO,14); // Read 14 bytes
    i = 0;
    while(Wire.available())
    {
        buffer[i] = Wire.receive();
        i++;
    }
    Wire.endTransmission();
    
    //record time
    curtime=micros();
    newTime=curtime;
    interval=newTime-oldTime;
    oldTime=newTime;

    //Combine bytes into integers
    //Temp is in MSB first
    temp = buffer[0] << 16 | buffer[1];
    // Gyro format is MSB first
    gyro_x = buffer[2] << 16 | buffer[3];
    gyro_y = buffer[4] << 16 | buffer[5];
    gyro_z = buffer[6] << 16 | buffer[7];
    // Because of orientation of chips
    // accel y output is in same orientation as gyro x
    // and accel x is gyro -y
    accel_y = buffer[8] << 10 | buffer[9];
    accel_x = buffer[10] << 10 | buffer[11];
    accel_z = buffer[12] << 10 | buffer[13];

   //gyro
   
   //accel vector
   RwAcc[0]=accel_x;
   RwAcc[1]=accel_y;
   RwAcc[2]=accel_z;
   normalize3DVector(RwAcc);
   

    // Print out what we have
    Serial.print(gyro_x);    // echo the number received to screen
    Serial.print(",");
    Serial.print(gyro_y);    // echo the number received to screen
    Serial.print(",");    
    Serial.print(gyro_z);   // echo the number received to screen 
    Serial.print(",");     
    Serial.print(RwAcc[0]);  // echo the number received to screen
    Serial.print(",");
    Serial.print(RwAcc[1]);  // echo the number received to screen
    Serial.print(",");   
    Serial.print(RwAcc[2]);   // echo the number received to screen
    Serial.print(",");
    Serial.print(interval);  // echo time interval
    Serial.print(",");
    Serial.print(temp);     // echo temp

    Serial.println("");     // prints carriage return
    delay(400);             // wait for a second   
}

void normalize3DVector(float* vector){
  static float R;  
  R = sqrt(vector[0]*vector[0] + vector[1]*vector[1] + vector[2]*vector[2]);
  vector[0] /= R;
  vector[1] /= R;  
  vector[2] /= R;  
}

Hi,
i tried every sample code (hobbytronics, varesano …). But no success.
I watched the registers after i set them to a value.
Theres only one Register which gives a constant value of zero.
It’s DLPF_FS (Register 22), even if i set it to another value…
Heres my Code if someone can find a mistake :slight_smile:

#include <Wire.h>
#include “ADXL_345_REGISTER.h”
#include “I2C.h”
#include “IMU_3000_REGISTER.h”
#include “Values.h”
/*****************************

  • IMU 3000
  • Digital Input auf ±2000°/sec
  • → FS_SEL = 3
  • → Scale Factor = 16.4
  • Daten 16 Bit gross
  • Statup Time bei 50ms
  • Temperatur Offset = 35°C
    *****************************/
    #define SCALE_FACTOR 16.4
    #define ANZAHL_BYTE 14
    byte BUFF[14]={
    0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    int cleanBUFF[14]={
    0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    int ERGEBNISSE[7]={
    0, 0, 0, 0, 0, 0, 0};
    float ERGEBNISSE_NACH_UMRECHNUNG[7]={
    0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
    int ADXL_DIREKT[3] = {
    0,0,0};
    int FIFO_ANZAHL = 0;
    byte CHECK_TRANSMISSION[1] = {
    0b00000000};
    void INIT_IMU()
    {
    writeTo(IMU_ADDR,PWR_MGM,PWR_MGM_VALUE);
    readFrom(IMU_ADDR,PWR_MGM,1,CHECK_TRANSMISSION);
    if(PWR_MGM_VALUE == CHECK_TRANSMISSION[0])
    {
    Serial.print(" PWR_MGM OK “);
    }
    else
    {
    Serial.print(” PWR_MGM ERROR “);
    }
    CHECK_TRANSMISSION[0] = 0b00000000;
    writeTo(IMU_ADDR,USER_CTRL,0b00100000);
    readFrom(IMU_ADDR,PWR_MGM,1,CHECK_TRANSMISSION);
    if(PWR_MGM_VALUE == CHECK_TRANSMISSION[0])
    {
    Serial.print(” PWR_MGM OK “);
    }
    else
    {
    Serial.print(” PWR_MGM ERROR “);
    }
    CHECK_TRANSMISSION[0] = 0b00000000;
    INIT_ADXL();
    writeTo(IMU_ADDR,USER_CTRL,USER_CTRL_VALUE);
    readFrom(IMU_ADDR,USER_CTRL,1,CHECK_TRANSMISSION);
    if(USER_CTRL_VALUE == CHECK_TRANSMISSION[0])
    {
    Serial.print(” USER_CTRL OK “);
    }
    else
    {
    Serial.print(” USER_CTRL ERROR ");
    }
    CHECK_TRANSMISSION[0] = 0b00000000;
    writeTo(IMU_ADDR,X_OFFS_USERH,X_OFFS_USERH_VALUE);
    writeTo(IMU_ADDR,X_OFFS_USERL,X_OFFS_USERL_VALUE);
    writeTo(IMU_ADDR,Y_OFFS_USERH,Y_OFFS_USERH_VALUE);
    writeTo(IMU_ADDR,Y_OFFS_USERL,Y_OFFS_USERL_VALUE);
    writeTo(IMU_ADDR,Z_OFFS_USERH,Z_OFFS_USERH_VALUE);
    writeTo(IMU_ADDR,Z_OFFS_USERL,Z_OFFS_USERL_VALUE);

writeTo(IMU_ADDR,FIFO_EN,FIFO_EN_VALUE);
readFrom(IMU_ADDR,FIFO_EN,1,CHECK_TRANSMISSION);
if(FIFO_EN_VALUE == CHECK_TRANSMISSION[0])
{
Serial.print(" FIFO_EN OK “);
}
else
{
Serial.print(” FIFO_EN ERROR “);
}
CHECK_TRANSMISSION[0] = 0b00000000;
writeTo(IMU_ADDR,AUX_VDDIO,AUX_VDDIO_VALUE);
readFrom(IMU_ADDR,AUX_VDDIO,1,CHECK_TRANSMISSION);
if(AUX_VDDIO_VALUE == CHECK_TRANSMISSION[0])
{
Serial.print(” AUX_VDDIO OK “);
}
else
{
Serial.print(” AUX_VDDIO ERROR “);
}
CHECK_TRANSMISSION[0] = 0b00000000;
writeTo(IMU_ADDR,AUX_SLV_ADDR,AUX_SLV_ADDR_VALUE);
readFrom(IMU_ADDR,AUX_SLV_ADDR,1,CHECK_TRANSMISSION);
if(AUX_SLV_ADDR_VALUE == CHECK_TRANSMISSION[0])
{
Serial.print(” AUX_SLV_ADDR OK “);
}
else
{
Serial.print(” AUX_SLV_ADDR ERROR “);
}
CHECK_TRANSMISSION[0] = 0b00000000;
writeTo(IMU_ADDR,SMPLRT_DIV,SMPLRT_DIV_VALUE);
readFrom(IMU_ADDR,SMPLRT_DIV,1,CHECK_TRANSMISSION);
if(SMPLRT_DIV_VALUE == CHECK_TRANSMISSION[0])
{
Serial.print(” SMPLRT_DIV OK “);
}
else
{
Serial.print(” SMPLRT_DIV ERROR ");
}
CHECK_TRANSMISSION[0] = 0b00000000;

writeTo(IMU_ADDR,AUX_BURST_ADDR,AUX_BURST_ADDR_VALUE);
readFrom(IMU_ADDR,AUX_BURST_ADDR,1,CHECK_TRANSMISSION);
if(AUX_BURST_ADDR_VALUE == CHECK_TRANSMISSION[0])
{
Serial.print(" AUX_BURST_ADDR OK “);
}
else
{
Serial.println(” AUX_BURST_ADDR ERROR “);
}
CHECK_TRANSMISSION[0] = 0b00000000;
writeTo(IMU_ADDR,DLPF_FS,DLPF_FS_VALUE);
readFrom(IMU_ADDR,DLPF_FS,1,CHECK_TRANSMISSION);
if(DLPF_FS_VALUE == CHECK_TRANSMISSION[0])
{
Serial.print(” DLPF_FS OK “);
}
else
{
Serial.print(” DLPF_FS ERROR ");
Serial.print(CHECK_TRANSMISSION[0],DEC);
}

}
void INIT_ADXL()
{
writeTo(ADXL_ADDR,POWER_CTL,0x00);
writeTo(ADXL_ADDR,POWER_CTL,0x16);
writeTo(ADXL_ADDR,POWER_CTL,POWER_CTL_VALUE);
writeTo(ADXL_ADDR,FIFO_CTL,FIFO_CTL_VALUE);
writeTo(ADXL_ADDR,INT_ENABLE,INT_ENABLE_VALUE);
}

void READ_IMU()
{
readFrom(IMU_ADDR,TEMP_OUT_H,ANZAHL_BYTE,BUFF);

cleanBUFF[0] = ((int)BUFF[0]<<8) & 0b1111111100000000;
cleanBUFF[2] = ((int)BUFF[2]<<8) & 0b1111111100000000;
cleanBUFF[4] = ((int)BUFF[4]<<8) & 0b1111111100000000;
cleanBUFF[6] = ((int)BUFF[6]<<8) & 0b1111111100000000;
cleanBUFF[8] = ((int)BUFF[8]<<8) & 0b1111111100000000;
cleanBUFF[10] = ((int)BUFF[10]<<8) & 0b1111111100000000;
cleanBUFF[12] = ((int)BUFF[12]<<8) & 0b1111111100000000;

cleanBUFF[1] = ((int)BUFF[1]) & 0b0000000011111111;
cleanBUFF[3] = ((int)BUFF[3]) & 0b0000000011111111;
cleanBUFF[5] = ((int)BUFF[5]) & 0b0000000011111111;
cleanBUFF[7] = ((int)BUFF[7]) & 0b0000000011111111;
cleanBUFF[9] = ((int)BUFF[9]) & 0b0000000011111111;
cleanBUFF[11] = ((int)BUFF[11]) & 0b0000000011111111;
cleanBUFF[13] = ((int)BUFF[13]) & 0b0000000011111111;

for(int i = 0; i<13;i++)
{
ERGEBNISSE = cleanBUFF | cleanBUFF[i+1];
* } *
* for(int i = 1;i<4;i++)*
* {*
ERGEBNISSE_NACH_UMRECHNUNG = (float)ERGEBNISSE*/16.4;*
* }*
* for(int i = 4;i<7;i++)*
* {*
ERGEBNISSE_NACH_UMRECHNUNG = (float)ERGEBNISSE*/256.0;*
* }*
}
/void GET_FIFO_COUNT()
_{
byte BUFF[2] = {
0x0,0x0 };
int cleanBUFF[2] = {
0x00,0x00 };_

readFrom(IMU_ADDR,FIFO_COUNTH,2,BUFF);
_ cleanBUFF[0] = ((int)BUFF[0]<<8) & 0b0000001100000000;
cleanBUFF[1] = ((int)BUFF[1]) & 0b0000000011111111;_

FIFO_ANZAHL = cleanBUFF[0] | cleanBUFF[1];
_ Serial.print(" FIFO COUNT : ");_
Serial.println(FIFO_ANZAHL);
_}/
void PRINT_VALUES(float VALUES[])
{
* Serial.print("TEMPERATUR: “);
Serial.print(VALUES[0]);
Serial.print(” GYRO X: “);
Serial.print(VALUES[1]);
Serial.print(” GYRO Y: “);
Serial.print(VALUES[2]);
Serial.print(” GYRO Z: “);
Serial.print(VALUES[3]);
Serial.print(” ACC X: “);
Serial.print(VALUES[4]);
Serial.print(” ACC Y: “);
Serial.print(VALUES[5]);
Serial.print(” ACC Z: ");
Serial.println(VALUES[6]);
}
void READ_ADXL()
{
byte wert[6]={
0,0,0,0,0,0 };_

readFrom(ADXL_ADDR,DATAX0,6,wert);
ADXL_DIREKT[0] = ((int)wert[1]<<8)|(int)wert[0];
ADXL_DIREKT[1] = ((int)wert[3]<<8)|(int)wert[2];
ADXL_DIREKT[2] = ((int)wert[5]<<8)|(int)wert[4];
Serial.print("ADXL_DIREKT[0]: “);
Serial.print(ADXL_DIREKT[0]);
Serial.print(” ADXL_DIREKT[1]: “);
Serial.print(ADXL_DIREKT[1]);
Serial.print(” ADXL_DIREKT[2]: “);
Serial.println(ADXL_DIREKT[2]);
_}
void IMU_TEST()
{
byte IDENTITAET[1] = {
0 };_

readFrom(IMU_ADDR,WHO_AM_I,1,IDENTITAET);
_ Serial.print(” Adresse des Geraets: ");
Serial.println(IDENTITAET[0],DEC);
}
void setup()
{
Serial.begin(57600);
Wire.begin();_

INIT_ADXL(); // Erst den ADXL initialisieren, da IMU danach die Daten ausliest*

* INIT_IMU();
IMU_TEST();
_ delay(50);
}
void loop()
{_

READ_IMU();
//GET_FIFO_COUNT();
READ_ADXL(); //ADXL Direkt funktioniert*

* PRINT_VALUES(ERGEBNISSE_NACH_UMRECHNUNG);
_ delay(50);
}*_