I2C voltage incompatibility

Hello all.

I am using the Arduino Duemilanove Atmega328 -5V and I want to communicate with the Barometric sensor BMP085 that is powered by 3V.

Is there any way to connect the Atmega with the sensor using the I2C without damaging it?

Your help is appreciated.

Thanks and regards, Manuel Silva

Working on the same problem myself right now. Will post a link.


Hope that helps.

Assuming the BMP085 is not 5v tolerant, one possibility is to run the I2C bus on 3.3v.

The Atmega hardware I2C pins are (according to the datasheet) open-drain when the TWI serial interface is enabled. Therefore, you could connect them to a 3.3v device, and use external pullup resistors to 3.3v.

The catch is that the Wire library enables the internal weak pullup resistors when Wire.begin() is called. I am not sure if this is dangerous for the 3.3v device, but you can edit the twi.c library to remove these lines:

 #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega328P__)
    // activate internal pull-ups for twi
    // as per note from atmega8 manual pg167
    sbi(PORTC, 4);
    sbi(PORTC, 5);
    // activate internal pull-ups for twi
    // as per note from atmega128 manual pg204
    sbi(PORTD, 0);
    sbi(PORTD, 1);

I have tried this, and verified that the I2C lines no longer go to 5v on Wire.begin(), and that communication is possible with a 3.3v I2C device. YMMV.

Hello all.

Thanks for your help and suggestions. I am going to try both of them.

Manuel Silva

Also look for Philips/NXP app note 10441: it has a circuit for doing the level shifting using a couple of inexpensive N-channel FETs.