ドキュメント

GPIO のボタンとリレー

押しボタン、ドア接点、リレーボードをスクリーンの GPIO ピンに配線すると、スクリーン上のアプリケーションがボタンを検知し、リレーを駆動し、エージェントに報告します。

GPIO でできること

GPIO(汎用入出力)ラインは、Player のボードにあるピンで、アプリケーションが 1 本ずつ読み取ったり駆動したりできます。ラインは、high か low を読み取る入力、またはアプリケーションが high か low に設定する出力です。

入力は部屋の様子を検知します:

  • 押しボタン。たとえば「サービスを呼ぶ」ボタンや「次のページ」ボタン。
  • ドア接点、リードスイッチ、リミットスイッチ。
  • フロースイッチや人感センサーのリレー出力など、無電圧接点を持つセンサー。

出力が反応します:

  • ドアストライクを解除したり、積層表示灯を切り替えたり、ブザーを鳴らしたりするリレー。
  • ボタンを点灯させる LED。

スクリーン上のアプリケーションは screenrig.device.gpio を通じて処理を行い、emit で何が起きたかをエージェントに伝えるので、「サービスが要求されました」がプロジェクトのイベントログに表示されます。エージェントは他のアプリケーションと同様に、アプリケーションを作成し、アップロードし、スクリーンに配置します。ほかに何に到達できるかはハードウェアのページを参照してください。

GPIO を持つ Player

プレーヤーGPIO入力のプル出力のアイドル時のレベルピン番号
Raspberry Pi 3、4、5(Linux Player)はい。40 ピンヘッダーで利用できます。Player がヘッダーチップを自動的に見つけます"up"、"down"、または"none"はいBCM 番号
他の Linux ボードはい、SCREENRIG_GPIO_CHIP を使います"up"、"down"、または"none"はいそのチップのライン番号
Android と Amazon Signage Stickデバイスが書き込み可能な sysfs GPIO チップを公開している場合いいえ:抵抗を追加しますはいそのチップのライン番号
BrightSignはい:GPIO コネクターのピン 0〜7、または BrightSign の USB-GPIO アダプター内蔵プルアップはいピン 0〜7 と、BrightSign のセクションにある範囲
macOS、Windows、Player ウェブアプリ、Samsung Smart Signage(Tizen)、LG webOS Signageいいえいいえいいえいいえ

フラグは、ページのコントローラー、またはページにアプリケーションが 1 つだけの場合はそのアプリケーションに渡されます。アプリケーションが capabilities["device.gpio"] を true として認識するのは、GPIO を備えた Player とデバイスの場合だけなので、同じビルドが GPIO のないスクリーンでも動作します。

Player をセットアップする

Raspberry Pi

Raspberry Pi にセットアップは不要です。Linux Player は Pi 3、4、5 のヘッダーチップを自動的に開き、ピンは BCM 番号です。Player のユーザーには /dev/gpiochip* へのアクセス権が必要です。Raspberry Pi OS では既定のユーザーが gpio グループに属しているため、アクセスできます。--kiosk インストールはそのアカウントを video と i2c のグループにのみ追加するので、別の --kiosk-user アカウントには gpio グループを付与し、Player を再起動してください:

sudo usermod -aG gpio KIOSK_USER

他の Linux ボード

他のボードでは、Player の起動環境で SCREENRIG_GPIO_CHIP を使い、ラインを持つチップを指定します:

SCREENRIG_GPIO_CHIP=/dev/gpiochip4

--kiosk インストールでは、sudo systemctl edit screenrig-player-kiosk.service でサービスに追加します:

[Service]
Environment=SCREENRIG_GPIO_CHIP=/dev/gpiochip4

ピンはそのチップのライン番号になります。Player のユーザーには、チップのデバイスファイルへのアクセス権が必要です。

Android

Android では、サイネージボードやカスタムイメージなど、デバイスが書き込み可能な sysfs GPIO チップを公開している場合に GPIO を使えます。ピンはチップのグローバルなライン番号です。標準的なテレビボックスにはそのようなチップがなく、アプリケーションは device.gpio を false として認識します。Player は、アプリケーションが使っている間だけラインを保持します。Android では入力のプルを設定できないため、ボタンを配線するのように抵抗を配線してください。

ピンを選ぶ

pin は 0〜255 の整数で、チップのライン番号です。Raspberry Pi では BCM 番号、つまり Pi のドキュメントが示す GPIO 番号で、ヘッダー上のピンの位置ではありません。GPIO17 は物理ピン 11 です。よく使うライン:

BCM 番号(pin)物理ピン注記
1711最初に使うのに適したライン
2713
2215
2316
2418
2522
529
631
1232
1333
1636
2637
2038
2140
2 と 33 と 5I2C ライン。プルアップが固定されているため、I2C 用に空けておきます
14 と 158 と 10シリアルコンソールのライン
0 と 127 と 28HAT の識別用に予約

グランドは物理ピン 6、9、14、20、25、30、34、39、3.3 V はピン 1 と 17 です。ヘッダー全体は Raspberry Pi のドキュメントに一覧があります。別のプログラムがすでに保持しているラインは pin_busy で、チップにないラインは pin_not_found で拒否されます。

ボタンを配線する

押しボタンを GPIO ラインとグランドの間に配線し、そのラインのプルアップを有効にします。ボタンを押すまでラインは high を読み取り、押すとグランドに引かれるため、押下は low として読み取られます。

 GPIO17 (pin 11) -----+
                      |
                   [ button ]
                      |
 GND (pin 9) ---------+

Raspberry Pi など Linux ボードでは、pull: "up" で Player にプルアップを要求します:

window.screenrig.device.gpio.onChange(17, handlePress, { pull: "up" });

pull: "down" は 3.3 V に配線したボタンに適しており、押すと high を読み取ります。"none" が既定です。Player はバイアスを設定しないため、何も接続していない入力はフローティングになり、抵抗のないボタンはランダムな変化を読み取ります。

Android はプルを設定しないため、グランドに配線したボタンには、ラインから 3.3 V へ約 10 kΩ の抵抗(プルアップ)を追加してください。BrightSign は入力にプルアップを内蔵しており、グランドに配線したボタンはそのまま動作します。

設定できない Player で "up" または "down" を要求しても、ハンドラーは停止しません。SDK はプルなしでラインを監視し、コード gpio_pull_unsupported で warn エントリを 1 件ログに記録します。

リレーを駆動する

リレーは、ピンから直接ではなく、必ずリレーボード経由で駆動してください。ピンが供給できるのは 3.3 V でわずか数ミリアンペアであり、リレーコイル、ドアストライク、積層表示灯、ブザーを切り替えることはできず、コイルの電圧スパイクでボードが損傷することがあります。リレーボードには、トランジスタとコイルの保護回路が載っています。

 5V (pin 2) -------------- VCC |
 GND (pin 6) ------------- GND | relay board
 GPIO27 (pin 13) --------- IN1 |
                               |  COM ---- supply for the load
                               |  NO  ---- the load (door strike, light, buzzer)

負荷には、リレーの接点を介して専用の電源から給電してください。入力が 3.3 V でトリガーされるボードを選びます。

const sr = window.screenrig;
await sr.device.gpio.write(27, true);   // relay on
await sr.device.gpio.write(27, false);  // relay off

ほとんどのボードは high で通電します。安価なボードの多くはアクティブローで、入力が low にされるとリレーが通電します。アクティブローのボードには idle: true を渡して、ページが離れたときにリレーがオフで解放されるようにしてください。アイドル時のレベルを参照してください。

await sr.device.gpio.write(27, false, { idle: true }); // active-low board: relay on
await sr.device.gpio.write(27, true, { idle: true });  // relay off

BrightSign の出力は 100 Ω を介した 3.3 V なので、BrightSign も同じ方法でリレーボードを駆動します。

3.3 V のみ

すべての GPIO ラインは 3.3 V ロジックです。Raspberry Pi のピンは 5 V トレラントではなく、ピンに 5 V を加えるとボードが損傷することがあります。接続できるのは無電圧接点だけです:ボタン、スイッチ、自身の電圧を持たないリレー出力。5 V、12 V、24 V、商用電源の電圧を出力するセンサーは、ピンとの間にレベルシフター、フォトカプラー、リレーが必要です。

チャタリング除去

機械式の接点はチャタリングを起こします。数ミリ秒の間、押下は high と low の間でちらつきます。Player は接点のチャタリングを除去するため、ハンドラーは押下を 1 回の変化、解放をもう 1 回の変化として受け取ります。Linux や Raspberry Pi のラインは、約 20 ms 以内に落ち着く変化を無視します。コードを書く必要はありません。それより短いパルスは GPIO 入力の用途ではありません。

ラインを検知する

onChange(pin, handler, options) はラインを監視します。ハンドラーはレベルをブール値で受け取り、high の場合は true です。最初の呼び出しには Player が監視を開始した時点のラインのレベルが渡され、以降の呼び出しは変化のたびに行われます。この呼び出しは、監視を停止する関数を返します。

const stop = window.screenrig.device.gpio.onChange(17, function (high) {
  doorOpen = high;
}, { pull: "up" });

同時に監視できるラインは最大 16 本で、17 本目は invalid_request を投げます。1 本のラインに 2 つのハンドラーがある場合、プルを共有します。異なる pull を指定した 2 つ目のハンドラーは、すぐに invalid_request を投げます。

アイドル時のレベル

write(pin, value, options) は idle オプションを受け取ります。これは、ページがラインを解放するときに Player がラインを駆動するレベルで、既定は low です。ページは、画面から離れたとき、コンテキストが終了したとき、screenrig.destroy() を呼び出したときにラインを解放します。その後 Player はラインを解放します。ピンへの最新の書き込みがアイドル時のレベルを決めます。

このため、ページが切り替わってもリレーは通電したままになりません。idle は、お使いのボードで「オフ」を意味するレベルに設定してください:ほとんどのボードは low、アクティブローのボードは high です。

ページが離れたとき

ページが保持するものは、ページとともに終わります。ページが画面から離れると、入力は停止し、すべての出力はアイドル時のレベルになって解放されます。Player が停止したりデバイスの電源が失われたりすると、ラインもなくなります。負荷はそのことを前提に計画してください。停電時に、建物が必要とする状態(施錠または解錠)になるドアストライクを選びます。

制限とエラー

  • ピンは 0〜255 の整数です。
  • 同時に監視できるラインは最大 16 本です。
  • write は、不正な pin、value、idle に対して invalid_request で、チップにないラインに対して pin_not_found で、別のプロセスが保持しているラインに対して pin_busy で、Player が GPIO チップを開けない場合は gpio_unavailable で拒否されます。
  • onChange は、17 本目のラインや競合する pull に対して invalid_request を投げます。拒否された監視はログに記録され、ハンドラーは実行されません。
  • 呼び出しは、何かを送信する前に inert、not_supported、capability_denied を確認します。順序は SDK リファレンスに記載されています。設定できない Player で idle を伴う write は、not_supported で拒否されます。

例:サービス呼び出し

GPIO17 にグランドへ配線したボタンがあると、お客様が支援を求めていることがエージェントに伝わり、GPIO27 の LED またはブザーのリレーが 5 秒間応答します。最初の読み取り値はラインがすでに持っているレベルなので、ハンドラーは high から low への変化にのみ動作します。

const sr = window.screenrig;

function active() {
  return sr.readyState === "active";
}

async function start() {
  if (!sr) return;
  await sr.waitUntilActive();
  await sr.ready();
  if (!sr.supports("device.gpio") || !sr.capabilities["device.gpio"]) return;

  let wasHigh = null;
  sr.device.gpio.onChange(17, function (high) {
    const pressed = wasHigh === true && high === false;
    wasHigh = high;
    if (!pressed || !active()) return;
    sr.emit("service.requested");
    document.getElementById("message").hidden = false;
    sr.device.gpio.write(27, true).catch(function () {});
    setTimeout(function () {
      document.getElementById("message").hidden = true;
      if (active()) sr.device.gpio.write(27, false).catch(function () {});
    }, 5000);
  }, { pull: "up" });
}
start();

ページが画面から離れると、ライン 27 はアイドル時のレベルで解放されます。idle を渡さない限り low なので、ページが切り替わる直前にボタンを押しても、リレーがオンのままになることはありません。

エージェントは、押下のたびにイベントログから読み取ります:

screenrig events list --type application.event --screen-id scr_SCREEN

例:ドア開放入力

GPIO17 にグランドへ配線したリードスイッチは、ドアが閉まると閉じるため、ドアが閉まっているときはラインが low、開いているときは high を読み取ります。ドアが開いている間、ページは通知を表示し、エージェントにも知らせます。

const sr = window.screenrig;
const notice = document.getElementById("door-notice");

function show(open) {
  notice.hidden = !open;
  document.body.classList.toggle("door-open", open);
}

async function start() {
  show(false);
  if (!sr) return;
  await sr.waitUntilActive();
  await sr.ready();
  if (!sr.supports("device.gpio") || !sr.capabilities["device.gpio"]) return;
  sr.device.gpio.onChange(17, function (high) {
    show(high);
    if (sr.readyState === "active") sr.emit(high ? "door.opened" : "door.closed");
  }, { pull: "up" });
}
start();

BrightSign

BrightSign プレーヤーも同じ API を実行します。ピン 0〜7 は GPIO コネクターのラインで、XT、XD、HD モデルのコネクター(DA-15 ソケット)では、ピン 0 がコネクターのライン 0、ピン 7 がライン 7 です。入力には固定のプルアップがあるため、pull は提供されず、グランドに配線したボタンはそのまま動作します。idle は他のすべての Player と同様に動作します。出力は 100 Ω を介した 3.3 V です。リレーはリレーボード経由で駆動してください。

BrightSign は USB 経由でラインのバンクをさらに 2 つ追加します:

ピンそれぞれの概要
0〜7GPIO コネクター
8〜39USB GPIO 拡張ボード、1 台あたり 8 ピン、最大 4 台:ピン 8〜15 が 1 台目、16〜23 が 2 台目、以降も同様です
100〜110BP200 または BP900 のボタンボード、番号 0:ピン 100+k はボタン k を入力として、その LED を出力として扱います
120〜130、140〜150、160〜170ボタンボード 1、2、3 も同様です

ピン 100+k への書き込みはボタン k の LED を点灯させ、ピン 100+k の監視はそのボタンを検知します。接続されていないボードや拡張ボードのピンは pin_not_found で拒否されます。

app dev で試す

screenrig app dev は GPIO をシミュレートします。ハーネスには GPIO チップのスイッチと、3 本のシミュレートされたラインが表示されます:17(low)、27(high)、そして別のプロセスが保持しているため pin_busy で応答する 22 です。上の例では 17 と 27 を使います。ラインのレベルをクリックすると変更でき、アプリケーションがそのラインを監視していれば変化を検知します。アプリケーションからの書き込みはラインを動かし、パネルには設定されたアイドル時のレベルが表示されます。ハーネスは pull と idle を受け付けるため、ビルドは画面に届く前にここで動作します。操作方法は ローカルで開発するを参照してください。

参照

よくある質問

スクリーンはリレーを駆動できますか。
はい。リレーボード経由で行います。アプリケーションがラインを high または low に設定し、ボードがドアストライク、積層表示灯、ブザーを切り替えます。リレーをピンから直接駆動しないでください。
ボタンには抵抗が必要ですか。
Raspberry Pi や他の Linux ボードでは不要です。プルアップを要求し、ボタンをグランドに配線してください。Android では、3.3 V へ約 10 kΩ の抵抗を追加します。BrightSign はプルアップを内蔵しています。
ピンにはどの番号を渡しますか。
Raspberry Pi では BCM 番号:GPIO17 は 17 で、物理ピン 11 にあります。他のボードでは、その GPIO チップのライン番号です。BrightSign では、BrightSign のセクションにあるピン範囲です。
ページが切り替わると、リレーはどうなりますか。
Player はラインをアイドル時のレベルに駆動してから解放します。アプリケーションが別のレベルを選ばない限り low です。アクティブローのリレーボードでは high を選んで、リレーがオフになるようにします。
アプリケーションは常時実行する必要がありますか。
アプリケーションは、ページがスクリーン上にある間、待ち受けます。ページが離れると、入力は停止し、出力はアイドル時のレベルに戻ります。
費用はいくらですか。
screenRIG は無料です。ボード、ボタン、リレーはお客様の負担です。