MicroPython的午睡(137)M5Stack UIFlow2、IO端子数を大幅拡張

Joseph Halfmoon

M5Stackは筐体の側面に各種端子が出ています。結構な数があるようでいて、それぞれの用途を活かして使おうと考えると「単なるGPIO」の数がちょっと足らない感じがしないでもない。そこで今回はIO ExpanderをM5Stackに接続してみました。1チップの接続でなんと16本のGPIO増。最大8チップで128本MAX。

※「MicroPython的午睡」投稿順 Indexはこちら

※M5Stack Grayに書き込んだUIFlow2.0 (Alpha-27)対応のMicroPython処理系とWindowsパソコン上で動作しているThonny 4.0.1で動作確認しています。

MCP23017 IOExpander

マイクロチップ社 MCP23017の製品ページが以下に。

MCP23017

I2Cバスに接続するIO Expanderです。I2Cバス接続なので実質このチップのために1ピンもつぶすことなくGPIO端子を拡張することが可能です(割り込み使いたいときは要るけど。)I2Cアドレス的には0x20から0x27の8個のアドレスにチップを接続可能(アドレスは配線による)なので、最大8個、128本までのGPIO端子まで拡張可能です。入出力の設定はI2C経由で個別端子毎にプログラマブル。I2Cバスの速度の制約をうけますが、単純なIOを追加したいときには非常に使いやすいデバイスじゃないかと思います。またI2Cバスインタフェースなので、ちょっとした回路を工夫すればホストと異なる電源を使うようにすることも可能。なかなかお役立ち。

今回、M5Stackに接続した実験回路は以下のごとし。実験のため、本体の3.3V電源直結で使っています。M5Stack_MCP23017_Schematic

なおこのチップについては、以下の別シリーズにて調べてます。

部品屋根性(32) マイクロチップ MCP23017、IO Expander

今回実験のMicroPythonスクリプト

さて、このチップをMicroPythonで制御することは、以前にラズパイPico上のMicroPythonでやってみています。

MicroPython的午睡(35) ラズパイPico、MCP23017でIO端子数拡張

ラズパイPicoのMicroPythonでやれているので、後はピン設定とか「コマケー話」をちょっとM5Stackに合わせてやれば、即動作するハズ。今回の実験用のスクリプトの動作は以下の通り。

    1. 接続するMCP23017は1チップのみ。I2Cアドレスは0x20番地
    2. まず接続確認を行い、接続がavailableであったら、MCP23017の全端子(ポートAとポートB各8ビット)を出力設定とする
    3. 3秒おきに端子にハイとローを出力。その際、隣り合う端子の出力は必ずハイとローが異なるパターンとする。
# testMCP23017.py
from machine import I2C, Pin
import M5
import time

IOEX0 = 0x20
IOCONA = 0x0A
IOCONB = 0x0B
IODIRA = 0x00
IODIRB = 0x01
GPIOA = 0x12
GPIOB = 0x13
OLATA = 0x14
OLATB = 0x15

device = IOEX0
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=100000)

def isIOEXavailable():
    global i2c
    lis = i2c.scan()
    if IOEX0 in lis:
        return True
    return False

def readByte(i2cADR, regADR):
    global i2c
    bufW = bytes([regADR])
    ackW = i2c.writeto(i2cADR, bufW)
    bufR = bytearray(1)
    ackR = i2c.readfrom_into(i2cADR, bufR)
    return int.from_bytes(bufR, 'little')  

def writeByte(i2cADR, regADR, dat):
    global i2c
    bufW = bytes([regADR, dat])
    ackW = i2c.writeto(i2cADR, bufW)
    return ackW  

def initDevice():
    global device
    writeByte(device, IOCONA, 0x20)
    writeByte(device, IODIRA, 0x00)
    writeByte(device, IODIRB, 0x00)
    writeByte(device, OLATA,  0xFF)
    writeByte(device, OLATB,  0xFF)

def main():
    global i2c, device
    M5.begin()
    print("M5Stack Gray, MCP23017 IO Expander OUTPUT test")
    print("IO Expander is ", end="")
    if not isIOEXavailable():
        print("not available.")
    else:
        print("available.")
        initDevice()
        while True:
            writeByte(device, OLATB,  0xAA)
            writeByte(device, OLATA,  0xAA)
            time.sleep(3)
            writeByte(device, OLATB,  0x55)
            writeByte(device, OLATA,  0x55)
            time.sleep(3)    

if __name__ == "__main__":
    main()
実機実行結果

16本も出力端子があるのに、端っこのポートAの7番と6番のみLEDに接続して点滅を見ています。交互に点滅しておるよ。M5Stack_MCP23017_DUT

端子はゴッソリ増やすことができるようになったので、その先に接続するものが楽しみだな。

MicroPython的午睡(136)M5Stack UIFlow2、DDSの出力周波数設定 へ戻る

MicroPython的午睡(138)M5Stack、MCP23017をIO拡張アダプタ化 へ進む