7 years, 8 months ago.

Combined I2C ADXL345 and ITG3200 in one package 6DOF

Information update: See latest comment below:-

main.c code:

#include "mbed.h"
#include "TextLCD.h"
#include "ADXL345_I2C.h"
#include "ITG3200.h"

I2C i2c(p9,p10);//p28,p27
Serial pc(USBTX, USBRX);
I2C i2c_lcd(p9,p10); // sda, scl
ADXL345_I2C accelerometer(p9, p10); //device i2c DevId 
ITG3200 gyro(p9, p10);
TextLCD_I2C lcd(&i2c_lcd, 0x4E, TextLCD::LCD20x4); // I2C bus, 2004A Slaveaddress 0x4E, LCD Type

//TextLCD Textlcd(&i2c_lcd, 0x4E, TextLCD::LCD20x4);

Timer t;

    
int main() {
   //Set highest bandwidth.
    gyro.setLpBandwidth(LPFBW_42HZ); //was gyro1.seLpBandwidth
    
    int readings[3] = {0, 0, 0};
     
    //pc.printf("Starting ADXL345 test...\n");
    lcd.printf("Starting ADXL 345 test...\n");
    wait(1);
    //pc.printf("Device ID is: 0x%02x\n", accelerometer.getDeviceID());
    lcd.printf("Device ID is: 0x%02X\n", accelerometer.getDeviceID());
    wait(1);
    
     // These are here to test whether any of the initialization fails. It will print the failure
    if (accelerometer.setPowerControl(0x00)){
         //pc.printf("didn't intitialize power control\n");
         lcd.printf("didn't intitialize power control\n");
         return 0;  }
     //Full resolution, +/-16g, 4mg/LSB.
     wait(0.1);
     
     if(accelerometer.setDataFormatControl(0x0B)){
        //pc.printf("didn't set data format\n");
        lcd.printf("didn't set data format\n");
        return 0;  }
     wait(0.1);
     
     //3.2kHz data rate.
     if(accelerometer.setDataRate(ADXL345_3200HZ)){
        //pc.printf("didn't set data rate\n");
        lcd.printf("didn't set data rate\n");
        return 0;    }
     wait(0.1);
     
     //Measurement mode.
     
     if(accelerometer.setPowerControl(MeasurementMode)) {
        //pc.printf("didn't set the power control to measurement\n");
        lcd.printf("didn't set the power control to measurement\n");
        return 0;   } 
 
   lcd.cls();
   lcd.printf("I2CU! Searching for I2C devices...\n");
   lcd.setBacklight(TextLCD::LightOn);
   int count = 0;
    for (int address=0; address<256; address+=1) {
        if (!i2c.write(address, NULL, 0)) { // 0 returned is ok
           lcd.printf(" - I2C device found at address 0x%02X\n", address);
           //device 0x4E is lcd display, device ADXL345 or ITG3200 is 0xA6 or 0xD0 ????
            count++;
            wait(1);
            lcd.cls();
        }
    }
    lcd.printf("%d devices found\n", count); 
     wait(1);
    
    t.start();
    while (1){
     
        wait(0.1);
        accelerometer.getOutput(readings);
        //pc.printf("%i, %i, %i\n", (int16_t)readings[0], (int16_t)readings[1], (int16_t)readings[2]);
              
        lcd.cls();
        lcd.printf("ITG3200 DevID 0x%02X\n",gyro.getWhoAmI()); //was gyro1.getWhoAmI()
        lcd.printf("ADXL DevID is: 0x%02x\n", accelerometer.getDeviceID());
        lcd.printf("Ax%i Ay%i Az%i\n", (int16_t)readings[0], (int16_t)readings[1], (int16_t)readings[2]);
        lcd.printf("Gx%i Gy%i Gz%i\n\r", gyro.getGyroX(), gyro.getGyroY(), gyro.getGyroZ());
        //lcd.printf("Temperature %2.1f \n",gyro.getTemperature());
        wait(1);
               
        }
}


And for some strange reason ADXL345 DevID is now showing 0x01??? and not as before 0x3F???

posted by Derek Calland 07 Mar 2017

Hi Erik, many thanks for all your help and suggestions here but I have this prograam now fully working by changing the ADXL345 I2C file to the library file - developer.mbed.org/users/peterswanson87/code/ADXL345_I2C/ and it works a treat as shown above. The DevID for the ADXL345 is returning 0xE5 and for the ITG3200 0x69. I do have 4K7 pull up resistors from a clamped/regulated 3.3v supply chip. What I want to nw for my own learning curve is examine the two ADXL345 I2C files and find out why this one works and the other has such strange properties. Again many thanks Erik for your helpful suggestions...apologies to frustrate you!

posted by Derek Calland 08 Mar 2017

1 Answer

7 years, 8 months ago.

Quote:

This translates to 0xA6 for a write and a 0xA7 for a read. So why is the program below returning 0xA6?

That program goes in steps of two through all the possible addresses, if you would go in steps of 1 it would return both 0xA6 and 0xA7 as valid address.

Why? As you say 0xA6 is write, 0xA7 is read, so on both addresses the device will respond. The mbed I2C library sets the required LSB value (which is the difference between 0xA6 and 0xA7) automatically depending on if you call the read function or if you call the write function. So it really does not matter which address you use, the mbed library overrides it, and just used the real address bits, and ignores the read/write bit.

Since that read/write bit does not matter anyway for the mbed library, the code you have for finding I2C addresses also skips it, and only returns the value for the write address.

Thanks Erik, I kind of understand your reply and I changed the step to 1 and indeed see 0xA6 and 0xA7 displayed also 0xD0 and xD1 for the ITG3200 device. I think my problem is am I seeing the correct device data registers as the integer values displayed are static if I move the device? Do I need to change any parameters in the ADXL345_I2C.h header file? I am now reading the Device ID using ADXL345_I2C.getDevId(); and it displays 0xc8. Do I need to use the 0x53 address as shown on the datasheet? and if so where?

posted by Derek Calland 07 Mar 2017

The 0x53 and 0xA6 address is exactly the same, just a different convention. 0x53 is based on the assumption that I2C has a 7-bit address, that is shifted one position to the left and a read/write bit is appended. 0xA6 is based on the assumption that I2C has an 8-bit address, where the LSB determines if it is the read or the write address. The 7-bit convention is more often used, but mbed used the 8-bit one. But if you use 0xA6 (or 0xA7), you are using the 0x53 from the datasheet.

And checking it, the DevId should indeed be something else, 0xE5. Could it be that your device simply has a different ID since it is a double die IC?

posted by Erik - 07 Mar 2017

Hi Erik, thanks for all your help here, I've played around with checking register values and my device ID's are the following:

lcd.printf("ITG3200 DevID 0x%02X\n",gyro.getWhoAmI()); //was gyro1.getWhoAmI()
    lcd.printf("ADXL345 DevId 0x%02X\n",ADXL345_I2C.getDevId());

ITG3200 DevID 0x69 ADXL345 DevID 0x3F

But I still have only a static integer value of 12 in Ax, Ay, Az?

posted by Derek Calland 07 Mar 2017

Btw naming your object same as class (ADXL345_I2C) is not something I would do.

Can you do the same as this one: https://developer.mbed.org/teams/Seeed/code/xadow_m0_accelerometer/file/769899f50706/main.cpp. Or just try that program with your pinout, to see if it works.

posted by Erik - 07 Mar 2017

I have now changed the main code to the following. Result is the DevID haschanged again to 0xEB and returns 12 for the three axes. This morning I had the same device plugged into my RaspPi and it works correctly using the ADXL345 from git.hub. So what do I conclude? Try and fix the mbed I2C method for this device as there is clearly something not right somewhere? It's a good test for me to learn. Any further help will be greatly appreciated!

#include "ADXL345_Test_I2C.h"
#include "mbed.h"

Serial pc(USBTX, USBRX);

I2C i2c(p9,p10);//p28,p27
I2C i2c_lcd(p9,p10); // sda, scl

ADXL345_I2C ADXL345_I2C(p9, p10);

int main()
{
    int readings[3] = {0, 0, 0};
 
     
    pc.printf("Starting ADXL345 test...\n");
    pc.printf("Device ID is: 0x%02X\n",ADXL345_I2C.getDevId());
 
    //Go into standby mode to configure the device.
    ADXL345_I2C.setPowerControl(0x00); //accelerometer.setPowerControl(0x00);
 
    //Full resolution, +/-16g, 4mg/LSB.
    ADXL345_I2C.setDataFormatControl(0x0B);  //accelerometer.setDataFormatControl(0x0B);
     
    //3.2kHz data rate.
    ADXL345_I2C.setDataRate(ADXL345_3200HZ);  //accelerometer.setDataRate(ADXL345_3200HZ);
 
    //Measurement mode.
    ADXL345_I2C.setPowerControl(0x08); //accelerometer.setPowerControl(0x08);
 
    while (1) {
        ADXL345_I2C.getOutput(readings);  //accelerometer.getOutput(readings);
        pc.printf("%i, %i, %i\n", (int16_t)readings[0], (int16_t)readings[1], (int16_t)readings[2]);
        
        wait(1);
    }
 
}
posted by Derek Calland 08 Mar 2017

What device ID do you get on your raspberry?

Without access to your hardware this is getting tough. 0xEB is a different one, but still not what you would expect. Some random thoughts in random order:

What if you read back for example DataFormatControl, is it what you set it to be?

Do you have your pull up resistors? Proper power supply? Ground between your device and the mbed shorted?

Does mbed receive an ACK? (the mbed I2C functions return if this happened).

Check with a logic analyzer? If you don't have one, order one from ebay (assuming you are a hobbyist, for professional applications buy the real one), they don't cost shit and are really useful.

posted by Erik - 08 Mar 2017