2020-07-11 PYNQ > Jupyter NotebookでHDMIモニタにsine curveを描く (pynq.lib.video Module使用)


動作環境
Windows 10 Pro (v1909) 
PYNQ-Z1 (Digilent) (以下、PYNQと表記)

関連

概要

  • bitstreamはbase.bitを使う
  • pynq.lib.video ModuleにあるAPIでHDMI入力とHDMI出力を行う
  • sine curveを描画する

方針

  • 描画を消すフレーム blkframeを用意
  • sine curveを描画するフレームを用意
  • 両社のフレームを交互に表示する

こうすると、アニメーション表示もできるようになる。
今回は静的な表示ではあるが。

接続

PCのHDMI出力をPYNQに読み取らせる。

  • A. PCのHDMI端子 <-> PYNQのHDMI IN
  • B. PYNQのHDMI OUT <-> モニタのHDMI

PCからのHDMI出力は今回用意しているが、クロックの設定などすれば不要になると思われる。

実装

Jupyter Notebookで以下を順番に実行する。

base.bitのダウンロードとHDMI IN/OUT設定。

from pynq.overlays.base import BaseOverlay
from pynq.lib.video import *

base = BaseOverlay("base.bit")
hdmi_in = base.video.hdmi_in
hdmi_out = base.video.hdmi_out

HDMIを動かす。

hdmi_in.configure()
hdmi_out.configure(hdmi_in.mode)

hdmi_in.start()
hdmi_out.start()

描画をする。

import time 
import numpy as np
from datetime import datetime
import math

adt = time.time()
print(adt)

blkframe = hdmi_out.newframe()
print(blkframe.shape)  # (720. 1280. 3)
# blkframe = np.zeros(720 * 1280 * 3, dtype = int).reshape(720, 1280, 3)
for row in range(0, 100): 
    for col in range(720):
        blkframe[col][row][0] = 0
        blkframe[col][row][1] = 0
        blkframe[col][row][2] = 0

drawframe = hdmi_out.newframe()
for row in range(0, 100): 
    for col in range(720):
        drawframe[col][row][0] = 0
        drawframe[col][row][1] = 0
        drawframe[col][row][2] = 0

adt = time.time()
print(adt)

for loop in range(10): 
    for ang in range(360):
        x = 720 - ang - 1  # 720: width 
        y = int(math.sin(math.radians(ang)) * 50) + 49
        drawframe[x][y][0] = 0 # blue
        drawframe[x][y][1] = 255 # green
        drawframe[x][y][2] = 0 # red
        # print(x,y)
    if loop % 2 == 1:
        outframe = drawframe
    else:
        outframe = blkframe

    hdmi_out.writeframe(outframe)
    time.sleep(1)

数秒ごとに真っ黒の画面とsine curveの描画交互に表示される。

処理時間

1518729496.3631167
(720, 1280, 3)
1518729515.325932

初期化処理で20秒近くかかる。numpy ndarrayへの代入が遅いようだ。