Programming two I2C devices to get output at the same time.

Hi.

I have a BMP 180 barometer and a MPU 6050 gyroscope. I connected them with arduino mega 2560 as attached in the picture.

if its not clear:

Barometer with arduino

GND = GND
VCC = 3.3v
SDA = SDA (pin 20)
SCL = SCL (PIN 21)

gyroscope with arduino

GND = GND
VCC = 3.3v
SDA = SDA (pin 20)
SCL = SCL (PIN 21)
INT = PIN 2.

I was successful with coding both separately. I used following code for barometer

```
/*********************************************************
Bosch Pressure Sensor BMP085 / BMP180 readout routine
for the Arduino platform.
 
Compiled by Leo Nutz
www.ALTDuino.de             
**********************************************************/

#include <Wire.h>

#define ADDRESS_SENSOR 0x77                // Sensor address

int16_t  ac1, ac2, ac3, b1, b2, mb, mc, md; // Store sensor PROM values from BMP180
uint16_t ac4, ac5, ac6;                    // Store sensor PROM values from BMP180
// Ultra Low Power      OSS = 0, OSD =  5ms
// Standard              OSS = 1, OSD =  8ms
// High                  OSS = 2, OSD = 14ms
// Ultra High Resolution OSS = 3, OSD = 26ms
const uint8_t oss = 3;                      // Set oversampling setting
const uint8_t osd = 26;                    // with corresponding oversampling delay

float T, P;                                // Set global variables for temperature and pressure

void setup()
{
Wire.begin();                            // Activate I2C

Serial.begin(9600);                      // Set up serial port

init_SENSOR();                            // Initialize baro sensor variables
delay(100);
}

void loop()
{
int32_t b5;

b5 = temperature();                      // Read and calculate temperature (T)

Serial.print("Temperature: ");
Serial.print(T, 2);
Serial.print(" C, ");
Serial.print(1.8 * T + 32.0, 2);
Serial.println(" F");

P = pressure(b5);                        // Read and calculate pressure (P)

Serial.print("Pressure: ");
Serial.print(P, 2);
Serial.print(" mbar, ");
Serial.print(P * 0.0295299830714, 2);
Serial.println(" inHg");
Serial.println("");

delay(500);                              // Delay between each readout

}

/**********************************************
Initialize sensor variables
**********************************************/
void init_SENSOR()
{
ac1 = read_2_bytes(0xAA);
ac2 = read_2_bytes(0xAC);
ac3 = read_2_bytes(0xAE);
ac4 = read_2_bytes(0xB0);
ac5 = read_2_bytes(0xB2);
ac6 = read_2_bytes(0xB4);
b1  = read_2_bytes(0xB6);
b2  = read_2_bytes(0xB8);
mb  = read_2_bytes(0xBA);
mc  = read_2_bytes(0xBC);
md  = read_2_bytes(0xBE);

Serial.println("");
Serial.println("Sensor calibration data:");
Serial.print(F("AC1 = ")); Serial.println(ac1);
Serial.print(F("AC2 = ")); Serial.println(ac2);
Serial.print(F("AC3 = ")); Serial.println(ac3);
Serial.print(F("AC4 = ")); Serial.println(ac4);
Serial.print(F("AC5 = ")); Serial.println(ac5);
Serial.print(F("AC6 = ")); Serial.println(ac6);
Serial.print(F("B1 = "));  Serial.println(b1);
Serial.print(F("B2 = "));  Serial.println(b2);
Serial.print(F("MB = "));  Serial.println(mb);
Serial.print(F("MC = "));  Serial.println(mc);
Serial.print(F("MD = "));  Serial.println(md);
Serial.println("");
}

/**********************************************
Calcualte pressure readings
**********************************************/
float pressure(int32_t b5)
{
int32_t x1, x2, x3, b3, b6, p, UP;
uint32_t b4, b7;

UP = read_pressure();                        // Read raw pressure

b6 = b5 - 4000;
x1 = (b2 * (b6 * b6 >> 12)) >> 11;
x2 = ac2 * b6 >> 11;
x3 = x1 + x2;
b3 = (((ac1 * 4 + x3) << oss) + 2) >> 2;
x1 = ac3 * b6 >> 13;
x2 = (b1 * (b6 * b6 >> 12)) >> 16;
x3 = ((x1 + x2) + 2) >> 2;
b4 = (ac4 * (uint32_t)(x3 + 32768)) >> 15;
b7 = ((uint32_t)UP - b3) * (50000 >> oss);
if(b7 < 0x80000000) { p = (b7 << 1) / b4; } else { p = (b7 / b4) << 1; } // or p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;
x1 = (p >> 8) * (p >> 8);
x1 = (x1 * 3038) >> 16;
x2 = (-7357 * p) >> 16;
return (p + ((x1 + x2 + 3791) >> 4)) / 100.0f; // Return pressure in mbar
}

/**********************************************
Read uncompensated temperature
**********************************************/
int32_t temperature()
{
int32_t x1, x2, b5, UT;

Wire.beginTransmission(ADDRESS_SENSOR); // Start transmission to device
Wire.write(0xf4);                      // Sends register address
Wire.write(0x2e);                      // Write data
Wire.endTransmission();                // End transmission
delay(5);                              // Datasheet suggests 4.5 ms

UT = read_2_bytes(0xf6);                // Read uncompensated TEMPERATURE value

// Calculate true temperature
x1 = (UT - (int32_t)ac6) * (int32_t)ac5 >> 15;
x2 = ((int32_t)mc << 11) / (x1 + (int32_t)md);
b5 = x1 + x2;
T  = (b5 + 8) >> 4;
T = T / 10.0;                          // Temperature in celsius
return b5; 
}

/**********************************************
Read uncompensated pressure value
**********************************************/
int32_t read_pressure()
{
int32_t value;
Wire.beginTransmission(ADDRESS_SENSOR);  // Start transmission to device
Wire.write(0xf4);                        // Sends register address to read from
Wire.write(0x34 + (oss << 6));            // Write data
Wire.endTransmission();                  // SEd transmission
delay(osd);                              // Oversampling setting delay
Wire.beginTransmission(ADDRESS_SENSOR);
Wire.write(0xf6);                        // Register to read
Wire.endTransmission();
Wire.requestFrom(ADDRESS_SENSOR, 3);      // Request three bytes
if(Wire.available() >= 3)
{
  value = (((int32_t)Wire.read() << 16) | ((int32_t)Wire.read() << 8) | ((int32_t)Wire.read())) >> (8 - oss);
}
return value;                            // Return value
}

/**********************************************
Read 1 byte from the BMP sensor
**********************************************/
uint8_t read_1_byte(uint8_t code)
{
uint8_t value;
Wire.beginTransmission(ADDRESS_SENSOR);        // Start transmission to device
Wire.write(code);                              // Sends register address to read from
Wire.endTransmission();                        // End transmission
Wire.requestFrom(ADDRESS_SENSOR, 1);            // Request data for 1 byte to be read
if(Wire.available() >= 1)
{
  value = Wire.read();                          // Get 1 byte of data
}
return value;                                  // Return value
}

/**********************************************
Read 2 bytes from the BMP sensor
*********************************************/
uint16_t read_2_bytes(uint8_t code)
{
uint16_t value;
Wire.beginTransmission(ADDRESS_SENSOR);        // Start transmission to device
Wire.write(code);                              // Sends register address to read from
Wire.endTransmission();                        // End transmission
Wire.requestFrom(ADDRESS_SENSOR, 2);            // Request 2 bytes from device
if(Wire.available() >= 2)
{
  value = (Wire.read() << 8) | Wire.read();    // Get 2 bytes of data
}
return value;                                  // Return value
}

```

I will attach a file with the code i used for the gyroscope.

But what i need to do is code the arduino to get the output values of these two i2c devices at the same time.

Is it possible to use two I2C devices connect to a single arduino and work with both togather?
If Yes Please let me understand how to call them when i need the outputs of them.

Please Help me.

Thank you. :wink:

1---07-12-13(pure).txt (15.9 KB)

Hi Namal

With both devices physically connected as in your diagram, does each program work with its respective device?

The two devices have different I2C addresses. You can see the barometer address in the code you posted:

#define ADDRESS_SENSOR 0x77

The gyroscope address is hidden in the library, but there is a comment about it in the code:

// class default I2C address is 0x68

Since 77 hex is different from 68 hex, the devices will not clash.

EDIT added

You can check the I2C addresses using a scanner program like this:

http://forum.arduino.cc/index.php?topic=197360.0

Regards

Ray

HI Hackscribble,

yes i know they have different addresses. but my problem is how to get the readings in one coding. i am actually trying to do is, building a system to a plane that can auto pilot. so i need to know the height and the gyroscope readings at the same time. :confused:

Hackscribble is it possible that u can guild me with a simple coding to take what ever the readings that those two devices generates?

Thank you for your time that spent to reply me.
:slight_smile: