Skip to content
MichaelMeissner edited this page Mar 16, 2020 · 30 revisions

I2C

  • I2C is a shared bus system that allows multiple devices to be hooked to a microprocessor using short wires.
  • Devices can either be the I2C master or slave.
  • Teensys might have multiple I2C buses, but a lot of the libraries out there assume there is only one I2C bus, because the early AVR 328p based Arduino systems only had one I2C bus.
  • To access the main I2C bus, use the Wire external class. On systems with a second I2C bus, use Wire1 instead of Wire to access the second I2C, and Wire2 to access the third I2C bus.
  • Each I2C slave has an address it listens to. On some devices there are solder pads or pins that allow you to configure which I2C address is used. Other devices have an I2C command that allows you to change the I2C address. Other I2C devices just have a single I2C address.
  • There are I2C multiplexers out there that allow you to connect multiple I2C devices that have the same address. One such multiplexer is the Adafruit TCA9548A board (https://www.adafruit.com/product/2717) that allows you to split an I2C bus into 8 separate I2C buses.
  • An older Arduino I2C tutorial is at: (http://www.gammon.com.au/i2c).
  • I2C has 4 pins: Power, ground, SDA, and SCL.

I2C debugging

Libraries

  • The main I2C library is in #include <Wire.h> (https://www.pjrc.com/teensy/td_libs_Wire.html)
  • An alternative I2C library for Teensy LC & 3.0, 3.1, 3.2, 3.5, and 3.6 is #include <i2c_t3.h> (https://github.com/nox771/i2c_t3)
  • Unfortunately, i2c_t3.h has not yet been ported to the Teensy 4.0.
  • Within a sketch, you can only use either Wire.h or i2c_t3.h. If you call any library that uses Wire.h, you can't use i2c_t3.h without cloning each of the libraries that used Wire.h, renaming the library, and changing Wire.h to i2c_t3.h.

Pull-up resistors

  • On ARM based systems (Teensy LC, 3.0, 3.1, 3.2, 3.5, 3.6, and 4.0) you need to have 2 pull-up resistors on each I2C bus.
  • One resistor goes between the SDA pin and 3.3v power in parallel to the data connection(s).
  • One resistor goes between the SCL pin and 3.3v power in parallel to the data connection(s).
  • On I2C buses that support 5 volts, a common value for the pull-up resistors is 4.7K ohms. On I2C buses that are 3.3 volts only, a common value for the pull-up resistors is 2.2K ohms. However, complex I2C buses can need different values for the resistors.
  • Many I2C devices provide their own pull-up resistors.
  • You can have multiple pull-up resistors on the I2C bus, and generally they will work together. However, having multiple pull-up resistors can mean the devices might not be able to handle faster I2C bus speeds.
  • If you have multiple pull-up resistors on an I2C bus, it is similar to having a single resistor of the sum of each of the resistors on the bus.
  • If no devices have pull-up resistors, I2C requests may hang.
  • Most newer Adafruit and Sparkfun I2C devices provide their own pull-up resistors.
  • For the main I2C bus, there is an example program (Wire -> Scanner) that probes the main I2C bus to see what devices are present. If this example hangs, you need to add pull-up resistors.
  • The Teensy Audio shields and the Teensy Prop shields, each provide 2.2K pull-up resistors on the main I2C bus.
  • The Adafruit Teensy -> feather adapter does not provide pull-up resistors.

Multiple I2C ports

  • Most Teensys can have more than one I2C bus.
  • Some Teensys can use alternate pins for some of the I2C pins. See the Wire.h or i2c_t3.h documentation for more details.
  • All ARM Teensys have the first I2C bus on pins 18/19 (SDA0/SCL0);
  • Teensy 4.0 has 2 additional I2C buses (17/16 are SDA1/SCL1; 25/24 are SDA2/SCL2);
  • Teensy 3.6 has 3 additional I2C buses (38/37 are SDA1/SCL1; 4/3 are SDA2/SCL2; 56/57 are SDA3/SCL3);
  • Teensy 3.5 has 2 additional I2C buses (38/37 are SDA1/SCL1; 4/3 are SDA2/SCL2);
  • Teensy 3.1 and 3.2 have 1 additional I2C bus (30/29 are SDA1/SCL1);
  • Teensy LC has 1 additional I2C bus (23/22 are SDA1/SCL1).

I2C cabling

There are 3 main ways I2C provide cabling:

  • Through hole pins: Many I2C devices provide 4 holes to solder in male/female pin headers or solder wires directly. Some devices provide two sets of holes to allow daisy chaining to connect multiple devices. There is no commonality in terms of order of the 4 pins (power, ground, SCL, and SDA). If you are bringing out custom cables, most devices group the power/ground pins together and the SCL/SDA pins together, so you can bring out 2 sets of 2 pin cables to be able to connect to most devices.
  • JST PH connections (2mm pitch): Adafruit uses 4 pin JST PH connections for many of its I2C devices, and calls it STEMMA. The Grove and Gravity systems also use 4 pin JST PH connectors for various 3/4 pin devices, and the I2C cables use the same order.
  • JST SH connections (1mm pitch): Adafruit uses the 4 pin JST SH connections for the smaller boards, and calls the cabling STEMMA QT. Sparkfun uses the same connector, and calls it QWIIC.
  • Differences: Adafruit has a page that explains the differences between the various cabling system: What is Stemma. There are various cables out there to convert from one system to another.
  • Interrupts: Some devices, such as the MCP23017 and MCP23008 I2C port expanders, provide a fifth pin that allows you to connect the pin to a pin on the Teensy, and it goes high when new data is available. You can attach an interrupt to that pin to be notified when new data is available. This can be used to reduce the amount of busy waiting that the Teensy does. The JST PH and JST SH cabling systems do not provide an interrupt pin.
Clone this wiki locally