Many sensor chips use the I²C bus, sometimes called TWI or SMBus, for communication. Most microcontrollers support I²C also natively and if not I can be implemented easily in software. Connecting I²C devices to a PC is much more difficult as soldering them onto the mainboard (where a SMBus can be found usually) is not a viable solution. Up to now I usually used a Atmel AVR microcontroller in teamwork with a FT232R (a standard USB↔RS232 converter).
The USB 2.0 successor of the FT232R, the FT232H, has a Multi-Protocol Synchronous Serial Engine (MPSSE) included which is designed to support serial interfaces such as I²C, SPI or JTAG at speeds up to 30 Mbps. This sounded to me as an interesting option to test I²C and SPI devices directly from my PC.
In this post, I want to describe how I connected the FT232H using a UM232H development module to a LM75 temperature sensor and read out the temperature on OS X. I used only the D2XX drivers as the LibMPSSE-I2C is only available for Windows and Linux.
Connecting of the setup is rather easy: To use the UM232H in host-powered mode, we have to connect VIO and 3V3 and USB and 5V0. The LM75 is powered by the 3V3 line and needs also a connection to GND. The I²C clock line is on the LM75 on the SCL pin and on the UM232H on the AD0. The I²C data line is on the LM75 on the SDA pin and on the UM232 on the AD1 and AD2 pin (AD1 handles the output of the data and AD2 the input). Both, the I²C clock line and the I²C data line need a pull-up to 3V3. A value between 1kΩ and 10kΩ is fine for low frequencies (< 100 kHz). The address lines of the LM75 (A0,A1,A2) are all set to 3V3 to this example, resulting in an address of 0x9E for the LM75. On the software side, we need to install the D2XX drivers. Download them and follow the instructions in the ReadMe file to install them. Download my C program lm75.c and compile it with
gcc -lftd2xx -o lm75 lm75.c
If everything worked, a simple
should list all FTDI devices found:
Device 0 Serial Number - FTUBIQVH
Now we can adress the device by its serial number and query it with
and get the temperature of the LM75:
Temperature: 26.0 C
If the query fails, the problem is usually that the virtual comport driver (VCP) is already occupying the device. Try to unload the driver with
sudo kextunload /System/Library/Extensions/FTDIUSBSerialDriver.kext
The code itself should be rather self-explanatory if your familiar with I²C. If not, here's a short overview: The first lines setup the FT232H in MPSSE mode. A list of all the MPSSE commands understood by the FT232H can be found here. The we send a I²C start condition followed by the address of the LM75 with the write bit set and the adress 0x00 (The temperature register, see LM75 datasheet for details). Next is a I²C restart condition followed by the address of the LM75 with the read bit set. Now we can read 2 bytes of data representing the temperature. To finalize the transaction we send an I²C stop condition.
This gets maybe a little clearer when we look at the transaction on the oscilloscope:
The yellow curve is the SCL line and the green curve shows the SDA line. In the upper panel we see the whole transaction consisting of 4 parts: Addressing the LM75 the first time with the write bit set, sending the address 0x00, addressing the LM75 the second time with the read bit set and the 2 data bytes sent by the LM75. The lower panal is a zoom on the first block were the address the LM75 for the first time. We can see the I²C start condition where the SDA goes low while SCL is high and afterwards the clock changes nine times. The first eight cycles transmit the address of the LM75 which is 0x9E or 0b10011110. The last bit is the ACK by the slave.