edit

Wio Terminalを使用してRaspberry Pi用HMI(Human-machine Interface)ディスプレイを作る

このwikiでは、 Wio TerminalRaspberry PiNvidia Jetson NanoBeagleBone およびOdyssey X86J4105など用の HMI (ヒューマンマシンインタフェース) USBディスプレイ として使う方法について紹介します! それで、Wio TerminalをHMI USBディスプレイに変えて、ずっと強力にさせて、より多くの産業のシナリオに適用させます。

これは ホストデバイスに接続された複数のWio Terminal をサポートすることができます。 理論によって、十分なUSBポートを持てば、望む限り多くのUSBポートが接続できます。Raspberry Piでは、これに接続する四つまでのWio Terminal(RPIが四つのUSBポートを備える)を 拡張 モードミラーモード でHMIディスプレイとして動作することをサポートします。詳しくは次の説明をご覧ください!

必要なハードウェア

Wio Terminalファームウェア

まず、PCを介して一つのArduino プログラムを自分のWio Terminalにアップロードする必要があります。

次は二つの **例**の NullFunctionalUSBDisplayAndMouseControlです:

  1. Wio Terminalでより高い画面更新率**がほしいなら、Wio Terminalに **NullFunctional をアップロードしてください。
  2. Wio TerminalをUSBマウスとして機能 させたいなら、Wio Terminalに USBDisplayAndMouseControl をアップロードしてください。

uf2 方法

利便性のために、 Wio Terminalのファームウェアをアップロードするという uf2 方法もあります。簡単に次の uf2 ファイルをダウンロードすれば十分です。

電源スイッチを二回速くスライドさせて、ブートローダーモードに入ります。 詳しくは、 こちらをご参照ください。

PCで Arduino という外部ドライブが見えます。 ダウンロードされたuf2ファイルを Arduino ドライブにドラッグしてください。

ホストデバイスファームウェア

それでは、ホストデバイス上のディスプレイドライバを設定しましょう。 これはRaspberry Pi、Jetson Nano およびOdyssey X86J4105になります:

Raspberry Pi

Raspberry Piの場合、まず カーネルヘッダとカーネルを更新する 必要があります。 terminalで次のコマンドを実行してください:

sudo apt-get -y --force-yes install raspberrypi-kernel-headers raspberrypi-kernel
  • Raspberry Piでディスプレイドライバーをダウンロードしてください:
cd ~
git clone https://github.com/Seeed-Studio/seeed-linux-usbdisp
  • ドライバーを作成してコンパイルする:
cd ~/seeed-linux-usbdisp/drivers/linux-driver
make & sudo make install
sudo reboot
  • configファイルをシステムロケーション に移動する:
sudo cp ~/seeed-linux-usbdisp/drivers/linux-driver/xserver_conf/10-disp.conf /usr/share/X11/xorg.conf.d/

Note

異なるスクリーンの構成が選択できて、デフォルトでは、一つのWio Terminalは一つのスクリーンとして使われます。

  • サービスを再起動する:
sudoサービスlightdmの再起動
  • Wio TerminalをRaspberry PiのUSBポートに接続しましょう!

現在、Wio TerminalがRaspberry Piのデスクトップを表示することが見えます! Wio Terminalで USBDisplayAndMouseControl というファームウェアをロードしたら、これらのボタンと5ウェイスイッチを使ってRaspberry Piのマウスをコントロールすることもできます。

Note

USBディスプレイドライバーのこのバージョンは、ホットスワッピングをサポートしていません。

Jetson Nano、BeagleboneとOdyssey X86

Nvidia Jetson NanoとOdyssey X86J4105 (Ubuntu)の場合、次の linuxドライバー をインストールして、 terminalで次のコマンドを実行します:

Note: Odyssey X86J4105の場合、ubuntuとdebian OSだけをテストしました。ほかのLinux OSが動作しない可能性もあります。

sudo apt install --reinstall linux-headers-$(uname -r)
  • ディスプレイドライバーをダウンロードする:
cd ~
git clone https://github.com/Seeed-Studio/seeed-linux-usbdisp
  • ドライバーを作成してコンパイルする:
cd ~/seeed-linux-usbdisp/drivers/linux-driver
make & sudo make install
sudo reboot
  • configファイルをシステムロケーション に移動する:
sudo cp ~/seeed-linux-usbdisp/drivers/linux-driver/xserver_conf/10-disp.conf /usr/share/X11/xorg.conf.d/
  • サービスを再起動する:
sudoサービスlightdmの再起動
  • Wio TerminalをデバイスのUSBポートに接続しましょう!

スクリーン表示の設定

前述のように、 一つのRaspberry Piに 複数 のWio Terminalを接続することができます。それで、 10-disp.conf ファイルを編集することでスクリーンの設定(スクリーンのロケーション)を整えることができます。次のようなほかの三つのスクリーン拡張設定が提供されます。

スクリーン設定 1

# Four-screen expansion
# pattern: 1  2  
#        : 3  4

これはseeed-linux-usbdisp/drivers/linux-driver/xserver_conf/ 下の 10-disp-1.conf です。 簡単にこのファイルを /usr/share/X11/xorg.conf.d/ にコピーして、 10-disp.conf と名付ける:

sudo cp ~/seeed-linux-usbdisp/drivers/linux-driver/xserver_conf/10-disp-1.conf /usr/share/X11/xorg.conf.d/10-disp.conf

スクリーン設定2

# Four-screen expansion
# pattern: 1
#        : 2  3  4

これは seeed-linux-usbdisp/drivers/linux-driver/xserver_conf/ 下の 10-disp-2.conf です。

スクリーン設定 3

# Four-screen expansion
# pattern: 1  2  3  4

これは seeed-linux-usbdisp/drivers/linux-driver/xserver_conf/ 下の 10-disp-3.conf です。

スクリーン設定 4

ミラーモード:

# Four-screen clone display

これは seeed-linux-usbdisp/drivers/linux-driver/xserver_conf/ 下の  10-disp-4.conf です。

PtQtGraphの例

また、 PyQtGraph というグラフを使って、 Wio Terminalで簡単にGUIを描くことができます!

  • まずPyQtGraphの依存項をインストールしましょう:
sudo apt update
sudo apt install python3 python3-distutils python3-pyqt5 python3-pip python3-numpy -y
sudo pip3 install pyqtgraph
  • スクリーンのマクロをエクスポートする:
export QT_QPA_PLATFORM=linuxfb:fb=/dev/fb1

Note: 中にはfb1 が一番のスクリーン、 fb2 が二番のスクリーン、 fb3 fb3 もこれによって類推します。 echo $QT_QPA_PLATFORM を使ってマクロをチェックしてもよいです。

  • 次のPyQtGraphの例のpythonファイルをコピーして、 test.pyと名付ける:
# -*- coding: utf-8 -*-
"""
Demonstrates common image analysis tools.
Many of the features demonstrated here are already provided by the ImageView
widget, but here we present a lower-level approach that provides finer control
over the user interface.
"""
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np


# Interpret image data as row-major instead of col-major
pg.setConfigOptions(imageAxisOrder='row-major')

pg.mkQApp()
win = pg.GraphicsLayoutWidget()
win.setWindowTitle('pyqtgraph example: Image Analysis')

# A plot area (ViewBox + axes) for displaying the image
p1 = win.addPlot(title="")

# Item for displaying image data
img = pg.ImageItem()
p1.addItem(img)

# Custom ROI for selecting an image region
roi = pg.ROI([-8, 14], [6, 5])
roi.addScaleHandle([0.5, 1], [0.5, 0.5])
roi.addScaleHandle([0, 0.5], [0.5, 0.5])
p1.addItem(roi)
roi.setZValue(10)  # make sure ROI is drawn above image

# Isocurve drawing
iso = pg.IsocurveItem(level=0.8, pen='g')
iso.setParentItem(img)
iso.setZValue(5)

# Contrast/color control
hist = pg.HistogramLUTItem()
hist.setImageItem(img)
win.addItem(hist)

# Draggable line for setting isocurve level
isoLine = pg.InfiniteLine(angle=0, movable=True, pen='g')
hist.vb.addItem(isoLine)
hist.vb.setMouseEnabled(y=False) # makes user interaction a little easier
isoLine.setValue(0.8)
isoLine.setZValue(1000) # bring iso line above contrast controls

# Another plot area for displaying ROI data
win.nextRow()
p2 = win.addPlot(colspan=2)
p2.setMaximumHeight(250)
win.resize(800, 800)
win.show()


# Generate image data
data = np.random.normal(size=(200, 100))
data[20:80, 20:80] += 2.
data = pg.gaussianFilter(data, (3, 3))
data += np.random.normal(size=(200, 100)) * 0.1
img.setImage(data)
hist.setLevels(data.min(), data.max())

# build isocurves from smoothed data
iso.setData(pg.gaussianFilter(data, (2, 2)))

# set position and scale of image
img.scale(0.2, 0.2)
img.translate(-50, 0)

# zoom to fit imageo
p1.autoRange()  


# Callbacks for handling user interaction
def updatePlot():
    global img, roi, data, p2
    selected = roi.getArrayRegion(data, img)
    p2.plot(selected.mean(axis=0), clear=True)

roi.sigRegionChanged.connect(updatePlot)
updatePlot()

def updateIsocurve():
    global isoLine, iso
    iso.setLevel(isoLine.value())

isoLine.sigDragged.connect(updateIsocurve)

def imageHoverEvent(event):
    """Show the position, pixel, and value under the mouse cursor.
    """
    if event.isExit():
        p1.setTitle("")
        return
    pos = event.pos()
    i, j = pos.y(), pos.x()
    i = int(np.clip(i, 0, data.shape[0] - 1))
    j = int(np.clip(j, 0, data.shape[1] - 1))
    val = data[i, j]
    ppos = img.mapToParent(pos)
    x, y = ppos.x(), ppos.y()
    p1.setTitle("pos: (%0.1f, %0.1f)  pixel: (%d, %d)  value: %g" % (x, y, i, j, val))

# Monkey-patch the image to use our custom hover function. 
# This is generally discouraged (you should subclass ImageItem instead),
# but it works for a very simple use like this. 
img.hoverEvent = imageHoverEvent


## Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()
  • 例を実行する:
python3 test.py
  • マウスがPyQtGraphのスクリプトでくラッシュすることを経験したかもしれません。sudo raspi-config -> Boot options -> Desktop/CLI -> Console Autologinをクリックするによって、簡単にraspberry piのデスクトップを無効にすることができます。

現在、PyQtGraphのスクリプトを実行すると、正常に動作できるようになります!

次のように異なるスクリーンで、それと対応するPyQtGraphスクリプトを実行するかもしれない:

Usermod SDK

このUSBディスプレイドライバーはPCでも動作できます。このようなドライバーが現在開発している途中なので、お楽しみにしてください!

更なる開発

より大きいスクリーンまたはより高い解像度、より高い更新率がほしいのでしょうか?もっと多く知りたいなら、produce@seeed.ccに連絡してください。

資料

技術サポート

技術的な問題は ファーラムに提出してください。