i2c

How to disable internal Arduino ATMEGA pullups on SDA and SCL with I2C bus

Last updated on Wed, 2011-12-07 13:50. Originally submitted by fabio on 2011-06-23 00:29.

Wire, the library available in the Arduino apis to communicate with devices on the I2C bus, as of the 022 version of the Arduino IDE, by default enable the internal pullups of the ATMEGA microcontroller.

As all 16MHz ATMEGA runs at 5V this means that with pullups enabled signals will have a 5 volt as logic level. Unfortunately, as many I2C devices runs at 3 Volts and aren't 5Volts tolerant, sending 5V signals to them is clearly a very bad idea. You may shorten your device life or even damage them irreparably.

Posted in:

Overclocking I2C to 800KHz with FreeIMU v0.3

Submitted by fabio on Mon, 2011-04-04 10:53.

I'm having some fun with my new Rigol DS1052E oscilloscope and the brand new FreeIMU v0.3 and it's integrated logic level converter.

I'm using the scope to stress test the I2C logic level converter and I found out that with Arduino and the Wire library hacking the code to overclock I2C to non-standard frequencies is actually extremely simple.

It's just a matter of changing the line

#define TWI_FREQ 100000L

in twi.h and upscale that to whatever you want by changing 100000L into eg 400000L or 800000L.

With FreeIMU v0.3, I've been able to reach the unbelievable speed of 800 KHz. Even at this speed, communication looks extremely stable and reliable. Also the quality of the signals through the logic level converter is still very good.

Of course, as all the sensors on FreeIMU v0.3 aren't designed for such speed, going so fast may actually damage the sensors and "woid your warranty". So, I wouldn't suggest trying this on your boards.

Here is a picture of the SCL signal scoped when running at 800KHz through the logic level converter. Cool!!!

FreeIMU SCL signal scoped when running at 800KHz through the logic level converter

Help me pushing writeTo and ReadFrom into Arduino Wire

Submitted by fabio on Sun, 2011-01-23 17:26.

If you ever worked with I2C in Arduino you probably have seen or have implemented yourself, the following code blocks:

When writing a value to one of the registers of the slave device:

  Wire.beginTransmission(DEVICE_ADDRESS);
  Wire.send(REG_ADDRESS);
  Wire.send(VAL_TO_WRITE);
  Wire.endTransmission();

When reading a value from the register of the slave device:

  Wire.beginTransmission(DEVICE_ADDRESS);
  Wire.send(REG_ADDRESS);
  Wire.endTransmission();
  Wire.beginTransmission(DEVICE_ADDRESS);
  Wire.requestFrom(DEVICE_ADDRESS,NUM_BYTES_TO_READ);

An I2C logic level converter/translator with integrated voltage regulator

Last updated on Mon, 2011-04-04 16:55. Originally submitted by fabio on 2011-01-07 13:20.

When using I2C to interface devices operating at different voltages, for example an Arduino running at 5 Volts and a sensor running at 3.3 Volts, it's usually a best practice to use a logic level converter/translator to translate one logic signal from one voltage to the other and vice versa.

There are devices which will work without problems even without a logic level converter (for example I used the ADXL345, the ITG3200 and the HMC5843 without it) but once you want to get very good precision it may be worth using a logic level converter. Moreover there are many devices which could get damaged if used without one.