Skip to content
MichaelMeissner edited this page Sep 9, 2020 · 29 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 a 7-bit 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.
  • The Wire -> Scanner.ino example program lists many of the common I2C addresses used.
  • 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 or the 4.1.
  • 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, 4.0, and 4.1) 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.

  • In some cases, the combined pull-up resistors may prevent you from achieving higher speeds, and you may need to remove the pull-up resistors from a board. If you have a choice of boards, it may be useful to use boards with removable pull-up resistors.

  • 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.

  • According to Paul Stoffregen, you might not need to use a 3.3 volt to 5 volt level converter if:

    • if you have I2C devices that need 5 volts;
    • If the pull-up resistors are 4.7K ohms or higher;
    • You power the I2C bus with 5 volts (VIN); and
    • You have a Teensy that is tolerant of 5 volts on the digital pins (Teensy 3.1, 3.2, or 3.5). Note, the Teensy LC, 3.0, 3.6, 4.0, and 4.1 ARE NOT tolerant of 5 volts, and you can damage your Teensy if you attach a 5 volt I2C device.
  • According to Paul Stoffregen Internal i2c pull-up resistors are enabled for the Teensy 4.0/4.1. These resistors should be strong enough for the basic I2C, but you may need external pull-resistors for faster speeds. You still need pull-up resistors for the Teensy LC, 3.1, 3.2, 3.5, or 3.6.

  • A lower resistance will charge/discharge the cable's capacitance faster, which results in steeper edges. With the wider pulses of lower frequencies a less steep edge won't influence the pulse's shape as much. Therefore the I2C specification gives maximum values for the pull-up resistors as a function of bus capacitance for three speed classes: The minimum values are defined in function of the bus voltage, and should limit the current through the drivers.

  • The Adafruit Teensy -> feather adapter does not provide pull-up resistors.

  • NXP I2C Specification

Multiple I2C ports

  • Most Teensys 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 and 4.1 have 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).
  • Unfortunately a lot of Arduino I2C device libraries were written on devices that only bring out one I2C bus, so the library doesn't have options to specify a different I2C bus. If you want to use a second or third I2C bus, you might have to clone and rename the device library so that it either has an option to specify the I2C bus or just always uses a specific I2C bus.

I2C speed grades

The I2C buses can run at various speed grades

  • standard mode: 100 kbit/s;
  • full speed: 400 kbit/s;
  • fast mode: 1 mbit/s; (and)
  • high speed: 3,2 Mbit/s

I2C cabling

There are 3 main ways I2C provide cabling:

Open Source Drivers

Some companies such as Adafruit and Sparkfun write various Open Source drivers for the boards that they sell. A lot of times, you can find cheaper clones of the boards out on the internet. Obviously if you buy the branded board, you are helping to fund the creation of the open source drivers, whereas the clone board is cheaper. In addition, the companies can replace the board if it has a manufacturing defect, while with a no-name clone, you might not have any after sale support. You can also go onto the vendor forums and ask questions about how the board works, and perhaps suggest changes to the driver that the driver author might consider. It is a trade-off you need to decide to do when buying these boards.

I2C boards

Some notable I2C boards that exist include:

  • MCP23017: Add up to 16 digital inputs or outputs per board. There are 3 address pins, so you can have up to 8 separate MCP23017 boards on the I2C bus, or 128 digital input/output pins. You can get generic versions of the MCP23017 chipset from other vendors. One driver for the MCP23017 is Adafruit-MCP23017-Arduino-Library.

  • ADS1015: Add up to 4 analog inputs per board (12-bit resolution). You can have up to 4 ADS1015 boards on the I2C bus. The inputs can either be 4 separate inputs, or two differential channels, and you can adjust the gain.. The driver for both the ADS1015 and ADS1115 boards is Adafruit_ADS1X15. The ADS1015 has a higher sample rate than the ADA1115.

  • ADS1115: Add up to 4 analog inputs per board (16-bit resolution). You can have up to 4 ADS1115 boards on the I2C bus. The inputs can either be 4 separate inputs, or two differential channels, and you can adjust the gain.. The driver for both the ADS1015 and ADS1115 boards is Adafruit_ADS1X15. The ADS1115 has a higher resolution than the ADS1015. Note in general, when you get to higher resolutions, you need to be more careful in designing the circuit.

  • OLED 128x64 mono display: If you need a simple monochrome display, the 128x64 OLED displays might fit the bill. The Adafruit board can be either I2C or SPI, depending on whether the solder jumpers are connected or not. The new version of the display now has STEMMA (JST PH) connectors in addition to through hole pins. The Adafruit driver is Adafruit_SSD1306. In addition to the Adafruit branded display, you can find a lot of generic versions of the display out on sites like ebay.

  • OLED 128x32 mono display: This display uses the same driver (Adafruit_SSD1306) as the previous display. Like the previous display, you can buy the Adafruit branded display, or you can buy cheaper clones on the internet.

  • PJRC Prop shield with motion sensors: The PJRC prop shield with motion sensors can allow you to sense various motions using the NXP Motion Sensor Library.

Clone this wiki locally