1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Adafruit MCP2221A モジュールを使う

Last updated at Posted at 2022-05-16

完全に宣伝のようです。失礼

image.png

これは何?

  • USB 2.0 to I2C/UART Protocol Converter with GPIO というチップです。
  • PCからPythonを使って手軽にIOにアクセスできる,というのがいいですね。
  • ADC/DAC/I2C/UARTも使えます。

セットアップ

わかりやすい解説がありますのでここでは省略します。

実行前に環境変数を確認するのが面倒といえば面倒ですが,それほどでもありません。

要するにCircuitPythonのライブラリーをPC上のPythonから使えるようにして,それを使ってMCP2221Aにアクセスしよう,ということになります。

Pythonでも別のアプローチもあるようです。

MicrochipからWindows用のCLI等も公開されています。

ここでは主に私のMacで,adafruitのガイドに沿って使うことに関して書きます。

ADを読んでlogを書いてみる

PCのストレージを使えるので,心置きなくログを書き出せそうですね。

AD_log.py
import board
from analogio import AnalogIn
import time

AD1 = AnalogIn(board.G1) # 10bit but 16bit comply by CircuitPython

f=open('log.csv','w')
f.write("count,ADC\n")

for i in range(10):
    s=str("%d,%d" % (i, AD1.value>>6))
    print(s)
    f.write(s)
    f.write("\n")
    time.sleep(1)

f.close()

実行例 G1端子を半固定抵抗に接続し,手作業で回しています。

$ python3 AD_log.py
0,0
1,60
2,186
3,333
4,411
5,471
6,600
7,704
8,990
9,1023
$ cat log.csv
count,ADC
0,0
1,60
2,186
3,333
4,411
5,471
6,600
7,704
8,990
9,1023
$

によれば,Note that even though the MCP2221's ADC is only 10 bits, the value is scaled to 16 bits to comply with the CircuitPython API. とのことです。

調べてみましたが,線形性はいいので,使い勝手が良さそうです。G1/G2/G3の3つのピンがADとして使えるとのことです。

簡単なGUIアプリを書いてみる

初めてtkinterを使ってみました。

tk_AD.py
import tkinter as tk

import board
from analogio import AnalogIn

def refresh_message():
    label["text"] = str("\nAD(G1) %.3f[V]" % (3.3*(AD1.value>>6)/1023) )
    root.after(100, refresh_message)

AD1 = AnalogIn(board.G1)

root = tk.Tk()
root.title("Read AD(G1) every 100msec")
root.geometry("400x200")
label = tk.Label(font=("",24, "bold"))
label.pack()
refresh_message()
root.mainloop()

実行例

image.png

I2Cを使ってみる

普通にCircuitPythonでI2Cを使う感覚ですね。INA219モジュールを接続しました。

INA219.py
import board
i2c = board.I2C()

def readRegisterI2C16(a): # a=pointer address
    while not i2c.try_lock():
        pass
    i2c.writeto(0x40, bytes([a]), stop=False)
    d = bytearray(2)
    i2c.readfrom_into(0x40, d)
    i2c.unlock()
    return(d[0] << 8 | d[1])

def writeRegisterI2C16(a, d): # a=pointer address, d=16bit data
    while not i2c.try_lock():
        pass
    i2c.writeto(0x40, bytes([a, int(d)>>8, int(d) & 0xff]), stop=False)
    i2c.unlock()

# convert 2's complement (ref)
# https://note.com/suujyou3/n/n35fca266f7b6

def toSigned16(d):
    return((d>>15) * (2**15) * (-1) + (d & 0x7FFF))

writeRegisterI2C16(5, 40.96 / 0.1) # Rshunt=0.1

print("Voltage: %d[mV]" % ((readRegisterI2C16(2)>>3)*4))
print("Current: %d[mA]" % (toSigned16(readRegisterI2C16(4))))

実行例 確認のため,あえて負の電流値になるように接続しています。

$ python3 INA219.py
Voltage: 3284[mV]
Current: -4[mA]
$

DACを使ってみる

  • G2/G3がDACとして使えます。
  • 出力インピーダンスが5kと大きいので要注意です。
  • 精度は5ビットと控えめです。CircuitPythonでは16ビットで指定します。Note that even though the MCP221's DAC is only 5 bits, you set it using a 16 bit value to comply with the CircuitPython API.
  • 上記の方法で,INA219を併用してログを書いてグラフにしてみました。線形を期待してはいけないようです。

image.png

USB - UART 変換として使う

こちらはスクリプト無しで,接続すればすぐに使えます。

おしまい

低レベルIOというのでしょうか,ロジックレベル,あるいは 0 - 3.3V の電圧をPCから直接扱うというのは新鮮な感覚ですね。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?