もよいめも

不定期更新ものづくりブログ

【Arduino】MCP23017を新バージョンライブラリで動かす

昔書いたMCP23017を使ってみた記事では、新しいライブラリーに対応できなくなってしまったので、改めてまとめました。


※書きかけです

古い方はこちらから
moyoi-memo.hatenablog.com

ライブラリーの詳細

今回使用する"Adafruit MCP23017 Arduino Library"は、
Adafruit Industries様が作成してくださったものとなります。
いやはや感謝!いつもお世話になっております。
↓Adafruit Industries様の製品は以下から
Adafruit - スイッチサイエンス


機能はざっと以下の通り(ver2.0.2時点)

  • MCP23017MCP23008(16本のGPIOピン+2本の割り込みピン)、MCP23S17(017のISP通信版)、MCP23008(8本のGPIOピン+1本の割り込みピン)、MCP23S08(008のISP通信版)に対応
  • GPIOの書き込み・読み取り(プルアップ可)
  • 最後の割り込みピンの取得
  • 複数のI2cバスに対応
  • GPIOの一括読み込み・書き込み
  • レジスタのアドレスの取得

さて、MCP23017の使い方を改めてまとめていこうと思います。
akizukidenshi.com

新ライブラリーではSPIで通信する「MCP23S17」と、GPIOが8ピンと半分になった簡易版?の「MCP23008」にも対応したみたいなのでいずれは使ってみたいです。
mcp23017はGPIOが0~15+割り込みピンが2つあるので語尾が17でmcp23008はGPIOが0~7+割り込みピンが1つあるので語尾が08なんですかね?
ただ、スペースを削減したい理由がなければ値段もほぼ変わらないし(もはや高い?)、入手性も良くないのでmcp23017を使うのが妥当だと思われます。

まずは1つ動かす

配線

Arduino nanoを使用する場合はA4がSDA、A5がSCLです。

f:id:moyoi:20200313101650p:plain
配線の仕方(画像はデータシートより)


f:id:moyoi:20200314112049p:plain
配線の仕方
MCP23017のGPB0をタクトスイッチに、GPA7のLEDをつなぎます。LEDの電流制限用抵抗は330~1kぐらいを選定してつないでください。

ちなみにプログラム上のピンの番号はこちら

GPB0 8 GPA7 7
GPB1 9 GPA6 6
GPB2 10 GPA5 5
GPB3 11 GPA4 4
GPB4 12 GPA3 3
GPB5 13 GPA2 2
GPB6 14 GPA1 1
GPB7 15 GPA0 0

プログラム

こちらからライブラリーをZIP形式でダウンロードします。
github.com
そして、Arduino ideのメニューのスケッチ→ライブラリーをインクルード→zip形式のファイルをインストールからダウンロードしたファイルを選択します。ソフトを再起動させれば導入は完了です。
プログラムはこれ↓

#include <Adafruit_MCP23X17.h>

Adafruit_MCP23X17 mcp;

void setup() {
  mcp.begin_I2C(0x20);//ちなみに接続エラーになるとfalseが戻り値として読み取れます。
  mcp.pinMode(7, OUTPUT); //GP7を出力ピンに
  mcp.pinMode(8, INPUT_PULLUP); //GP0をプルアップで入力ピンに
}

void loop() {
  if (mcp.digitalRead(8) == LOW) {
    mcp.digitalWrite(7, HIGH);
  } else {
    mcp.digitalWrite(7, LOW);
  }
}

複数のMCP23S17を使う

f:id:moyoi:20211026053001p:plain
I2cアドレスの設定

データシートより

データシートを見ると、アドレスの後半3bitをA0~A2で直接設定できるみたいです。
ちなみに0がGND、1が5Vです。

A0 A1 A2 アドレス
0 0 0 0x20
1 0 0 0x21
0 1 0 0x22
1 1 0 0x23
0 0 1 0x24
1 0 1 0x25
0 1 1 0x26
1 1 1 0x27
#include <Adafruit_MCP23X17.h>

#define LEDPIN 13

Adafruit_MCP23X17 mcp1;
Adafruit_MCP23X17 mcp2;

void setup() {
  pinMode(LEDPIN,OUTPUT);
  if(mcp1.begin_I2C(0x20)==false||mcp2.begin_I2C(0x21)==false){
    digitalWrite(LEDPIN,HIGH);
  }else{
    digitalWrite(LEDPIN,LOW);
  }
  
  for (int i = 0; i <= 15; i++) {
    mcp1.pinMode(i, OUTPUT);
    mcp2.pinMode(i, OUTPUT);
  }
}

void loop() {
  for (int i = 8; i <= 15; i++) {
    mcp1.digitalWrite(i, HIGH);
    delay(20);
    mcp1.digitalWrite(i, LOW);
  }
  for (int i = 8; i <= 15; i++) {
    mcp2.digitalWrite(i, HIGH);
    delay(20);
    mcp2.digitalWrite(i, LOW);
  }
  for (int i = 0; i <= 7; i++) {
    mcp2.digitalWrite(i, HIGH);
    delay(20);
    mcp2.digitalWrite(i, LOW);
  }
  for (int i = 0; i <= 7; i++) {
    mcp1.digitalWrite(i, HIGH);
    delay(20);
    mcp1.digitalWrite(i, LOW);
  }
}