🐥

Pro MicroでI2Cを動かす (2) - I2Cで接続

2024/05/25に公開

シリーズ2つ目のこの記事では、I2Cの基礎とPro Microでの利用をみてゆきます。

I2Cの基礎

本当はI²C(アイスクエアドシー)ですが、面倒なのでI2Cと呼ばれています。

クロック信号(SCL)とデータ信号(SDA)の2本を使い、各ICでそれぞれ接続するだけで通信ができます。拡張性の必要なシステムに良さそうな規格。互換性のある上位版のI3Cもあるらしいです。


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

繋がれたデバイスを操作するICをマスター、繋がれた機器たちをスレーブと呼ばれ、1:多で処理するのが一般的です。

規格の詳細はこちら: https://www.nxp.com/docs/ja/user-guide/UM10204.pdf

通信速度と規格

通信速度は繋がっているデバイスたちがどのI2C規格に対応しているか、および回路の設計に依存します。


引用: https://en.wikipedia.org/wiki/I²C

I2C規格の中でも、規格によってはだいぶ別物になります。通信速度が遅いと制約がゆるいですが、徐々に厳しくなっていき、Ultara-fast modeに至っては単方向通信になります。

Pro Micro (ATmega32U4) はFast modeの400kbit/sや1Mbit/sに対応しているように見えます(要出典)。自作キーボード用途ではおそらく400kbit/sあれば何とかなると思われるので、ここからは制約もゆるいFast modeでの対応を考えてゆきます。

接続方法

SCL, SDAをそれぞれ繋ぐだけで通信ができます。デイジーチェーン、つまり1つのICからさらにケーブルを伸ばして別のICに繋ぐということも可能です。ここで重要なのが、適切な大きさのプルアップ抵抗を挟む必要がある、ということです。

Fast modeでは、立ち上がり時間(lowからhighに変化する時間)は300nsが最大となっています(参考)。これを満たすように抵抗を置くのですが、計算が中々大変です。要は大きすぎてもだめ。小さすぎてもだめ。しかもケーブル、デバイスに依存します。最大静電容量は400pFですが、これは大体3-4mくらいの(一般的な)ケーブルに相当しそうです(参考)。難しいので計算サイトを使いました。便利。

I2Cバスプルアップ抵抗の計算 keisan.casio.jp

試しに計算すると、下図のようになります。大きめの350pFを見積もるとだいぶギリギリで、1kΩがピッタリだと分かります。長いケーブルを想定している場合、1kΩを置いておくと良さそうです。消費電力は増えるので、短い場合は大きな抵抗で良いです(要計算)。


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

通信方法

マスターからアドレスを指定して送受信します。そのため、事前にスレーブ機器のアドレスを知っておく必要があります。繋がっている機器のアドレスをスキャンするプログラムも書けるので、初期化タイミングでいい感じに処理するのが良さそうです。プログラム作成の時点で詳しく見てゆきます。

規格上、アドレスは7bit使えます。そのため理論上は2^7=128機器に対応しています。が、色々な方法で制限されたり増やしたりされます。これも後述します。

今回使うI2Cモジュール

世の中には色々なI2C対応モジュールがありますが、今回はピンを増やしてくれるIO エキスパンダーに活躍してもらいます。

IOエキスパンダーは、IOピンを拡張するためのICです。Pro Microは18個ほど汎用ピンを持っていますが、もっとたくさん欲しい時にもってこいです。

今回使用するのはMCP23017秋月で190円)で16bit(16ピン)増やせます。ただし、アドレスは3ビットしか設定できず、上位4bitは固定されています(0x20-0x27)。そのため普通に繋ぐと8個が頭打ちになります。

MCP23017はI/Oピンに内部プルアップ抵抗を使うことができます。自分で用意しなくて良いので楽ですが、100kΩと弱いので自分で付けるケースも多いようです。

用意するパーツ

ここからはブレッドボード上で実際に動かしてみましょう。まず1つ繋いで動くか見てみましょう。動作確認には、適当なピンにスイッチを繋いで、押して反応するかを見ることとします。

今回は1kΩの抵抗でプルアップしたI2C通信をして、MCP23017が動作するかを確認します。

第1回で使用したパーツは、既に持っているものとします。一応後述して必要なパーツを概観できるようにします。

  • MCP23017 x1
  • 1kΩの抵抗x2
  • ブレッドボード(BB-801など)x1
    • ブレッドボードを分けたい場合。1つで収まる場合はそれでも良い

第一回で使ったもの

配線

何度も見ることになるPro Microのピンアサインを確認して、SCL/SDAをチェックします。


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

MCP23017のデータシートも見つつ、どのピンにどれを挿すかを決めます。SCLとSDAの位置を間違えがちなので注意します。他にはMCP23017のGPB0(1ピン)にテスト用スイッチを繋げ、VCCとGNDを繋げ、#RSTにVCCを繋ぐなどの定型作業をしたら完了です。今回、アドレスはすべてlowにし、0x20にします。


実績: I2Cデバイスを一つ繋いだ

データシートの詳細は次回の記事で見てゆきます。

プログラム作成(I2C Scanner編)

I2Cを使う場合、セットアップ時点でどの機器が繋がっているかを確認し、それに対して処理を行います。

まずは、簡単に接続ができているかどうかだけ確認してみましょう。このような時に便利な I2C Scanner というプログラムがあります。コピペして実行してみましょう。

Arduino Playground - I2cScanner playground.arduino.cc

上手くいくと、次のような表示がSerial Monitorに出てきます。アドレスの配線をパチパチ変えて、表示が変わるかも確認してみましょう。

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

デバイスをちゃんと認識しない場合は、#RESETとアドレスx3がちゃんと配線されているかを疑いましょう。

また、I2C Scannerは今後デバッグに頻繁に使うので、メモしておくと良いでしょう。

まとめ

ちょっと複雑になりましたが、SDAとSCLの2本を繋ぐだけで色々なデバイスと通信ができるのは非常に便利ですね。

次回は、繋いだデバイスの入力を受け取ってみましょう。

Discussion