エッジデバイスのLEDマトリックスに情報表示、Raspberry Pi + ScrollpHATHD

●概要

今回は、エッジデバイスで取得したセンサーデータや、ステータスメッセージなどを LED マトリックスに表示するアプリケーションを紹介します。離れた場所からでも視認性が高いので、センサーデータなどを常時監視が必要なアプリケーションに最適です。

ハードウエアは Raspberry Pi Zero WH に PIMORONI 製の Scroll pHAT HD を接続しています。動作中の様子は下記の様になります。

動作しているときの様子

Raspberry Pi 上では、Raspbian OS と オールブルーシステムの abs_agent が動作しています。Scroll pHAT HD を操作するためのライブラリは、PIMORONI 社で提供されている Python ライブラリは使用せずに、Lua スクリプトで全ての描画処理を行っています。このため、イベントハンドラや Web API 等から簡単に表示内容を更新することができ、またCPU 負荷もかなり抑えることができています。

●セットアップ方法

必要なハードウエアは Raspberry Pi 本体と Scroll pHAT HD だけです。今回は Raspberry Pi Zero WH にセットアップする例で説明します。Scroll pHAT HD のコネクタは半田付けが必要ですが、ピンソケットだけなので難易度は低く簡単です。

Raspberry Pi WH と Scroll pHAT HD を接続したら、Raspbian OS をセットアップします。運用中は LCD ディスプレイやキーボードなどを Raspberry Pi Zero に接続していると邪魔なので、WiFi ネットワーク経由で操作できるように SSH サーバーのセットアップも行って下さい。

今回紹介するアプリでは、Raspbian の I2C ドライバ・ユーティリティや PIMORONI 社で提供されているライブラリは使用しませんのでインストールする必要はありませんが、インストールした状態でも問題ありません。

デフォルトの “pi” ユーザーでログイン後、abs_agent のインストールキットをここからダウンロードしたものを tar コマンドで展開します。

abs_agent のインストール

tar コマンドを実行したディレクトリに abs_agent ディレクトリが作成されますので、その中のサーバー設定ファイル(abs_agent.xml)を vi エディタ等で編集してRaspberry Pi の CPU タイプを指定します。今回は Raspberry Pi Zero を使用しますので下記の XML タグに “BCM2708″ を記述してください。エディタでサーバー設定ファイルを編集します。Raspberry Pi ver2 や ver3 を使用する場合には “BCM2709″にします。

下記キャプチャの矢印部分にある、<Hardware> タグの内容を、Raspberry Pi Zero 用の “BCM2708″ に設定します。

次に、Scroll pHAT HD 操作用の Lua ライブラリを有効にするために、インストールキットを展開した abs_agent/scripts/preload/100_RASPI ディレクトリ内にある “_scrollphathd” ディレクトリ名の先頭にあるアンダースコア “_” を取り除いて “scrollphathd”にリネームします。

最後に、abs_agent 起動時に文字列データをスクロール表示させるタスクを自動起動する設定を行います。abs_agent/scripts/SERVER_START.lua ファイルをエディタで開いて、Scroll pHAT HD 用のスクロール表示タスクの起動部分のコメントを外して有効にします。ここでは2種類のタスクを選択できます。1つ目が1つの文字列をスクロール表示するタスク(RASPI/SCROLLPHATHD_DISPLAY_TASK)で、もう一つが複数の文字列を順に文字列ごとにスクロール表示するタスク(RASPI/SCROLLPHATHD_BULLETIN_BOARD_TASK)です。ここでは、最初の方の1つの文字列を表示するタスクを有効にしています。

これで設定は完了です。もし Windows マシンがある場合にはログサーバーのセットアップを行っておくと動作ログをネットワーク経由で取得することができます。ここでは Windows PC にログサーバー(192.168.100.45) を設置しています。

最初は手動で abs_agent を起動してみます。I2C ハードウエア(実際にはプロセッサのレジスタ)に直接アクセスするために、sudo コマンドで特権を与える必要がある点に注意してください。OS (Raspbian) 起動に abs_agent を自動起動させる場合には /etc/rc.local ファイルに起動コマンドを書き込んでおきます。詳しい設定方法は abs_agent ユーザーマニュアルを参照してください。

正常に起動すると、Scroll pHAT HD に Raspberry Pi の IP アドレスがスクロール表示されます。

この状態で、abs_agent のグローバル共有変数に設定した文字列を Scroll pHAT HD に表示できます。スクリプトやコンソールから文字列を設定する場合には、グローバル共有変数名 “SCROLLPHATHD_MESSAGE” に任意の文字列を設定します。文字列中には日本語も使用できます。

例えば、コンソールから agent_data クライアントプログラムを使用してグローバル共有変数に値を設定する場合には下記の様なコマンドを入力します。

./agent_data -k SCROLLPHATHD_MESSAGE -v 今日は晴れ

すると、Scroll pHAT HD には下記の様に文字列が表示されます。(長い文字列は自動的にスクロール表示されます)

●スクロール表示させるタスク(RASPI/SCROLLPHATHD_DISPLAY_TASK)の説明

abs_agent 起動時に自動起動して、スクロール表示を行っている RASPI/SCROLLPHATHD_DISPLAY_TASKスクリプトの内容は以下のようになっています。

--[[

●機能概要

Scroll pHAT HD LEDマトリックス表示器に文字列を表示する。
表示する文字列データはグローバル共有変数に設定されているものを使用する。

長い文字列はスクロール表示される。表示可能な文字は ASCIIと日本語で、それ以外の
文字は表示できない。

●参照するグローバル共有変数

---------------------------------------------------------------------------------
キー値                      値
---------------------------------------------------------------------------------
SCROLLPHATHD_MESSAGE	"<message string>"

表示するメッセージ文字列を設定する。
設定可能な文字列の最大長は英数字の場合に約 256文字です。(Max 1536ピクセル)

●セットアップ

このスクリプトは ScrollpHAT HD (17x7 pixel) PIMORONI LEDマトリックス出力用ライブラリ関数を
使用します。インストール直後はライブラリが無効になっていますので、ライブラリの
ディレクトリ名をリネームして有効にしてください。方法は、ライブラリを格納しているディレクトリ名
"preload/100_RASPI/_scrollphathd" の、先頭についたアンダースコアを取り除いて
"preload/100_RASPI/scrollphathd" にリネームした後 abs_agent を再起動させてください。

●備考

このスクリプトは無限ループに入って終了しないので、必ず別スレッドで起動してください。

●変更履歴

2018/05/17     日本語フォント表示機能を追加

2018/05/06     bright パラメータを追加

2018/04/06     初版作成

copyright(c) 2018 All Blue System

]]

---------------------------------
-- 2重起動防止用チェック
---------------------------------
if not exclusive_check(g_script) then
    log_msg("*ERROR* exclusive_check() failed. script = " .. g_script,g_script)
    return
end
log_msg("start..   TaskID = " .. g_taskid,g_script)

-----------------------------------------------------------------------------------------------------------------
-- 指定したグローバル共有変数の値が変更されるか、もしくは指定されたカウント値 x 10ms 経過するまで内部でウェイト
-- 最後に取得したグローバル共有変数の値を返す。
-----------------------------------------------------------------------------------------------------------------
function global_change_wait(global_name,start_val,max_wait_cntr)
	local stat,new_val
	local cntr = 0
	repeat
		wait_time(10)
		cntr = cntr + 1
		stat,new_val = get_shared_data(global_name)
	until (cntr >= max_wait_cntr) or (start_val ~= new_val)
	return new_val
end

---------------------------------
-- デバイスとタスク内変数初期化
---------------------------------
if not raspi_i2c_clock(1,1500) then error() end	-- I2C bus1 クロック設定 100KHz = 150MHz / 1500
scrollphathd_try_init()								-- ScrollpHATHD 初期化
local message_var = "SCROLLPHATHD_MESSAGE"			-- 表示する文字列データを取得するグローバル共有変数
local font = 2 									-- 5x7smooth フォント
local stat,misaki_font = shmem_copy("MISAKI_FONTX",0,0) -- 日本語フォントデータをグローバル共有メモリから作業用にロードする
if not stat then
    log_msg("*ERROR* MISAKI_FONTX not found.",g_script)
	return
end

-----------------------------------------------------------------------------------------------------------------
-- メインループ。無限ループを停止させる場合には script_kill() または "agent_task -k <taskid>" コマンドを使用する
-----------------------------------------------------------------------------------------------------------------
local pixel_data			-- 描画時のピクセルデータを一時的に保持する
local pixel_idx			-- 描画時のピクセルデータを一時的に保持する
local org_x = 0			-- 文字列の描画開始座標
local org_y = 0			-- 文字列の描画開始座標
local disp_msg = "???"		-- 現在表示中の文字列データ
local new_msg = ""			-- 最後に取得した最新の文字列データ
local sw = 0				-- 文字列のピクセル幅
local sh = 0				-- 文字列のピクセル高
local first_wait = 50		-- スクロール表示時の最初と最後にウェイトする時間 x10ms
local inter_wait = 3		-- スクロール中のウェイトする時間 x10ms
local max_x = 0
local bright = 0.5			-- 描画時の明るさ。0 から 1.0 までの範囲で指定
while true do
	if disp_msg ~= new_msg then -- 新しい文字列データがセットされたので描画する
		disp_msg = new_msg
		pixel_data = {}
		pixel_idx = {}
		scrollphathd_clear()
		-- sw,sh = scrollphathd_draw_string(pixel_idx,pixel_data,org_x,org_y,disp_msg,font,bright) -- 英数字のみ
		sw,sh = scrollphathd_draw_jstring(pixel_idx,pixel_data,org_x,org_y,disp_msg,misaki_font,bright) -- 英数字と日本語
		scrollphathd_draw_commit(pixel_idx,pixel_data)
		scrollphathd_transfer(0,0)
		scrollphathd_display(0)
	end
	max_x = org_x + sw
	if (max_x > 17) then -- スクロール表示が必要か?
		scrollphathd_transfer(0,0) -- 最初の1画面分を表示
		new_msg = global_change_wait(message_var,disp_msg,first_wait)
		if disp_msg ~= new_msg then goto SCROLL_FINISH end
		if max_x > 1535 then max_x = 1535 end
		for x0 = 1,max_x - 17 do -- 画面に表示する部分を1ピクセル右にずらす
			scrollphathd_transfer(0,x0)
			new_msg = global_change_wait(message_var,disp_msg,inter_wait)
			if disp_msg ~= new_msg then goto SCROLL_FINISH end
		end
	end
	new_msg = global_change_wait(message_var,disp_msg,first_wait)

::SCROLL_FINISH::

end

このスクリプトでは、グローバル共有データにセットされた文字列を1文字毎に文字コードに分解した後、フォントテーブルを利用してピクセルデータを作成しています。その後、Scroll pHAT HD に表示する位置を1ピクセルづつずらしてデータを転送します。

上記のスクリプトから Scroll pHAT HD を I2C バスで操作するために、Lua スクリプトで作成したライブラリ関数を使用しています。ここでは、これらのライブラリ関数の説明は省略しますが、もし内容を確認したい方は、abs_agent/scripts/preload/100_RASPI/scrollphathd ディレクトリに格納されているスクリプトファイルをご覧ください。

●Web API から表示する文字列を設定する

abs_agent のグローバル共有変数は Web API から内容を変更できますので、Web アプリケーション等から簡単に Scroll pHAT HD の表示内容を設定できます。

Web API 経由で操作する場合には、通常 abs_agent 内に専用の Web ユーザーアカウントを作成して、ログイン認証した時に取得できるセッション情報を使用します。

LAN 内などで簡単に利用するために、常に有効な固定のセッション情報を予め abs_agent 側で作成しておくと、ログイン認証を省略して Web API を操作することができます。ここでは予め、固定のセッション情報を作成する方法を説明します。

abs_agent 起動時に自動実行されるスクリプト(SERVER_START.lua) ファイルにセッションを作成するスクリプトを記述します。abs_agent/scripts/SERVER_START.lua ファイルをエディタで開いて、下記の様なスクリプトを記入します。

create_session() ライブラリ関数に指定した文字列(セッショントークン) を使用すると、常に Web API 経由でグローバル共有変数の操作やスクリプト実行が可能になります。

最後に、上記の設定を有効にするために abs_agent を再起動させます。単純に Raspberry Pi を Raspbian OS ごとリブートさせても構いませんが、ここではステップ毎にコマンドを入力して再起動させてみます。コマンドの実行例は下記の様になります。

最初に、バックグランドで動作しているScroll pHAT HD のスクロール表示タスクを agent_task コマンドで確認しています。表示された <task_id> 文字列を使用して、agent_task -k <task_id> コマンドを実行すると、実行中のバックグランドタスクを強制終了させることができます。

その後、agent_shutdown コマンドを実行して abs_agent プログラムを終了させます。全てのサービスモジュールをシャットダウンするのに数秒かかりますので、しばらく待ったあと、abs_agent を手動で起動させます。

SERVER_START.lua スクリプトに設定した固定のセッション情報を確認するために、agent_session コマンドを実行しています。セッションが作成されていれば、そのセッショントークン文字列を指定するだけで、Web API 経由で abs_agent にアクセスできます。

早速 PC の Web ブラウザからアクセスして Scroll pHAT HD の表示内容を設定してみます。

上記は Windows で動作している Firefox ウェブブラウザの URI に 、Web API アクセス用のパスを入力した様子です。IP アドレスと HTTP ポート番号は Raspberry Pi の IP アドレスと abs_agent 設定ファイル(abs_agent.xml)に記述されたポート番号に合わせます(デフォルト値は 8080)。/command/json/shared_data が abs_agent のグローバル共有変数を操作するためのコマンドパスに相当します。

URL の session パラメータには、先に設定した固定のセッショントークン文字列を指定します。key パラメータにはスクロール表示タスクで監視しているグローバル共有変数名(SCROLLPHATHD_MESSAGE)を、value パラメータに表示したい文字列を指定します。日本語を URL パラメータに指定する場合には、本来 URL エンコードしたものを指定しないといけないのですが、Firefox の URI 欄では勝手にエンコードしてくれるようで、そのまま記述できるので大変便利です。

HTTP プロトコルでコマンドを実行すると、レスポンスが JSON フォーマットで返ります。Firefox ブラウザでは HTTP で取得したJSON 文字列が自動で整形されて表示されます。このとき同時に、Scroll pHAT HD では設定した文字列がスクロール表示されている筈です。

●エクセルのセル内容を表示する

次は、Windows PC のプログラムから表示する文字列を設定する例を紹介します。abs_agent のインストールキット中にある DLL ファイル、または ABS-9000 LogServer のインストールキットに含まれる DLL を利用すると、Windows プログラムから直接 abs_agent 上のグローバル共有変数を更新することができます。

ここではログサーバーを設置した Windows PC 上でマイクロソフト・エクセルを動作させて、セルの内容を Scroll pHAT HD に表示してみます。

先に紹介した Web API 経由のアクセス時には、認証用にセッション情報を必要としまし。これは、Web 経由でアクセスする場合には不特定のホストからのアクセスになるために、アクセス毎の認証が必要になるためにこのような仕様にしています。

DLL 経由でアクセスする場合や abs_agent 間でアクセスする場合には特定のホストからのアクセスに限定できますので、セッション情報は不要になります。その代わりに予め、アクセスされる側の abs_agent にアクセスする側のホスト名を登録しておきます。ここでは agent_hosts コマンドで Windows PC のホスト名(ここでは eagle)を abs_agent に設定しています。

この状態で Windows PC(eagle) 上で実行するエクセルからアクセスしてみます。エクセルファイルを開くと下記の様な画面が表示されます。このファイルはインストールキット中の contrib/Excel/Agent_ScrollpHATHD.xls ファイルに格納されています。

サーバー設定タブで表示される画面上で、abs_agent のホスト名または IP アドレスをセルに代入してください。

その後、文字列表示タブを開いて項目の値のセル内容を更新すると、自動的に合計値が計算されてセルに表示されます。このとき、Scroll pHAT HD 上には合計セルの値が表示されます。

手動更新ボタンを押すと、その右横のセルに設定している文字列を Scroll pHAT HD に表示します。これらの動作を行っている ワークシート中のマクロは下記の様に記述されています。

マクロからコールしている AG_set_shared_data() ライブラリ関数が DLL ライブラリのラッパー関数になります。これらのラッパー関数定義については、ワークシート中の標準モジュール(XASDLCMDIntf) に記述されています。また DLL 自身の仕様については abs_agent のユーザーマニュアルをご覧ください。

動作したときの様子は記事の最後に添付した動画をご覧ください。

●考察

今回は、Raspberry Pi に簡単に接続可能な LED 表示器を利用して、様々な方法でデータを表示できることを紹介しました。LCD と違って遠くからでも視認しやすいですので、カウンタ値やエラーメッセージの表示に適していると思います。

●動作例の動画

メッセージ表示を行っているときの動画を載せましたのでご覧ください。(音量注意)

この記事で設定した内容の詳しい説明や、ログサーバーのインストール方法、abs_agent の自動起動方法、Web API コマンドや DLL ライブラリ使用方法についてはユーザーマニュアルに詳しく記載されています。インストールキット中の docs/user_manual.pdf またはここから最新のユーザーマニュアルをダウンロードして参照してください。

ご意見や質問がありましたら、お気軽にメールをお寄せください(contact@allbluesystem.com) 。

それではまた。