Documentation

Boutons et relais sur GPIO

Câblez un bouton-poussoir, un contact de porte ou une carte relais aux broches GPIO d’un écran, et l’application sur l’écran perçoit le bouton, pilote le relais et fait rapport à votre agent.

Ce que fait le GPIO

Les lignes GPIO (entrée/sortie à usage général) sont les broches de la carte d’un Player qu’une application peut lire et piloter une à une. Une ligne est une entrée qui lit le niveau haut ou bas, ou une sortie que l’application met au niveau haut ou bas.

Les entrées perçoivent la pièce :

  • Un bouton-poussoir, comme un bouton « appel de service » ou « page suivante ».
  • Un contact de porte ou de fenêtre, un interrupteur à lames souples ou un interrupteur de fin de course.
  • Tout capteur à contact sec, comme un interrupteur de débit ou une sortie de relais sur un détecteur de mouvement.

Les sorties agissent sur la pièce :

  • Un relais qui libère une gâche de porte, commute une colonne lumineuse ou fait retentir un avertisseur sonore.
  • Une DEL qui éclaire un bouton.

L’application sur l’écran fait le travail par screenrig.device.gpio et informe votre agent de ce qui s’est passé avec emit, de sorte que « service demandé » apparaît dans le journal des événements du projet. Votre agent crée l’application, la téléverse et la place sur l’écran comme n’importe quelle autre. La page matériel montre ce qu’une application peut atteindre d’autre.

Quels Players ont du GPIO

PlayerGPIOPull d’entréeNiveau de repos de la sortieNuméros de broche
Raspberry Pi 3, 4 et 5 (Player Linux)Oui, sur la barrette de 40 broches. Le Player trouve de lui-même la puce de la barrette"up", "down" ou "none"OuiLes numéros BCM
Autres cartes LinuxOui, avec SCREENRIG_GPIO_CHIP"up", "down" ou "none"OuiLes numéros de ligne de cette puce
Android et Amazon Signage StickLà où l’appareil expose une puce GPIO sysfs accessible en écritureNon : ajoutez une résistanceOuiLes numéros de ligne de cette puce
BrightSignOui : broches 0 à 7 sur le connecteur GPIO, ou un adaptateur USB-GPIO BrightSignPull-up intégrésOuiBroches 0 à 7, et les plages de la section BrightSign
macOS, Windows, l’application Web Player, Samsung Smart Signage (Tizen), LG webOS SignageNonNonNonNon

L’indicateur va au contrôleur de la page, ou à l’application seule sur sa page. Une application voit capabilities["device.gpio"] comme true seulement sur un Player et un appareil qui ont du GPIO, de sorte qu’une même version s’exécute aussi sur un écran qui n’en a pas.

Configurer le Player

Raspberry Pi

Un Raspberry Pi n’exige aucune configuration. Le Player Linux ouvre de lui-même la puce de la barrette d’un Pi 3, 4 ou 5, et une broche est son numéro BCM. L’utilisateur du Player doit avoir accès à /dev/gpiochip*. Sur Raspberry Pi OS, l’utilisateur par défaut appartient au groupe gpio, qui donne cet accès. Une installation --kiosk ajoute son compte aux groupes video et i2c seulement ; donnez donc à un autre compte --kiosk-user le groupe gpio et redémarrez le Player :

sudo usermod -aG gpio KIOSK_USER

Autres cartes Linux

Sur une autre carte, nommez la puce qui porte les lignes avec SCREENRIG_GPIO_CHIP, dans l’environnement de lancement du Player :

SCREENRIG_GPIO_CHIP=/dev/gpiochip4

Pour une installation --kiosk, ajoutez-le au service avec sudo systemctl edit screenrig-player-kiosk.service :

[Service]
Environment=SCREENRIG_GPIO_CHIP=/dev/gpiochip4

Une broche est alors un numéro de ligne de cette puce. L’utilisateur du Player doit avoir accès au fichier d’appareil de la puce.

Android

Android offre le GPIO là où l’appareil expose une puce GPIO sysfs accessible en écriture, comme une carte d’affichage dynamique ou une image personnalisée. Une broche est le numéro de ligne global de la puce. Un boîtier TV standard n’a pas une telle puce, et l’application voit device.gpio comme faux. Le Player ne détient une ligne que pendant que l’application l’utilise. Android ne peut pas définir le pull d’une entrée : câblez une résistance, comme dans Câbler un bouton.

Choisir une broche

pin est un entier de 0 à 255 : le numéro de ligne de la puce. Sur un Raspberry Pi, c’est le numéro BCM, le numéro GPIO que nomme la documentation du Pi, et non la position de la broche sur la barrette. GPIO17 est la broche physique 11. Lignes courantes :

Numéro BCM (le pin)Broche physiqueRemarque
1711Une bonne première ligne
2713
2215
2316
2418
2522
529
631
1232
1333
1636
2637
2038
2140
2 et 33 et 5Lignes I2C avec pull-up fixes ; laissez-les à l’I2C
14 et 158 et 10Les lignes de la console série
0 et 127 et 28Réservée à l’identification du HAT

La masse correspond aux broches physiques 6, 9, 14, 20, 25, 30, 34 et 39, et le 3.3 V aux broches 1 et 17. La documentation Raspberry Pi liste toute la barrette. Une ligne qu’un autre programme détient déjà rejette pin_busy, et une ligne que la puce n’a pas rejette pin_not_found.

Câbler un bouton

Câblez un bouton-poussoir entre une ligne GPIO et la masse, et activez le pull-up de cette ligne. La ligne lit le niveau haut jusqu’à ce que le bouton soit pressé, et un appui la tire à la masse, donc un appui lit le niveau bas.

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

Sur un Raspberry Pi ou une autre carte Linux, demandez le pull-up au Player avec pull: "up" :

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

pull: "down" convient à un bouton câblé à 3.3 V, qui lit le niveau haut lorsqu’il est enfoncé. "none" est la valeur par défaut : le Player ne définit aucune polarisation, donc une entrée sans rien de branché flotte et un bouton sans résistance lit des changements aléatoires.

Android ne définit aucun pull ; ajoutez donc une résistance d’environ 10 kΩ de la ligne vers 3.3 V (un pull-up) pour un bouton câblé à la masse. Un BrightSign a des pull-up intégrés sur ses entrées, et un bouton câblé à la masse fonctionne tel quel.

Demander "up" ou "down" sur un Player qui ne peut pas le définir n’arrête pas le gestionnaire : le SDK surveille la ligne sans pull et consigne une entrée warn avec le code gpio_pull_unsupported.

Piloter un relais

Pilotez un relais par une carte relais, et jamais directement depuis une broche. Une broche fournit quelques milliampères à 3.3 V, ce qui ne peut pas commuter une bobine de relais, une gâche de porte, une colonne lumineuse ou un avertisseur sonore, et la pointe de tension d’une bobine peut endommager la carte. Une carte relais porte le transistor et la protection de la bobine.

 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)

Alimentez la charge depuis sa propre alimentation par les contacts du relais. Choisissez une carte dont l’entrée se déclenche à 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

La plupart des cartes s’activent au niveau haut. Beaucoup de cartes bon marché sont à niveau bas actif : le relais s’active lorsque l’entrée est tirée au niveau bas. Passez idle: true pour une carte à niveau bas actif afin qu’une page qui quitte laisse le relais désactivé. Voir Niveau de repos.

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

Une sortie sur un BrightSign est à 3.3 V à travers 100 Ω, donc un BrightSign pilote une carte relais de la même façon.

3.3 V seulement

Chaque ligne GPIO est en logique 3.3 V. Les broches d’un Raspberry Pi ne tolèrent pas 5 V, et 5 V sur une broche peut endommager la carte. Ne raccordez que des contacts secs : un bouton, un interrupteur ou une sortie de relais qui ne porte aucune tension propre. Un capteur qui sort 5 V, 12 V, 24 V ou la tension secteur exige un convertisseur de niveau, un optocoupleur ou un relais entre lui et la broche.

Antirebond

Un contact mécanique rebondit : pendant quelques millisecondes, un appui oscille entre le niveau haut et le niveau bas. Le Player filtre les rebonds de contact, de sorte que le gestionnaire perçoit un appui comme un seul changement et le relâchement comme un autre. Une ligne Linux ou Raspberry Pi ignore les changements qui se stabilisent en environ 20 ms. Aucun code de votre part n’est nécessaire, et une impulsion plus courte n’est pas un usage de l’entrée GPIO.

Écouter une ligne

onChange(pin, handler, options) surveille une ligne. Le gestionnaire reçoit le niveau sous forme de booléen, true pour le niveau haut. Le premier appel porte le niveau qu’a la ligne lorsque le Player commence à la surveiller, et chaque appel suivant est un changement. L’appel retourne une fonction qui arrête la surveillance.

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

Au plus 16 lignes sont surveillées à la fois, et une 17e lève invalid_request. Deux gestionnaires sur une même ligne partagent son pull : un second gestionnaire avec un pull différent lève invalid_request aussitôt.

Niveau de repos

write(pin, value, options) accepte une option idle, le niveau vers lequel le Player pilote la ligne lorsque la page la libère. Par défaut, c’est le niveau bas. La page libère une ligne lorsqu’elle quitte l’écran, lorsque son contexte se termine et lorsqu’elle appelle screenrig.destroy(). Le Player libère alors la ligne. La dernière écriture pour une broche définit son niveau de repos.

C’est pourquoi un relais ne reste pas activé après le départ de la page. Réglez idle au niveau qui signifie « désactivé » pour votre carte : bas pour la plupart des cartes, haut pour une carte à niveau bas actif.

Quand la page part

Ce qu’une page détient prend fin avec la page. Lorsqu’elle quitte l’écran, ses entrées s’arrêtent et chaque sortie passe à son niveau de repos et est libérée. Lorsque le Player s’arrête ou que l’appareil perd l’alimentation, les lignes suivent. Planifiez la charge en conséquence : choisissez une gâche de porte qui verrouille ou déverrouille comme le bâtiment l’exige en cas de panne de courant.

Limites et erreurs

  • Une broche est un entier de 0 à 255.
  • Au plus 16 lignes sont surveillées à la fois.
  • write rejette invalid_request pour un pin, value ou idle invalide, pin_not_found pour une ligne que la puce n’a pas, pin_busy pour une ligne qu’un autre processus détient et gpio_unavailable lorsque le Player ne peut ouvrir aucune puce GPIO.
  • onChange lève invalid_request pour une 17e ligne ou un pull en conflit. Une surveillance refusée est consignée, et le gestionnaire ne s’exécute jamais.
  • Un appel vérifie inert, not_supported et capability_denied avant d’envoyer quoi que ce soit. La référence du SDK en donne l’ordre. Un write avec idle rejette not_supported sur un Player qui ne peut pas le définir.

Exemple : appel de service

Un bouton sur GPIO17, câblé à la masse, indique à votre agent qu’un client veut de l’aide, et une DEL ou un relais d’avertisseur sur GPIO27 répond pendant cinq secondes. La première lecture est le niveau que la ligne a déjà, de sorte que le gestionnaire n’agit que sur un passage du niveau haut au niveau bas.

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();

Lorsque la page quitte l’écran, elle libère la ligne 27 à son niveau de repos, le niveau bas sauf si vous passez idle, de sorte qu’un bouton pressé juste avant le départ de la page ne laisse pas le relais activé.

Votre agent lit chaque appui dans le journal des événements :

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

Exemple : entrée porte ouverte

Un interrupteur à lames souples sur GPIO17, câblé à la masse, se ferme lorsque la porte est fermée ; la ligne lit donc le niveau bas porte fermée et le niveau haut porte ouverte. La page affiche un avis tant que la porte est ouverte et en informe votre agent.

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

Un lecteur BrightSign exécute la même API. Les broches 0 à 7 sont les lignes du connecteur GPIO, le connecteur des modèles XT, XD et HD (une prise DA-15), la broche 0 est la ligne 0 du connecteur et la broche 7 sa ligne 7. Ses entrées ont des pull-up fixes, donc pull n’est pas offert et un bouton câblé à la masse fonctionne tel quel. idle fonctionne comme sur tous les Players. Les sorties sont à 3.3 V à travers 100 Ω : pilotez un relais par une carte relais.

Un BrightSign ajoute deux autres banques de lignes par USB :

BrochesCe qu’elles sont
0 à 7Le connecteur GPIO
8 à 39Expanseurs GPIO USB, 8 broches chacun, jusqu’à 4 : les broches 8 à 15 sont le premier expanseur, 16 à 23 le deuxième, et ainsi de suite
100 à 110Une carte de boutons BP200 ou BP900, numéro 0 : la broche 100+k est le bouton k en entrée, et sa DEL en sortie
120 à 130, 140 à 150 et 160 à 170Cartes de boutons 1, 2 et 3, de la même façon

Une écriture sur la broche 100+k allume la DEL du bouton k, et une surveillance sur la broche 100+k perçoit le bouton. Une carte ou un expanseur non connecté fait rejeter pin_not_found à ses broches.

Essayer dans app dev

screenrig app dev simule le GPIO. Le banc d’essai affiche un interrupteur de puce GPIO et trois lignes simulées : 17 (bas), 27 (haut) et 22, qu’un autre processus détient et qui répond donc pin_busy. Les exemples ci-dessus utilisent 17 et 27. Cliquez sur le niveau d’une ligne pour le changer, et votre application est avertie du changement lorsqu’elle surveille la ligne. Une écriture de l’application déplace la ligne, et le panneau affiche le niveau de repos qu’elle a défini. Le banc d’essai accepte pull et idle, de sorte qu’une version s’y exécute avant d’atteindre un écran. Développer en local décrit les contrôles.

Référence

Questions

Un écran peut-il piloter un relais ?
Oui, par une carte relais. Une application met une ligne au niveau haut ou bas, et la carte commute la gâche de porte, la colonne lumineuse ou l’avertisseur. Ne pilotez jamais un relais directement depuis une broche.
Un bouton a-t-il besoin d’une résistance ?
Sur un Raspberry Pi ou une autre carte Linux, non : demandez le pull-up et câblez le bouton à la masse. Sur Android, ajoutez une résistance d’environ 10 kΩ vers 3.3 V. Un BrightSign a des pull-up intégrés.
Quel numéro dois-je passer pour une broche ?
Sur un Raspberry Pi, le numéro BCM : GPIO17 est 17 et se trouve à la broche physique 11. Sur une autre carte, le numéro de ligne de sa puce GPIO. Sur un BrightSign, les plages de broches de la section BrightSign.
Que devient un relais quand la page change ?
Le Player pilote la ligne vers son niveau de repos, le niveau bas sauf si l’application en a choisi un autre, puis la libère. Choisissez le niveau haut pour une carte relais à niveau bas actif afin que le relais soit désactivé.
L’application doit-elle fonctionner en permanence ?
L’application écoute tant que sa page est à l’écran. Lorsque la page part, les entrées s’arrêtent et les sorties passent à leur niveau de repos.
Combien cela coûte-t-il ?
screenRIG est gratuit. La carte, le bouton et le relais sont à votre charge.