header source
my icon
esplo.net
ぷるぷるした直方体
Cover Image for Running I2C on Pro Micro (2) - I2C Connection

Running I2C on Pro Micro (2) - I2C Connection

だいたい15分で読めます

Announcement: A book that greatly expands and revises the content of this article is now available. Please check it out if you want comprehensive information.


In this second article of the series, we'll look at the basics of I2C and its use with Pro Micro.

I2C Basics

It's actually I²C (I-squared-C), but it's commonly called I2C for convenience.

It uses two lines, a clock signal (SCL) and a data signal (SDA), allowing communication by simply connecting each IC. It seems to be a good standard for systems that need expandability. There's also a compatible upper version called I3C.


Source: https://www.rohm.co.jp/electronics-basics/micon/mi_what7

The IC that controls the connected devices is called the master, and the connected devices are called slaves. It's common to process in a 1:many relationship.

For detailed specifications, see here: https://www.nxp.com/docs/ja/user-guide/UM10204.pdf

Communication Speed and Standards

The communication speed depends on which I2C standard the connected devices support and the circuit design.


Source: https://en.wikipedia.org/wiki/I²C

Even within I2C standards, some specifications are quite different. With slower communication speeds, the constraints are looser, but they gradually become stricter, and in Ultra-fast mode, it becomes unidirectional communication.

Pro Micro (ATmega32U4) seems to support Fast mode at 400kbit/s and 1Mbit/s (citation needed). For custom keyboard purposes, 400kbit/s is probably sufficient, so from here on, we'll consider supporting Fast mode, which has looser constraints.

Connection Method

You can communicate just by connecting SCL and SDA respectively. Daisy-chaining, or extending cables from one IC to connect to another IC, is also possible. The important point here is that you need to insert pull-up resistors of appropriate size.

In Fast mode, the rise time (time to change from low to high) has a maximum of 300ns (reference). Resistors need to be placed to meet this, but the calculation is quite complicated. In short, too big is no good, too small is no good. It also depends on the cable and device. The maximum capacitance is 400pF, which seems to correspond to about 3-4m of (typical) cable (reference). Since it's difficult, I used a calculation site. It's convenient.

I2C Bus Pull-up Resistor Calculation keisan.casio.jp

If we try a calculation, it looks like the figure below. Estimating a larger 350pF is quite close, and we can see that 1kΩ is just right. If you're assuming long cables, it's good to place 1kΩ. Since power consumption increases, larger resistances are fine for shorter cases (calculation required).


https://keisan.casio.jp/exec/user/1649986426

Communication Method

The master sends and receives by specifying the address. Therefore, you need to know the address of the slave device in advance. You can also write a program to scan the addresses of connected devices, so it's good to process this nicely at initialization timing. We'll look at this in detail when creating the program.

According to the standard, 7 bits can be used for addresses. Therefore, theoretically, it supports 2^7=128 devices. However, this is restricted or increased in various ways. We'll discuss this later as well.

I2C Module We'll Use This Time

There are various I2C-compatible modules in the world, but this time we'll have an IO expander that increases pins play an active role.

An IO expander is an IC for expanding IO pins. Pro Micro has about 18 general-purpose pins, but it's perfect when you want even more.

This time we'll use MCP23017 (190 yen at Akizuki) which can add 16 bits (16 pins). However, only 3 bits can be set for the address, and the upper 4 bits are fixed (0x20-0x27). Therefore, if you connect normally, it maxes out at 8.

MCP23017 can use internal pull-up resistors for I/O pins. It's convenient because you don't have to prepare them yourself, but since they're weak at 100kΩ, it seems many cases still add their own.

Parts to Prepare

From here, let's actually run it on a breadboard. First, let's connect one and see if it works. For operation confirmation, we'll connect a switch to an appropriate pin and see if it responds when pressed.

This time, we'll perform I2C communication pulled up with a 1kΩ resistor and confirm that MCP23017 operates.

We'll assume you already have the parts used in the first article. I'll list them below to give an overview of the necessary parts.

  • MCP23017 x1
  • 1kΩ resistor x2
  • Breadboard (BB-801 etc.) x1
    • If you want to separate the breadboard. If it fits on one, that's fine too.

What We Used in the First Article

Wiring

Check the Pro Micro pin assignment that you'll see many times and check SCL/SDA.


Source: https://cdn.sparkfun.com/datasheets/Dev/Arduino/Boards/ProMicro16MHzv1.pdf

While looking at the MCP23017 datasheet, decide which pin to insert where. Be careful not to mix up the positions of SCL and SDA. Other than that, connect a test switch to GPB0 (pin 1) of MCP23017, connect VCC and GND, connect #RST to VCC, and other routine work, and it's complete. This time, we'll set all addresses to low, making it 0x20.


Achievement: Connected one I2C device

We'll look at the details of the datasheet in the next article.

Program Creation (I2C Scanner Edition)

When using I2C, you check which devices are connected at the setup point and process them accordingly.

First, let's just check if the connection is working. There's a convenient program called I2C Scanner for such times. Let's copy and paste it and run it.

Arduino Playground - I2cScanner playground.arduino.cc

If it works well, you'll see a display like this in the Serial Monitor. Try changing the address wiring and see if the display changes.

I2C Scanner
Scanning...
I2C device found at address 0x20  !
done

If it doesn't recognize the device properly, suspect whether #RESET and address x3 are properly wired.

Also, since we'll frequently use I2C Scanner for debugging in the future, it's good to make a note of it.

Summary

It's gotten a bit complex, but it's very convenient that you can communicate with various devices just by connecting two lines, SDA and SCL.

Next time, let's try receiving input from the connected device.

Share