最終的に作ったライブラリは
こちら。
ラズパイ・ファン基板で OLEDを取り付け易くしたのだけれど、
i2c接続なので表示速度はどうなのだろうというのが気になっていた。
というのは、i2cは転送速度が速くない。
ラズパイのデフォルトでは100kbps。
OLEDは 128x64 dot なので、128x64 = 8kbit。
これを100kbpsで転送すると、転送時間は
8kbit ÷ 100kbps = 0.08sec
連続表示させると
毎秒 1 ÷ 0.08 = 12.5 フレーム表示できることになる。
スムーズな動画表示には少し遅い。転送以外の処理の時間も必要。
実際のところはどうなのだろうと測ってみることにした。
テストプログラム
使用したライブラリは
Adafruit_Python_SSD1306。
グラフィック・ライブラリ
Pillowのimageのデータを、そのまま表示できる
使い易いライブラリだ。
以下のプログラムを動かしてみた。
import Adafruit_SSD1306,time
from PIL import Image,ImageDraw,ImageFont
disp = Adafruit_SSD1306.SSD1306_128_64(rst=None,i2c_address=0x3C)
disp.begin()
image = Image.new('1',(disp.width,disp.height))
draw = ImageDraw.Draw(image)
font = ImageFont.truetype(
font='/usr/share/fonts/truetype/freefont/FreeMono.ttf',
size=50)
t0 = time.time()
draw.text((0, 0), 'Test', font=font, fill=1)
t1 = time.time()
disp.image(image)
t2 = time.time()
disp.display()
t3 = time.time()
print('draw text : %f' % (t1-t0))
print("disp image: %f" % (t2-t1))
print("display : %f" % (t3-t2))
実行結果は次のようになった。
pi@raspberrypi$ python speed_test.py
draw text : 0.001905
disp image: 0.033468
display : 0.116709
pi@raspberrypi$
データ転送に 0.116秒かかっているが、計算の 0.08秒とは
さほど違わない。次に /boot/config.txtに以下の行を追加後
rebootし、 i2cを400kbpsにして試してみる。
dtparam=i2c_baudrate=400000
実行結果
pi@raspberrypi$ python speed_test.py
draw text : 0.002004
disp image: 0.033668
display : 0.036361
pi@raspberrypi$
データ転送は期待通り約4倍高速化されたが、
disp imageの 0.033秒が大きい。
これはPillowのImageのデータをOLEDのバッファの
フォーマットに変換する処理で、ソースを見ると
Pythonで1bitづつ処理している。
この処理に時間が掛るとデータ転送を
早くしても、表示はあまり速くならない。
ライブラリ作成
ということで、 ラズパイ i2c接続OLED用に
Pythonのライブラリを作ってしまった。
githubで公開している。
i2cの操作は直接 /dev/i2c-1とかをオープンして行っている。
ここの資料を見ながらプログラムしたら、
特に問題もなく出来た。
テストプログラムで確認
新しいテストプログラムで処理時間を調る。
テストプログラムを新しいライブラリ用に若干修正した。
import time
from PIL import Image,ImageDraw,ImageFont
from RaspiOled import oled
oled.begin()
image = Image.new('1',oled.size)
draw = ImageDraw.Draw(image)
font = ImageFont.truetype(
font='/usr/share/fonts/truetype/freefont/FreeMono.ttf',
size=50)
t0 = time.time()
draw.text((0, 0), 'Test', font=font, fill=1)
t1 = time.time()
oled.image(image)
t2 = time.time()
oled.vsync()
t3 = time.time()
print('draw text : %f' % (t1-t0))
print("disp image: %f" % (t2-t1))
print("sync : %f" % (t3-t2))
実行結果は次のようになった。
ちなみにi2sの速度は400kbps
pi@raspberrypi$ python3 speed_test2.py
draw text : 0.001897
disp image: 0.000538
sync : 0.023852
pi@raspberrypi$
OLEDバッファへの書き込み(disp image)は0.0005秒になり、
データ転送も 0.023秒と高速化された。
で、やっぱり Bad Apple
ここまでやると、当然やるのはBad Apple。
Bad Appleの動画をffmpegでフレームごとに
bmpのファイルに変換し、
画像表示プログラム(
image.py)で
再生している。今回は音もwavファイルに変換したものを
ラズパイのaplayコマンドで同時に再生している。
ちなみに 画像表示プログラムとaplayを同時に走らせると、
画像が遅れるので、sleepコマンドで1.6秒後にaplayを起動している。
RssDisp
動画 BadAppleを再生できるのは良いのだが、まだなんか不満。
Oledでグリグリヌメヌメ表示できることを示したい。
HSES-NODE-OLEDで動かした
RssDispを動かしたい。
で、実装したのだが、予想外に手間がかかった。
文字のスクロール表示は、当初Pillow側でやろうかと思って
いたのだが、あまり効率よくできそうな気がせず、
ライブラリに表示イメージをずらす機能を追加。
更にテキストをスクロール表示させるクラスも
ライブラリに追加。
これでやっと RSSの表示プログラム
rssDisp.pyが完成した。
HSES-NODE-OLED版とほぼ同じ動作が実現できた。
こちらの方が https サイトにも対応しているので、
表示できるRSSサイトが多い。 ESP8266/Arduinoでも
httpsサイトへのアクセスはできるのだが、fingerprintを
入力する必要があり、面倒なので使っていない。
でもまぁ、HSES-NODE-OLEDの方が表示しっぱなしでも
惜しくないので良いかもしれない。
HSES-NODE-OLEDは
スイッチサイエンスで発売中。