h_nari @ 熊本市のブログ。電子工作、プログラミング、ゲーム、TV、 政治、インターネットなどに日々の思い付きを、 うだうだ~と書いていきたい。
このブログにはコメント欄を設けておりません。 記事への御意見、ご質問はtwitter @h_nari宛に お願い致します。


アーカイブ

メタ情報
RSS
Login

USB-I2C基板 (ソフトウェア編)

USB-I2C基板はpythonから使いたい。 pythonでI2C経由で機器を操作する プログラムを作りたい。 MCP2221 Pythonで検索すると いろいろ情報が見つかる。


PyMCP2221Aを試す

PyMCP2221Aというライブラリを試す。 MCP2221Aの機能(ADC,DAC,GPIO,CLK,I2C)を全て サポートしているようだ。

I2C接続のセンサーを試すと、簡単に値の読み取りなど できるようになった。もう少し派手なデモも欲しいので、 I2C接続のOLEDディスプレイ(128x64モノクロ)も試すが、 うまくいかない。 調べると PyMCP2221Aは 60byteまでの書き込みにしか対応していないことが判明。 そこで 60byte超のデータにも対応できるよう改造してみるが うまくいかない。

Circuit Python Libraryを試す

Adafruitも MCP2221AのUSB-I2Cボードを出しているので、 それ用のPythonライブラリを試してみる。 すると描画はできるが、繰り返すとエラーになる。 試したプログラムを以下に示す。

import os
os.environ['BLINKA_MCP2221'] = '1'

from board import SCL, SDA
import busio
import adafruit_ssd1306
from random import randint

i2c = busio.I2C(SCL, SDA)
oled = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c)
oled.fill(0)
for i in range(1000):
    print(i)
    x0 = randint(0,128)
    y0 = randint(0,64)
    x1 = randint(0,128)
    y1 = randint(0,64)
    oled.line(x0,y0,x1,y1,1)
    oled.show()

実行結果も下に示す。

$ C:/Users/nari/AppData/Local/Programs/Python/Python36-32/python.exe c:/01proj/v385_USB_I2C/python/blinka_test.py
0
1
 ... 中略 ...
86
87
Traceback (most recent call last):
  File "c:/01proj/v385_USB_I2C/python/blinka_test.py", line 19, in 
    oled.show()
  File "C:\Users\nari\AppData\Local\Programs\Python\Python36-32\lib\site-packages\adafruit_ssd1306.py", line 185, in show
    self.write_framebuf()
  File "C:\Users\nari\AppData\Local\Programs\Python\Python36-32\lib\site-packages\adafruit_ssd1306.py", line 232, in write_framebuf
    self.i2c_device.write(self.buffer)
  File "C:\Users\nari\AppData\Local\Programs\Python\Python36-32\lib\site-packages\adafruit_bus_device\i2c_device.py", line 104, in write
    self.i2c.writeto(self.device_address, buf, start=start, end=end, stop=stop)
  File "C:\Users\nari\AppData\Local\Programs\Python\Python36-32\lib\site-packages\busio.py", line 94, in writeto
    address, memoryview(buffer)[start:end], stop=stop
  File "C:\Users\nari\AppData\Local\Programs\Python\Python36-32\lib\site-packages\adafruit_blinka\microcontroller\mcp2221\i2c.py", line 19, in writeto
    self._mcp2221.i2c_writeto(address, buffer, start=start, end=end)
  File "C:\Users\nari\AppData\Local\Programs\Python\Python36-32\lib\site-packages\adafruit_blinka\microcontroller\mcp2221\mcp2221.py", line 298, in i2c_writeto
    self._i2c_write(0x90, address, buffer, start, end)
  File "C:\Users\nari\AppData\Local\Programs\Python\Python36-32\lib\site-packages\adafruit_blinka\microcontroller\mcp2221\mcp2221.py", line 202, in _i2c_write
    raise RuntimeError("Unrecoverable I2C state failure")
RuntimeError: Unrecoverable I2C state failure

$

その他の試み

MicroChip社提供の MCP2111A用DLLを Pythonから使ってみようとするが、 うまくいかず、 Linux用DriverをRaspberry Piで試すが OLEDへの表示はできない。

現象としては、MCP2221Aへ書き込み(USBパケットの送出)を 繰り返していると、コマンドが受け入れられませんでした という状態になり、リトライを繰り返すうち、 復旧不可能な状態になってしまう感じ。

結論

MCP2221のI2Cは、短いパケットであれば 使えているようであるが、 (現状のソフトウェアでは?) 長いデータの書き込み などを安定して行えないようである。

自分の用途では、短いデータのやりとりで 充分な気もするが、動作のわけのわからない 感じが気持ち悪いし USB-I2Cの転送速度の遅さも気に入らないので MCP2221Aの使用は諦めることにする。

次は FT232Hを試そうかと思う。 これだと I2Cに加えてSPIも使用可能。 Adafruitの奴はカッコいいのだが、 カッコ良すぎて実験用にピンヘッダをハンダ付け するのもためらわれてしまう。 秋月の奴だと気軽に実験できそう。