The I2C protocol is another popular protocol for communicating with sensors and devices.  I2C is more complex and sometimes slower than SPI, but only requires two data lines (and a ground) which is desireable in some situations.  Luckily the MPSSE component of the FT232H can implement the I2C protocol so you can speak to these devices with the FT232H breakout.

To use I2C with the Adafruit Python GPIO library and the FT232H board you'll need to setup your circuit in a special way.  In particular you'll need to tie the D1 and D2 pins together with a jumper wire.  One of the pins will be read by the F232H as an input, and the other pin will be used as an output.  When tied together both these pins form the SDA or data line for I2C.  

The D0 pin alone will be the SCL clock line for I2C.

The second thing you'll need to do with your circuit is add explicit pull-up resistors from SDA & SCL on the FT232H up to 3.3 or 5 volts.  This is necessary because the FT232H does not have pull-up resistors built in to these lines as it is a very general purpose chip.  I recommend using 4.7 kilo-ohm resistors as these pull-ups.

To summarize, for using I2C you need to setup your hardware as follows:

  • Connect FT232H D1 and D2 together with a jumper wire.  This combined connection is the I2C SDA data line.
  • Add a 4.7 kilo-ohm resistor from the I2C SDA data line (pins D1 and D2 above) up to FT232H 5V.
  • Add a 4.7 kilo-ohm resistor from FT232H D0 up to FT232H 5V.  This pin D0 is the I2C SCL clock line.

Software Usage

To use I2C with the Adafruit Python GPIO library you'll need to create an Adafruit_FT232.I2CDevice instance.  This object takes as a parameter to its initializer the FT232H object that represents your FT232H chip, and the address of the I2C device to communicate with using the chip.  

For example the code below creates an I2C device for a device with address 0x70:

import Adafruit_GPIO.FT232H as FT232H

# Temporarily disable FTDI serial drivers.
FT232H.use_FT232H()

# Find the first FT232H device.
ft232h = FT232H.FT232H()

# Create an I2C device at address 0x70.
i2c = FT232H.I2CDevice(ft232h, 0x70)

At this point the I2CDevice instance is ready for reading and writing simple 8 and 16 bit values from registers.  The interface on the I2CDevice class for reading and writing is exactly the same as the interface on the Raspberry Pi Python I2C code, so you can examine code which is written for the Pi and use it with very few changes on the FT232H.

For example to read a 16 bit register value and write an 8 bit register value to the device the code might look like:

# Read a 16 bit unsigned little endian value from register 0x01.
response = i2c.readU16(0x01)

# Write a 8 bit value 0xAB to register 0x02.
i2c.write8(0x02, 0xAB)

That's all there is to using I2C with the Adafruit Python GPIO library and the FT232H board!

You might also be interested in this tutorial which shows how to use the FT232H breakout with some Adafruit I2C devices that have been ported to use Adafruit's Python GPIO library.

Other I2C Libraries

Note that there are other libraries you might consider using for I2C communication with the FT232H.  You can use libmpsse to speak the I2C protocol from C or Python code.  See this guide on using a color sensor for more information and code to use libmpsse and an I2C device.

Another alternative is the libMPSSE-I2C library that uses the FTDI D2XX drivers.  See this application note for more details on using libMPSSE-I2C.

I2C Device Enumeration

You can run the following script to enumerate all possible I2C devices, kind of like the i2cdetect command on Linux.  The script works by enumerating each possible I2C address (ignoring a few reserved ones) and checking if any device on the bus sends an ACK for the address.

import Adafruit_GPIO.FT232H as FT232H

# Temporarily disable FTDI serial drivers.
FT232H.use_FT232H()

# Find the first FT232H device.
ft232h = FT232H.FT232H()

print 'Scanning all I2C bus addresses...'
# Enumerate all I2C addresses.
for address in range(127):
	# Skip I2C addresses which are reserved.
	if address <= 7 or address >= 120:
		continue
	# Create I2C object.
	i2c = FT232H.I2CDevice(ft232h, address)
	# Check if a device responds to this address.
	if i2c.ping():
		print 'Found I2C device at address 0x{0:02X}'.format(address)
print 'Done!'
Last updated on 2015-05-04 at 04.27.56 PM Published on 2014-11-12 at 01.56.13 PM