Moving Forward

Homepage of Andrew Robinson

Manually Controlling Arduino I2C Lines

without comments

Recently I found myself working with a device that requires a pulse on the I2C SDA line to wake it up, before sending the first command. I was interfacing with this device using the Arduino platform to get up and running and found myself at a loss when I dug through the Wire library for a way to manually toggle the line.

It turns out that as long as the Universal Serial engine has control of the I2C bus, there is no way to manually toggle the lines. The solution was to temporarily disable the TWI, toggle the line, and re-enable it. The code to perform this action is as follows:

void wakeSensor() {
  // This command serves as a wakeup to the sensor

  // You'll have the look up the registers for your specific device, but the idea here is simple:
  // 1. Disabled the I2C engine on the AVR
  // 2. Set the Data Direction register to output on the SDA line
  // 3. Toggle the line low for ~1ms to wake the micro up. Enable I2C Engine
  // 4. Wake a millisecond.

  TWCR &= ~(1<<2); // Disable I2C Engine
  DDRC |= (1<<4); // Set PC4 pin to output mode
  PORTC &= ~(1<<4); // Pull pin low
  delay(1);
  PORTC |= (1<<4); // Pull pin high again
  TWCR |= (1<<2); // I2C is now enabled
  delay(1);
}

Hopefully someone finds this function as useful as I have! It will have to be modified for your specific microcontroller, I’m using an older Duemilanove board so your mileage may vary.

Written by Andrew Robinson

April 3rd, 2011 at 6:14 pm

Posted in Uncategorized

Leave a Reply