I2CDriver is now available from Amazon, in the Excamera Store from Crowd Supply, and from UK distributor Cool Components.

Contents

Getting Started

I2CDriver lets you easily drive I2C devices from any computer. When you first connect it to the USB port, the display blinks white for a moment then shows something like this:

Connect the three sets of colored hookup wires as shown, following the same sequence as on the label:

GND black
VCC red
SDA blue
SCL yellow

The top two signals carry power, the VCC line supplies 3.3 volts.

Across the top of the display I2CDriver continuously measures the USB bus voltage, and the current output.

Software installation

The source for all the I2CDriver software is the repository. Available are:

Installation of the GUI and command-line utilities varies by platform.

Windows

This installer contains the GUI and command-line utilities.

The GUI shortcut is installed on the desktop:

launching it brings up the control window:

If there is only one serial device, the I2CDriver device should be automatically selected. If there is more than one device, select its COM port from the pulldown menu at the top. Once connected, you can select a connected I2C device and write and read data.

The command line utility i2ccl is also installed. For example to display status information:

c:\>"c:\Program Files\Excamera Labs\I2CDriver\i2ccl.exe" COM6 i
uptime 8991  4.957 V  30 mA  25.8 C SDA=1 SCL=1 speed=100 kHz

See below for more information on the command-line syntax.

Linux

For the command-line tool, clone the repository , then do:

cd i2cdriver/c
make -f linux/Makefile
sudo make -f linux/Makefile install
i2ccl /dev/ttyUSB0 i

and you should see something like:

uptime 1651  4.971 V  0 mA  21.2 C SDA=1 SCL=1 speed=100 kHz

MacOS

For the command-line tool, clone the repository , then do:

cd i2cdriver/c
make -f linux/Makefile
sudo make -f linux/Makefile install
i2ccl /dev/cu.usbserial-DO00QS8D i

(substituting your actual I2CDriver's ID for DO00QS8D) and you should see something like:

uptime 1651  4.971 V  5 mA  21.2 C SDA=1 SCL=1 speed=100 kHz

Note that the port to use is /dev/cu.usbserial-XXXXXXXX, as explained here.

Python 2 and 3

The I2CDriver bindings can be installed with pip like this:

pip install i2cdriver

then from Python you can read an LM75B temperature sensor with:

>>> import i2cdriver
>>> i2c = i2cdriver.I2CDriver("/dev/ttyUSB0")   # or something like COM16 for Windows
>>> d=i2cdriver.EDS.Temp(i2c)
>>> d.read()
17.875
>>> d.read()
18.0

You can print a bus scan with:

>>> i2c.scan()
-- -- -- -- -- -- -- --
-- -- -- -- -- -- -- --
-- -- -- -- 1C -- -- --
-- -- -- -- -- -- -- --
-- -- -- -- -- -- -- --
-- -- -- -- -- -- -- --
-- -- -- -- -- -- -- --
-- -- -- -- -- -- -- --
48 -- -- -- -- -- -- --
-- -- -- -- -- -- -- --
-- -- -- -- -- -- -- --
-- -- -- -- -- -- -- --
68 -- -- -- -- -- -- --
-- -- -- -- -- -- -- --
[28, 72, 104]

The Python GUI (which uses wxPython) can be run with:

python i2cgui.py

which depending on your distribution looks something like this:

There are more examples in the samples folder in the repository.

help(i2cdriver) shows the documentation for the module.

C/C++

I2CDriver is contained in a single source file with a single header. Both are in this subdirectory. Usage follows the Python API and is fairly self-explanatory.

The command-line tool i2ccl

i2ccl is the same on all platforms.

The first parameter to the command is the serial port, which depends on your operating system. All following parameters are control commands. These are:

i display status information (uptime, voltage, current, temperature)
d device scan
w dev <bytes> write bytes to I2C device dev
p send a STOP
r dev N read N bytes from I2C device dev, then STOP
m enter I2C bus monitor mode

For example the command:

i2ccl /dev/ttyUSB0 r 0x48 2

reads two bytes from the I2C device at address 0x48. So with an LM75B temperature sensor connected you might see output like:

0x16,0x20

which indicates a temperature of about 22 degrees C.

I2C devices usually have multiple registers. To read register 3 of the LM75B, you first write the register address 3, then read two bytes as before:

i2ccl /dev/ttyUSB0 w 0x48 3 r 0x48 2
0x50,0x00

Which shows that register 3 has the value 0x5000.

The display

The main display on the screen has three sections. The top section is a heat-map showing all 112 legal I2C addresses. Devices that are currently active are white. Inactive devices fade to yellow, purple and finally blue. The middle section is a symbolic interpretation of current I2C traffic. Details on this are below. The bottom two lines show a representation of the SDA (blue) and SCL (yellow) signals.

The symolic decode section shows I2C transactions as they happen. Start and stop are shown as S and P symbols. After a S symbol the address byte is shown, with a right arrow (write) or left arrow (read). There are gray lines connecting the address byte to its heat-map indicator. Following this is a series of data bytes. Each byte is shown in hex, with either a green dot (ACK) or red dot (NACK).

So for example the above sequence is showing

  • Start, write to address 45
  • Write byte 7A
  • Repeated Start, read from address 45
  • Read byte 00
  • Read byte A2
  • Stop

The above sequence is very typical for reading registers from an I2C Device. Note that the final NACK (red dot) is not an error condition, but the standard way of handling the last byte of read transaction.

As a monitor

In monitor mode, the I2CDriver does not write any data to the I2C bus. Instead it monitors bus traffic and draws it on the display. This makes it an ideal tool for troubleshooting and debugging I2C hardware and software.

In monitor mode the mode indicator character in the top-left of the display changes from D to M.

There are several ways of entering monitor mode:

Capture mode

Pull-up resistors

Examples

The Python samples directory contains short examples of using all Electric Dollar Store I2C modules:

Module Function Sample
DIG2 2-digit 7-seg display EDS-DIG2.py
LED RGB LED EDS-LED.py
POT potentiometer EDS-POT.py
BEEP Piezo beeper EDS-BEEP.py
REMOTE IR remote receiver EDS-REMOTE.py
EPROM CAT24C512 64 Kbyte EPROM EDS-EPROM.py
MAGNET LIS3MDL magnetometer EDS-MAGNET.py
TEMP LM75B temperature sensor EDS-TEMP.py
ACCEL RT3000C Accelerometer EDS-ACCEL.py
CLOCK HT1382 real-time clock EDS-CLOCK.py

All demos and applications are run the same way, supplying the I2CDriver on the command-line. For example:

python EDS-LED.py COM16

Also included are some small applications which demonstrate combinations of modules:

Color Compass

Source code: EDS-color-compass.py

Color compass uses MAGNET and LED, reading the current magnetic field direction and rendering it as a color on the LED. As you twist the module, the color changes. For example there is a particular direction for pure red, as well as all other colors. The code reads the magnetic field direction, scales the values to 0-255, and sets the LED color.

Egg Timer

Source code: EDS-egg-timer.py

The demo uses POT, DIG2 and BEEPER to make a simple kitchen egg timer. Twisting the POT sets a countdown time in seconds, and after it's released the ticker starts counting. When it reaches "00" it flashes and beeps.

Take-a-ticket

Source code: EDS-take-a-ticket.py

This demo runs a take-a-ticket display for a store or deli counter, using REMOTE, DIG2 and BEEP modules. It shows 2-digit "now serving" number, and each time '+' is pressed on the remote it increments the counter and makes a beep, so the next customer can be served. Pressing '-' turns the number back one.

Technical notes

Electrical specifications

I2C speed 100/400 KHz ± 1%
Voltage accuracy 0.01 V
Current accuracy 5 mA
Uptime accuracy 150 ppm
Uptime wrap 31.7 years
Temperature accuracy ± 2 C
Maximum input voltage (SDA, SCL) 5 V
Maximum output current (SDA, SCL) 8 mA
Maximum output current (GND, VCC) 470 mA
Current consumption 25 mA

Port names

The serial port that I2CDriver appears at depends on your operating system.

On Windows, it appears as COM1, COM2, COM3 etc. You can use the Device Manager or the MODE command to display the available ports. This article describes how to set a device to a fixed port.

On Linux, it appears as /dev/ttyUSB0, 1, 2 etc. The actual number depends on the order that devices were added. However it also appears as something like:

/dev/serial/by-id/usb-FTDI_FT230X_Basic_UART_DO00QS8D-if00-port0

Where DO00QS8D is the serial code of the I2CDriver (which is handily printed on the bottom of each I2CDriver). This is longer, of course, but always the same for a given device.

Similarly on Mac OS, it appears as /dev/cu.usbserial-DO00QS8D.

Decreasing the USB latency timer

I2CDriver performance can be increased by setting the USB latency timer to its minimum value of 1 ms. This can increase the speed of two-way I2C traffic by up to 10X.

On Linux do:

setserial /dev/ttyUSB0 low_latency

On Windows and Mac OS follow these instructions.

Temperature sensor

The temperature sensor is located in the on-board EFM8 microcontroller. It is calibrated at manufacture to within 2 C.

Raw protocol

I2CDriver uses a serial protocol to send and receive I2C commands. Connect to the I2CDriver at 1M baud, 8 bits, no parity, 1 stop bit (1000000 8N1).

Because many I2CDriver commands are ASCII, you can control it interactively from any terminal application that can connect at 460800 baud. For example typing u and s toggles the CS line and ? displays the status info.

Commands are:

? transmit status info
e <byte> echo <byte>
   
1 set speed to 100 KHz
4 set speed to 400 KHz
s <addr> send START/addr, return status
0x80-bf read 1-64 bytes, NACK the final byte
0xc0-ff write 1-64 bytes
a <N> read N bytes, ACK every byte
p send STOP
x reset I2C bus
r register read
d scan devices, return 112 status bytes
   
m enter monitor mode
c enter capture mode
b enter bitbang mode
i leave bitmang, return to I2C mode
   
u <byte> set pullup control lines
v start analog voltage measurement
w read voltage measurement result

So for example to send this sequence:

The host should send:

s 0x90 Start write to device 45
0xc0 0x7a Write 1 byte
s 0x91 Start read from device 45
0x80 Read 1 byte
p Stop

The status response is always 80 characters, space padded. For example:

[i2cdriver1 DO01JUOO 000000061 4.971 000 23.8 I 1 1 100 24 ffff                ]

The fields are space-delimited:

i2cdriver1 fixed identifier
serial serial code identifier
uptime I2CDriver uptime 0-999999999, in seconds
voltage USB bus voltage, in volts
current attached device current, in mA
temperature junction temperature, in C
mode current mode, I for I2C, B for bitbang
SDA SDA line state, 0 or 1
SCL SCL line state, 0 or 1
speed I2C bus speed, in KHz
pullups pullup state byte
crc 16-bit CRC of all input and output bytes (CRC-16-CCITT)

The sample confirm.py shows the CRC-16-CCITT calculation.