完全に宣伝のようです。失礼
これは何?
- 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のストレージを使えるので,心置きなくログを書き出せそうですね。
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を使ってみました。
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()
実行例
I2Cを使ってみる
普通にCircuitPythonでI2Cを使う感覚ですね。INA219モジュールを接続しました。
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を併用してログを書いてグラフにしてみました。線形を期待してはいけないようです。
USB - UART 変換として使う
こちらはスクリプト無しで,接続すればすぐに使えます。
おしまい
低レベルIOというのでしょうか,ロジックレベル,あるいは 0 - 3.3V の電圧をPCから直接扱うというのは新鮮な感覚ですね。