Documentazione

Pulsanti e relè su GPIO

Collega un pulsante, un contatto porta o una scheda relè ai pin GPIO di uno schermo, e l’applicazione sullo schermo rileva il pulsante, pilota il relè e riferisce al tuo agente.

Che cosa fa il GPIO

Le linee GPIO (general-purpose input/output, ingresso/uscita generico) sono i pin della scheda di un Player che un’applicazione può leggere e pilotare uno alla volta. Una linea è un ingresso che legge alto o basso, oppure un’uscita che l’applicazione imposta alta o bassa.

Gli ingressi percepiscono l’ambiente:

  • Un pulsante, come uno di “chiamata assistenza” o “pagina successiva”.
  • Un contatto di porta o finestra, un contatto reed o un finecorsa.
  • Qualsiasi sensore con contatto pulito, come un flussostato o un’uscita a relè su un rilevatore di movimento.

Le uscite agiscono sull’ambiente:

  • Un relè che sblocca un’elettroserratura, accende una torretta luminosa o fa suonare un cicalino.
  • Un LED che illumina un pulsante.

L’applicazione sullo schermo fa il lavoro tramite screenrig.device.gpio e comunica al tuo agente che cosa è successo con emit, così “assistenza richiesta” compare nel registro eventi del progetto. Il tuo agente crea l’applicazione, la carica e la colloca sullo schermo come qualsiasi altra. La pagina hardware mostra che altro può raggiungere un’applicazione.

Quali Player hanno il GPIO

PlayerGPIOPull dell’ingressoLivello di riposo dell’uscitaNumeri di pin
Raspberry Pi 3, 4 e 5 (Player Linux)Sì, sull’header a 40 pin. Il Player trova da solo il chip dell’header"up", "down" o "none"SìI numeri BCM
Altre schede LinuxSì, con SCREENRIG_GPIO_CHIP"up", "down" o "none"SìI numeri di linea di quel chip
Android e Amazon Signage StickDove il dispositivo espone un chip GPIO sysfs scrivibileNo: aggiungi una resistenzaSìI numeri di linea di quel chip
BrightSignSì: pin da 0 a 7 sul connettore GPIO, oppure un adattatore USB-GPIO BrightSignPull-up integratiSìPin da 0 a 7 e gli intervalli nella sezione BrightSign
macOS, Windows, l’app web Player, Samsung Smart Signage (Tizen), LG webOS SignageNoNoNoNo

Il flag va al controller della pagina, o all’applicazione che è sola nella sua pagina. Un’applicazione vede capabilities["device.gpio"] come true solo su un Player e un dispositivo che ha il GPIO, così una stessa build gira anche su uno schermo che non lo ha.

Configura il Player

Raspberry Pi

Un Raspberry Pi non richiede configurazione. Il Player Linux apre da solo il chip dell’header di un Pi 3, 4 o 5, e un pin è il suo numero BCM. L’utente del Player deve avere accesso a /dev/gpiochip*. Su Raspberry Pi OS l’utente predefinito appartiene al gruppo gpio, che lo concede. Un’installazione --kiosk aggiunge il suo account solo ai gruppi video e i2c, quindi dai a un account --kiosk-user diverso il gruppo gpio e riavvia il Player:

sudo usermod -aG gpio KIOSK_USER

Altre schede Linux

Su un’altra scheda, indica il chip che porta le linee con SCREENRIG_GPIO_CHIP, nell’ambiente di avvio del Player:

SCREENRIG_GPIO_CHIP=/dev/gpiochip4

Per un’installazione --kiosk, aggiungilo al servizio con sudo systemctl edit screenrig-player-kiosk.service:

[Service]
Environment=SCREENRIG_GPIO_CHIP=/dev/gpiochip4

Un pin è allora un numero di linea di quel chip. L’utente del Player deve avere accesso al file di dispositivo del chip.

Android

Android ha il GPIO dove il dispositivo espone un chip GPIO sysfs scrivibile, come una scheda per signage o un’immagine personalizzata. Un pin è il numero di linea globale del chip. Una TV box standard non ha un chip simile, e l’applicazione vede device.gpio come false. Il Player trattiene una linea solo finché l’applicazione la usa. Android non può impostare il pull di un ingresso: collega una resistenza, come in Collega un pulsante.

Scegli un pin

pin è un intero da 0 a 255: il numero di linea del chip. Su un Raspberry Pi è il numero BCM, il numero GPIO riportato nella documentazione del Pi, e non la posizione del pin sull’header. GPIO17 è il pin fisico 11. Linee comuni:

Numero BCM (il pin)Pin fisicoNota
1711Una buona prima linea
2713
2215
2316
2418
2522
529
631
1232
1333
1636
2637
2038
2140
2 e 33 e 5Linee I2C con pull-up fissi; lasciale per I2C
14 e 158 e 10Le linee della console seriale
0 e 127 e 28Riservato all’identificazione HAT

La massa sono i pin fisici 6, 9, 14, 20, 25, 30, 34 e 39, e 3.3 V sono i pin 1 e 17. La documentazione di Raspberry Pi elenca l’intero header. Una linea che un altro programma già occupa rifiuta con pin_busy, e una linea che il chip non ha rifiuta con pin_not_found.

Collega un pulsante

Collega un pulsante tra una linea GPIO e la massa, e attiva il pull-up di quella linea. La linea legge alto finché il pulsante non viene premuto, e una pressione la porta a massa, quindi una pressione legge basso.

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

Su un Raspberry Pi o un’altra scheda Linux, chiedi il pull-up al Player con pull: "up":

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

pull: "down" è adatto a un pulsante collegato a 3.3 V, che legge alto quando viene premuto. "none" è il valore predefinito: il Player non imposta alcuna polarizzazione, quindi un ingresso senza nulla di collegato resta flottante e un pulsante senza resistenza legge variazioni casuali.

Android non imposta alcun pull, quindi aggiungi una resistenza di circa 10 kΩ dalla linea a 3.3 V (un pull-up) per un pulsante collegato a massa. Un BrightSign ha pull-up integrati sui suoi ingressi, e un pulsante collegato a massa funziona così com’è.

Richiedere "up" o "down" su un Player che non può impostarlo non ferma il gestore: l’SDK osserva la linea senza pull e registra una voce warn con il codice gpio_pull_unsupported.

Pilota un relè

Pilota un relè tramite una scheda relè, e mai direttamente da un pin. Un pin fornisce pochi milliampere a 3.3 V, che non bastano per comandare la bobina di un relè, un’elettroserratura, una torretta luminosa o un cicalino, e il picco di tensione di una bobina può danneggiare la scheda. Una scheda relè ha il transistor e la protezione della bobina a bordo.

 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)

Alimenta il carico dalla sua alimentazione, attraverso i contatti del relè. Scegli una scheda il cui ingresso scatta a 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 maggior parte delle schede si eccita su alto. Molte schede economiche sono attive basse: il relè si eccita quando l’ingresso viene portato a livello basso. Passa idle: true per una scheda attiva bassa, così una pagina che esce rilascia il relè come spento. Vedi Livello di riposo.

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

Un’uscita su un BrightSign è a 3.3 V attraverso 100 Ω, quindi un BrightSign pilota una scheda relè allo stesso modo.

Solo 3.3 V

Ogni linea GPIO è a logica 3.3 V. I pin di un Raspberry Pi non tollerano 5 V, e 5 V su un pin può danneggiare la scheda. Collega solo contatti puliti: un pulsante, un interruttore o un’uscita a relè che non porta alcuna tensione propria. Un sensore con uscita a 5 V, 12 V, 24 V o tensione di rete richiede un convertitore di livello, un optoisolatore o un relè tra lui e il pin.

Antirimbalzo

Un contatto meccanico rimbalza: per pochi millisecondi la pressione oscilla tra alto e basso. Il Player filtra il rimbalzo dei contatti, quindi il gestore rileva una pressione come un solo cambio e il rilascio come un altro. Una linea Linux o Raspberry Pi ignora i cambi che si stabilizzano entro circa 20 ms. Non serve alcun codice da parte tua, e un impulso più breve non è un caso d’uso per l’ingresso GPIO.

Ascolta una linea

onChange(pin, handler, options) osserva una linea. Il gestore riceve il livello come booleano, true per alto. La prima chiamata porta il livello che la linea ha quando il Player inizia a osservarla, e ogni chiamata successiva è una variazione. La chiamata restituisce una funzione che interrompe l’osservazione.

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

Al massimo 16 linee sono osservate contemporaneamente, e una 17ª genera invalid_request. Due gestori su una linea condividono il suo pull: un secondo gestore con un pull diverso genera subito invalid_request.

Livello di riposo

write(pin, value, options) accetta un’opzione idle, il livello a cui il Player porta la linea quando la pagina la rilascia. Il valore predefinito è basso. La pagina rilascia una linea quando lascia lo schermo, quando il suo contesto termina e quando chiama screenrig.destroy(). Il Player poi rilascia la linea. L’ultima scrittura su un pin imposta il suo livello di riposo.

Ecco perché un relè non resta eccitato dopo che la pagina è andata via. Imposta idle sul livello che significa “spento” per la tua scheda: basso per la maggior parte delle schede, alto per una scheda attiva bassa.

Quando la pagina esce

Ciò che una pagina tiene termina con la pagina. Quando esce dallo schermo, i suoi ingressi si fermano e ogni uscita va al suo livello di riposo e viene rilasciata. Quando il Player si ferma o il dispositivo perde alimentazione, le linee vanno con essi. Pianifica il carico di conseguenza: scegli un’elettroserratura che blocca o sblocca nel modo che serve all’edificio quando manca la corrente.

Limiti ed errori

  • Un pin è un intero da 0 a 255.
  • Al massimo 16 linee sono osservate contemporaneamente.
  • write rifiuta con invalid_request un pin, value o idle non valido, con pin_not_found una linea che il chip non ha, con pin_busy una linea occupata da un altro processo e con gpio_unavailable quando il Player non riesce ad aprire alcun chip GPIO.
  • onChange genera invalid_request per una 17ª linea o per un pull in conflitto. Un’osservazione rifiutata viene registrata nel log e il gestore non viene mai eseguito.
  • Una chiamata controlla inert, not_supported e capability_denied prima di inviare qualsiasi cosa. Il riferimento SDK ne elenca l’ordine. Un write con idle rifiuta con not_supported su un Player che non può impostarlo.

Esempio: chiamata assistenza

Un pulsante su GPIO17, collegato a massa, comunica al tuo agente che un cliente vuole assistenza, e un LED o un relè del cicalino su GPIO27 risponde per cinque secondi. La prima lettura è il livello che la linea ha già, quindi il gestore agisce solo su un cambio da alto a basso.

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

Quando la pagina lascia lo schermo, rilascia la linea 27 al suo livello di riposo, basso salvo che tu passi idle, così un pulsante premuto subito prima che la pagina vada via non lascia il relè acceso.

Il tuo agente legge ogni pressione dal registro eventi:

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

Esempio: ingresso porta aperta

Un contatto reed su GPIO17, collegato a massa, si chiude quando la porta è chiusa, quindi la linea legge basso con la porta chiusa e alto con la porta aperta. La pagina mostra un avviso finché la porta è aperta e lo comunica al tuo agente.

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 player BrightSign esegue la stessa API. I pin da 0 a 7 sono le linee del connettore GPIO, il connettore dei modelli XT, XD e HD (una presa DA-15): il pin 0 è la linea 0 del connettore e il pin 7 la sua linea 7. I suoi ingressi hanno pull-up fissi, quindi pull non è offerto e un pulsante collegato a massa funziona così com’è. idle funziona come su ogni Player. Le uscite sono a 3.3 V attraverso 100 Ω: pilota un relè tramite una scheda relè.

Un BrightSign aggiunge altri due banchi di linee tramite USB:

PinChe cosa sono
da 0 a 7Il connettore GPIO
da 8 a 39Expander GPIO USB, 8 pin ciascuno, fino a 4: i pin da 8 a 15 sono il primo expander, da 16 a 23 il secondo, e così via
da 100 a 110Una scheda pulsanti BP200 o BP900, numero 0: il pin 100+k è il pulsante k come ingresso e il suo LED come uscita
da 120 a 130, da 140 a 150 e da 160 a 170Schede pulsanti 1, 2 e 3, allo stesso modo

Una scrittura sul pin 100+k accende il LED del pulsante k, e un’osservazione sul pin 100+k rileva il pulsante. Una scheda o un expander non collegato fa rifiutare i suoi pin con pin_not_found.

Provalo in app dev

screenrig app dev simula il GPIO. L’harness mostra un interruttore del chip GPIO e tre linee simulate: 17 (basso), 27 (alto) e 22, che un altro processo tiene occupata e che quindi risponde pin_busy. Gli esempi sopra usano 17 e 27. Fai clic sul livello di una linea per cambiarlo, e la tua applicazione rileva la modifica quando osserva la linea. Una scrittura dell’applicazione sposta la linea, e il pannello mostra il livello di riposo che ha impostato. L’harness accetta pull e idle, così una build vi gira prima di arrivare su uno schermo. Sviluppa in locale descrive i controlli.

Riferimento

Domande

Uno schermo può pilotare un relè?
Sì, tramite una scheda relè. Un’applicazione imposta una linea alta o bassa, e la scheda comanda l’elettroserratura, la torretta luminosa o il cicalino. Non pilotare mai un relè direttamente da un pin.
Un pulsante ha bisogno di una resistenza?
Su un Raspberry Pi o un’altra scheda Linux, no: chiedi il pull-up e collega il pulsante a massa. Su Android aggiungi una resistenza di circa 10 kΩ a 3.3 V. Un BrightSign ha i pull-up integrati.
Quale numero passo per un pin?
Su un Raspberry Pi, il numero BCM: GPIO17 è 17 e si trova sul pin fisico 11. Su un’altra scheda, il numero di linea del suo chip GPIO. Su un BrightSign, gli intervalli di pin nella sezione BrightSign.
Che cosa succede a un relè quando la pagina cambia?
Il Player porta la linea al suo livello di riposo, basso salvo diversa scelta dell’applicazione, e la rilascia. Scegli alto per una scheda relè attiva bassa, così il relè è spento.
L’applicazione deve essere sempre in esecuzione?
L’applicazione ascolta finché la sua pagina è sullo schermo. Quando la pagina esce, gli ingressi si fermano e le uscite vanno al loro livello di riposo.
Quanto costa?
screenRIG è gratuito. La scheda, il pulsante e il relè sono a tuo carico.