Programming

PJLink用ライブラリ(Arduino)を作りました

Programming
スポンサーリンク

新年、明けましておめでとうございます。今年もよろしくお願いします。
2025年、一発目のネタは組み込み(Arduino)向けのPJLink制御用ライブラリです。

きっかけ

それにしても、なぜ本ブログでPJLinkを取り扱うことにしたのか?

実は、数年前にプロジェクターを制御する組み込み機器を作る案件を引き受けたのですが、そこでPJLinkのコマンドを叩くファームウェアを書いたことがきっかけでPJLinkを知りました(詳細は機密保持のため割愛)。

苦労の末、どうにかPJLinkでプロジェクターの制御ができるようになったのですが、せっかくならPJLinkコマンドの処理を共通化して汎用的に使えるよう、Arduino用のライブラリを作ることにしました。

PJLinkとは?

一言でいうと、ネットワーク経由でプロジェクター/ディスプレイを制御するための統一規格です(公式から詳細な仕様もダウンロードできます)。

JBMIA PJLink

基本的な仕様

IPアドレスとポート番号:4352(ポート名:pjlink)でプロジェクターと接続して、TCP/IPプロトコルを介し、以下のようなパケットで構成されるコマンドをプロジェクターと送受信します。

ヘッダ+クラスコマンド本体セパレータパラメータ終端
2バイト4バイト1バイト128バイト以内1バイト

また、パケット固有の文字列は以下の通りで、コマンド本体パラメータを変えることでプロジェクターの命令や応答を定義します。
(接続直後の応答など一部例外あり)

  • ヘッダ:”%”
  • クラス番号:1 / 2
  • セパレータ:” “(要求)、”=”(応答)
  • 終端:CR

パスワード認証

パスワード認証にも対応しており、MD5アルゴリズムを使ってパスワード(ASCII英文字32文字まで)と乱数(4バイト整数: ASCII英小16進数8文字)から暗号化メッセージ(32バイトASCII文字列)を生成して認証を行って…いました。

なんと2024年3月に更新があり、認証セキュリティ強化のためSHA256ハッシュアルゴリズムによる暗号生成に変更されています!
プロジェクターと制御コントローラーの双方で乱数を生成し、乱数2つのXOR値(の文字列)とパスワードを連結してSHA256のハッシュ値を生成することでパスワード認証を行います。

パスワードASCII英文字32文字まで
乱数 (4バイト)ASCII16進数8文字
乱数 (16バイト)ASCII16進数32文字
ハッシュ値ASCII16進数64文字

MD5使用時は暗号化メッセージのみを送っていましたが、SHA256ではコントローラー側の乱数とハッシュ値を連結してプロジェクターに送信します。そのため、暗号化メッセージの文字数も32バイトから96バイトと3倍になっています。

ただし、仕様変更から日が浅いので古い機種では対応していない可能性もあり、現仕様で認証できなかった際は旧仕様のMD5で再度通信するように公式でも書かれています。

実は、開発したライブラリはまだSHA256に対応していません(汗)。なるべく早く対応したい…。

利点と制約

上記の通りのパケットを定義したことで、PJLink対応のプロジェクターなら同一のコマンドで制御することが可能になりました。

RS232C通信などで制御できる機種もありますが、PJLink以前は各社独自で制御コマンドを規格しているため、大本の仕様(通信速度など)からコマンドのプロトコル、パラメータ文字列までバラバラでメーカーに問い合わせるか自分で調べる必要があります。
PJLinkではこうしたコマンド自体が統一されたため、コマンド文字列については調べる手間が無くなった事が一番の利点です。

しかし、送受信する文字列が統一されただけなので、実際の挙動や応答内容については相変わらず検証する必要があります。動作については各機種バラバラなので、機器を入れ替えると前と異なる動作をする可能性もあり、そういった意味ではまだPJLinkの謳う高い相互接続性には遠いといった印象です。

ビデオプロジェクタを制御してみよう | 音響・映像・電気設備が好き

Arduinoライブラリ

そんなPJLinkをArduinoでも使えるよう、ライブラリにしてみました。

GitHub - Revetronique/PJLink: Arduino library for generating or parsing PJLink command
Arduino library for generating or parsing PJLink command - Revetronique/PJLink

主な仕様は以下の通り。

  • PJLink用のコマンド生成(generator)と解析(parser)を担当
    • 生成:generatePacket をラップした各種メソッドでコマンド文字列を生成
    • 解析:process(String) で受信した文字列からパラメータなどを読み取り
  • インスタンス生成なしで利用可能
  • パスワード認証対応
    • MD5アルゴリズム
    • setPassword(const char*) に文字列を入れて設定
    • プロジェクター側のメッセージ(PJLINK 1 [乱数])をprocessで解析することで、認証用の暗号メッセージも自動的に取得

また、動作検証については以下のマイコンで行っています。

  • AVR(8bit):プロジェクターで動作検証(UNO R3 + Ethernet Shield v2)
  • ESP32:文字列生成の部分まで確認

ライブラリの細かな設計や実装は別の記事にしようと思っていますが、現時点で対応していない課題が残っているので、対応したら改めて解説していく予定です。

  1. UDP経由での検索・状態通知に対応(クラス2)
  2. 認証手続きにおけるSHA256アルゴリズムへの対応

実機検証

プロジェクターはたまたま家にあった Canon LV-8320 を使いました。
(昔とあるコンテストで受賞した際の賞品なのですが…その経緯はまた別の話で)

【プロジェクター】LV-8320機種仕様

ただ、上記のは10年以上前の古い機種なので、現行機種でPJLink対応のですとエプソン製の EB-2155W などいろいろあります。

Amazon.co.jp

実はAmazonだとあまり見つからない(何故かエプソン製ばかり見つかる)ので、家電量販店かメルカリなどでPJLink対応の機種を型番やメーカー名などで検索して探したほうがいいですが、ほぼすべて10万超えの機種なので、おいそれと手を出すのは難しいかもしれません。もし入手する機会などがあればお試しください。

参考

PJLinkってなんだ? | 音響・映像・電気設備が好き

QlabでPJLinkプロジェクターを制御する #映像 – Qiita

Cycling ’74 Max 8でPJLink制御を行う | 音響・映像・電気設備が好き

Pjlink-Python&Windows-VC#で動かしました。 #TCP/IP – Qiita

タイトルとURLをコピーしました