ESP32 I2CでIOエキスパンダする

  • 2021.10.08
  • I2C
ESP32 I2CでIOエキスパンダする

今回はESP32ペリフェラルのI2Cを使ってIOエキスパンダでLチカしてみます。

この記事は JTAG でデバッグすることを前提にして書いています。
環境構築については こちら をご覧になってください。

投稿時の開発環境を記しておきます。

PC:
Windows10 OS

開発ボード :
ESP32-DevKitCーVE
(Soc : ESP32-D0WD-V3)

デバッガー(H/W):
FT2232D

デバッガー (S/W) :
Visual Studio Code + PlatformIO + ESP-IDF Framework

IOエキスパンダとは

IOポートを拡張するためのデバイスです。
IOエキスパンダと呼ばれるデバイスでいくつかの半導体メーカーでつくられています。

SPIやI2Cのインターフェースでマイコンと接続し、IOポートを拡張することができます。

今回は秋月電子で販売している こちら を使ってみることにしました。

MCP23017はI2Cのインターフェースで16ビットのIOポートを拡張することができ、16ビットそれぞれに対して入出力の選択が可能です。

回路図

デバッグ環境の回路構成に対して以下の回路を追加します。
ESP32の番号はGPIOの番号です。

MCP23017はI2Cのデバイスで、アドレス選択用のピンが3本あります。

これにより、ワンペアのI2C信号で最大 16 × 8 ビットのGPIOを拡張することができます。

I2CのSCLK, SDAの信号はプルアップして使います。ここでは4.7kΩでプルアップしました。

割り込みは使っていません。

RESET端子は回路を簡略化するために3.3Vにつなぎました。

プロジェクトをつくる

VSCodeで使っていたプロジェクトを開いていたら、File – Close Folder して閉じておきます。

その後にVSCodeからPlatformIOをOpenします。

以下の内容でプロジェクトを新規に作成します。

Name : ESP32E-i2c-master
Board : Espressif ESP32 Dev Module
Framework : Espressif IoT Development Framework

Name : ESP32E の “E” は Framework (Espressif IoT Development Framework)の頭文字を示しています。

(後から見てわかるように、ESP-IDFを使うことを明示しています)

次にplatformio.ini に以下の3行を追加して、 Ctrl + s で保存しておきます。

COM[4]の4の部分はデバイスマネージャーのポート(COMとLPT)で Silicon Labs CP210x から始まるCOMの番号を記述します。

debug_tool = minimodule
upload_port = COM[4]
monitor_speed = 115200

I2CマスターのAPIリファレンスとサンプル

I2CのAPIは こちら を参照してください。

サンプルプログラムは こちら を参考にしました。

PlatformIOで Eresspsif IoT Development Framework を選択したことにより、以下のローカルフォルダからも参照可能なはずです。

C:\Users\xxxxx\.platformio\packages\framework-espidf\examples\peripherals\i2c\i2c_self_test

(xxxxxは皆さまのユーザー名)

動作概要

I2C

I2CはSPIに比べると低速です。

テクニカルリファレンスマニュアルの4.IO_MUXの項目を見ると、DirectI/O(first signal)の部分にI2Cはありません。

ということでIO_MUXは気にせずに、GPIOを適当に選んで使いました。(回路図を参照)

まぁI2Cは遅いですからね、全く問題ナシ。。

SPIのGPIO Matrix and IO_MUX によると、

IO_MUX : max. 80MHz
GPIO Matrix : max. 40MHz

だそうです。

クロックはI2Cとしては速からず遅からずの400kHzで動かしてみることにしました。

概要からは見つけられなかったのですが、I2Cは0と1の2つが存在するようです。
(レジスタの説明に 0 と 1 の記述がある)

今回は0を使ってみます。そして以下のようにGPIOを割り当ててみました。

(数値はGPIOの番号)

SDA=2
SCLK=0

I2Cの挙動としては、

(1)ハードウェアアドレス+レジスタアドレス+書き込みデータ
(2)ハードウェアアドレス+レジスタアドレス+読み込みデータ(リスタートを含む)

の2パターンのみが動きます。

このデバイスでは、これで充分なのでそれ以外の動作は確認していません。

(例えば連続した複数データの読み書き等)

実際には 400KHz 出ていませんでした。360kHz程度でしょうか。。
観測した波形を貼っておきます。

(1)GPIOAへの書き込みの後、GPIOBを読み、GPIOBへの書き込み

(2)GPIOAへの書き込み(詳細)

(3)クロック波形の確認用

IOエキスパンダ MCP23017

詳細については こちら を参照してください。

16ビットのIOポートを入力または出力ポートに設定して使うことができます。

やることはSPIの時と同じでインターフェースがかわるだけです。

GPIOAは全てのビットを出力に設定します。
GPIOBはD7ビットだけを入力にして、それ以外は出力に設定します。
MCP23017にコマンドを書き込むことで内部でプルアップするのでGPIOBのD7ビットに外付けの抵抗は不要です。
(MCP23017の内部プルアップは100kΩなのでノイズには弱いかも知れませんが・・・)

GPIOA0につながっているLED(D2) はタイマーでLチカします。
GPIOB0につながっているLED(D1) は GPIOB7 をGNDにつなぐと点灯します。

ソースコードを github esp32e-i2c-master-mcp23017 におきました。

( 環境: VSCode + PlatformIO , Espressif IoT Development Framework )

ESP-IDE環境で SPI MCP23017 を試してみたい方は参考になさってください。

参考というほど、できの良いものではありませんけれど (^_^)

I2Cカテゴリの最新記事