MCP2221でCircuitPythonのプログラムをPCから直接動かす

FT232HというICでPCをCircuitPython化する方法を記事にしたが、ほぼ同じ事がMCP2221というICを使っても出来る。やってみた。

スポンサーリンク

仕組みと用意するべきもの

MCP2221はUSB接続のプロトコルコンバータで、I2C、UARTとGPIO4本が備わっている。
価格はFT232Hよりもだいぶ安く、IC単体で200円位で売られている。外付け部品は電源周りにコンデンサを取り付ける程度なので、ブレッドボードで使う場合はブレイクアウトボードではなくDIPタイプの単体ICを買えば十分だろう。

USB⇔シリアル変換IC MCP2221A−I/P: 半導体(モジュール) 秋月電子通商-電子部品・ネット通販
電子部品,通販,販売,半導体,IC,マイコン,電子工作USB⇔シリアル変換IC MCP2221A−I/P秋月電子通商電子部品通信販売

PCのCircuitPython化は、FT232Hの場合と同様、BlinkaというPythonライブラリがMCP2221を介してI2CやGPIOなどの制御を行うことで実現する。

BlinkaOnMCP2221

ドライバ類のインストール

例によってセットアップ方法がAdafruit社の解説記事に詳しく書かれている。

以下、それぞれのOSで実際に行ったことのメモ書き。

Windows10

  • 以下を実行してhidapiをインストールする。が、既にインストール済みと言われた(FT232HのBlinkaセットアップでインストールされた?)
pip install hidapi

Linux(Ubuntu20.04)

  • 一般ユーザでデバイスが見えるようにするためにudevルールを追加する。/etc/udev/rules.d/99-mcp2221.rulesを作成し、以下の一行を書き込む。
SUBSYSTEM=="usb", ATTRS{idVendor}=="04d8", ATTR{idProduct}=="00dd", MODE="0666"
  • ネイティブドライバの無効化。以下のコマンドを実行。
sudo rmmod hid_mcp2221
  • ネイティブドライバを起動時に読み込まないようにさせるため、/etc/modprobe.d/blacklist.confに以下の一行を追加
blacklist hid_mcp2221
  • hidapiのインストール(Windowsとは異なり、こちらはインストールが必要だった)
pip install hidapi

Blinkaのインストール

pipコマンド一発でOKの筈(FT232H用に既にインストール済みなので、推測)

pip install adafruit-blinka

環境変数の設定

Blinkaは自動でMCP2221を検出することはしてくれないので、環境変数の設定が必要。(FT232H用の環境変数がセットされているとエラーになるので注意)

Windowsコマンドプロンプトの場合

set BLINKA_MCP2221=1

Windows Power Shellの場合

$env:BLINKA_MCP2221=1

Linux(bash)の場合

export BLINKA_MCP2221=1

これに加えて、手元の環境ではBLINKA_MCP2221_RESET_DELAYの設定も必要だった。設定すべき値も環境依存の模様。

export BLINKA_MCP2221_RESET_DELAY=3

MCP2221の周辺配線とピンアサイン

単体ICの最低限の周辺配線は以下のような物。
電源周りにコンデンサを取り付ける必要がある。

MCP2221周辺回路

MCP2221のICピン名とCircuitPythonでの定義名の関係、および機能は下の表の通り。

ICピンCircuitPython定義機能
GP0G0デジタルIOのみ
GP1G1デジタルIO、ADC
GP2G2デジタルIO、ADC、DAC
GP3G3デジタルIO、ADC、DAC
SCLSCLI2Cクロック
SDASDAI2Cデータ

Blinkaの動作チェック

Blinkaをインストールし、環境変数を設定したらPC側の準備は完了。MCP2221に最低限の配線を行ってPCにUSB接続したら、Pythonの対話モードから以下を実行する。

import board
board.board_id

board.board_idの値として’MICROCHIP_MCP2221’が返ってきたらBlinkaは正常動作している。

$ python
Python 3.8.10 (default, Mar 15 2022, 12:22:08) 
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import board
>>> board.board_id
'MICROCHIP_MCP2221'
>>> 

テストがてらデジタル電圧計にしてみる

MCP2221にはADCが付いており、電圧測定が可能。

ここのところCPythonのCicruitPython化というお題で似たような記事を何度か書いており(ラズパイLinux編FT232H編)、動作チェックと言えばLチカとかSSD1306の簡易テストばかりでつまらないので、今回は電圧計を作ってみた。

ただMCP2221を使って電圧測定を行うには内蔵の基準電圧を有効化する設定が必要。少々込み入っているので、その設定方法は別記事にまとめた。

MCP2221内蔵ADCで測定した電圧をSSD1306ディスプレイに表示させるPythonコードは以下の通り。PCにインストールされているTrueTypeフォントを使って電圧を大きく表示させている。フォントの指定を変えればWindowsでも動作する。

import time
import os
import busio
from PIL import Image, ImageDraw, ImageFont
import board
from analogio import AnalogIn

import adafruit_ssd1306
i2c = busio.I2C(board.SCL, board.SDA)

adc = AnalogIn(board.G2)
board.pin.mcp2221.adc_configure(0b111)

display = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c)

image = Image.new("1", (display.width, display.height))
draw = ImageDraw.Draw(image)

font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 32)
# font = ImageFont.truetype("C:/Windows/Fonts/msgothic.ttc", 32) # for Windows

while True:
    voltage = (adc.value * 4.096) / 65536

    draw.rectangle([0,0,display.width,display.height], fill=0)
    draw.text((0, 16), " {:4.2f}V".format(voltage), font=font, fill=255)
    display.image(image)
    display.show()
    time.sleep(0.5)

下の写真はMCP2221のGP2とGNDの間にリチウムイオン電池を接続し、リアルタイム電圧測定をした時の様子。同時測定したマルチメーターと殆ど同じ電圧がSSD1306ディスプレイに表示されており、精度はかなり良さそう。

MCP2221電圧計

まとめ

MCP2221はピン数は少ないものの、I2CやデジタルIOだけでなくアナログIOが備わっており、小規模な電子工作実験だったらこれだけで事足りるんじゃないかと思う。なにげにADCが高精度だったり、アナログの精度が良い所も◎。

手軽に使えて十分な機能を備えており、今後出番が増えそうだ。

コメント