« Grove-OLED-i2cをFramebufferモジュールで機能拡張する | トップページ | python3でCircuitPythonのAPIを使用する(リンク集) »

2020年4月25日 (土)

Grove-OLED-i2cにFramebufferモジュールを使ってイメージを表示する

2020/4/25+

MCP2221A adafruit_blinka Framebuffer Image

MCP2221A adafruit_blinka Framebuffer Image

概要

MCP2221Aボードで以下のGrove-OLED-i2cにFramebufferモジュールを使ってイメージを表示する. 本記事は「Grove-OLED-i2cをFramebufferモジュールで機能拡張する」の続きになる。

Grove - OLED Display 1.12"

本ボードは、ボードのバージョンによって、解像度が96x96または128x128であり、それぞれでコントローラも異なる。 入手したボードは、v1.1で解像度は128x128でコントローラはSH1107Gであった。(Vdd:3.3V/5V両用対応)

接続

MCP2221Aボードのi2cに本件のOLEDを接続する。(Vdd=3.3V)

該当モジュールのインストール

cd ~/mcp2221a_ws # 仮想環境に切り替える source blinka/bin/activate # sh1107g_cpy.pyをダウンロードする wget https://beta-notes.way-nifty.com/blog/files/sh1107g_cpy.py # adafruit_framebufをインストールする pip3 install adafruit-circuitpython-framebuf # framebufで使用するフォントをダウンロードする wget https://github.com/adafruit/Adafruit_CircuitPython_framebuf/blob/master/examples/font5x8.bin # python3のimageライブラリーをインストールする pip3 install Pillow # adafruit_imageloadモジュールをダウンロードする(CircuitPython用) git clone https://github.com/adafruit/Adafruit_CircuitPython_ImageLoad.git cp -r Adafruit_CircuitPython_ImageLoad/adafruit_imageload . # テスト用画像をダウンロードする(これは任意の画像で良い) wget https://upload.wikimedia.org/wikipedia/en/5/58/Blinka.png

テスト用画像をビットマップ画像に変換する

以下のスクリプトを実行してテスト用ビットマップ画像を作る:
mk_b1image.py

#!/usr/bin/python3 from PIL import Image im = Image.open('Blinka.png') resized_im = im.resize((128,128)) gray_im = resized_im.convert("L") # 以下の「x < 90」の「90」の画像によって調整すること tmp_im = gray_im.point(lambda x: 0 if x < 90 else 255) b1_im = tmp_im.convert('1') b1_im.save('blinka_b1.bmp') # inverted image # 以下の「x < 90」の「90」の画像によって調整すること tmp_im = gray_im.point(lambda x: 255 if x < 90 else 0) inv_b1_im = tmp_im.convert('1') inv_b1_im.save('blinka_inv_b1.bmp')

これにより以下の2つのファイルが作られる。
blinka_b1.bmp
blinka_inv_b1.bmp

デモ・スクリプト(python3/circuitpython兼用)

test_fb1_sh1107g.py

#CIRCUITPY = True CIRCUITPY = False # import image related module if CIRCUITPY: import displayio import adafruit_imageload else: from PIL import Image # for CircuitPython/blinka import time import busio import board i2c = busio.I2C(board.SCL, board.SDA) i2c.try_lock() from sh1107g_cpy import SH1107G oled = SH1107G(i2c) oled.clear() #----------------------------- # framebuffer related import adafruit_framebuf # pixel size for display WIDTH = 128 HEIGHT = 128 fbuf = bytearray(round(WIDTH * HEIGHT / 8)) fb = adafruit_framebuf.FrameBuffer(fbuf, WIDTH, HEIGHT, buf_format=adafruit_framebuf.MVLSB) #------------------------------ # write image into framebuffer def fb_image(fb,img): # Iterate through the pixels for x in range(img.width): for y in range(img.height): if img.getpixel((x, y)): fb.pixel(x, y, 1) else: fb.pixel(x, y, 0) # for circuitpython def fb_image_cpy(fb,img): # Iterate through the pixels for x in range(img.width): for y in range(img.height): if img[x, y]: fb.pixel(x, y, 1) else: fb.pixel(x, y, 0) # (for debug) Ascii printer for very small framebufs! def print_buffer(the_fb): print("." * (the_fb.width+2)) for y in range(the_fb.height): print(".", end='') for x in range(the_fb.width): if fb.pixel(x, y): print("*", end='') else: print(" ", end='') print(".") print("." * (the_fb.width+2)) # clear framebuffer def clear_fbuf(): for i, _ in enumerate(fbuf): fbuf[i] = 0 #---------------------------------- print("image test1: ") clear_fbuf() if CIRCUITPY: im, pal = adafruit_imageload.load( "blinka_b1.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette) fb_image_cpy(fb, im) else: im = Image.open('blinka_b1.bmp') im.show() fb_image(fb, im) # show display oled.draw(fbuf, len(fbuf)) time.sleep(4) print("image test2: ") clear_fbuf() if CIRCUITPY: im, pal = adafruit_imageload.load( "blinka_inv_b1.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette) fb_image_cpy(fb, im) else: im = Image.open('blinka_inv_b1.bmp') im.show() fb_image(fb, im) # show display oled.draw(fbuf, len(fbuf)) time.sleep(4)

変数CIRCUITPYのTrue/Falseでcircuitpython/python3用を切り換えている。

実行

PC(python3)の場合

# 仮想環境を有効化する source blinka/bin/activate # 実行する export BLINKA_MCP2221=1 python3 test_fb1_sh1107g.py

注意:変数CIRCUITPYをFalseにすること。

CircuitPythonの場合

REPL: import test_fb1_sh1107g

注意:変数CIRCUITPYをTrueにすること。

なお、CircuitPythonで実行する場合、 以下のファイル/ディレクトリをCIRCUITPYにコピーする:

(1)sh1107g_cpy.py (2)blinka/lib/python3.6/site-packages/adafruit_framebuf.py # 「python3.6」の部分は、ホストPCの状況に合わせる (3)test_fb1_sh1107g.py (4)blinka_b1.bmp (5)blinka_inv_b1.bmp (6)adafruit_imageload(デレクトリ) これは、CIRCUITPY/lib以下にコピーする

動作実績

(1)MCP2221Aボード
正常に動作した(Vdd=3.3V)
(2)CircutPython Teensy4.0
正常に動作した(Vdd=3.3V)
(3)FT232Hボード
i2c.scan()でデバイス・アドレスが返ってこない。(動作せず)(Vdd=5V)
デバイスの仕様としては、5V/3.3V両用対応になっているが本ボードでは動作しないようだ。

参照情報

PIL/Pillow チートシート

Framebuffer API
Famebuffer docs (MicroPython-based)

Python library for Seeedstudio Grove devices
Arduino Library for this Grove - OLED Display 1.12inch
download datasheet SH1107_v2.1.pdf

USB-I2CブリッジボードV2(GROVE対応ボード)【MR-GROVE-B】
USB-I2CブリッジボードV2(GROVE対応ブレッドボード版)【MR-GROVE-BB】
MCP2221 Blinka Pinout

CircuitPython Libraries on any Computer with MCP2221

CircuitPython on Linux and Raspberry Pi
CircuitPython 5.0.x - I2C

PCのpython3でCircuitPythonのAPIを使用する(FT232H版)
PCのpython3でCircuitPythonのAPIを使用する(MCP2221A版)

以上

|

« Grove-OLED-i2cをFramebufferモジュールで機能拡張する | トップページ | python3でCircuitPythonのAPIを使用する(リンク集) »

linux」カテゴリの記事

CircuitPython」カテゴリの記事

Teensy4.0」カテゴリの記事

MCP2221A」カテゴリの記事

SH1107G」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)




« Grove-OLED-i2cをFramebufferモジュールで機能拡張する | トップページ | python3でCircuitPythonのAPIを使用する(リンク集) »