O que o GPIO faz
As linhas GPIO (entrada/saída de uso geral) são os pinos da placa de um Player que um aplicativo pode ler e acionar um a um. Uma linha é uma entrada que lê alto ou baixo, ou uma saída que o aplicativo define como alta ou baixa.
As entradas percebem o ambiente:
- Um botão de pressão, como um botão de "chamar atendimento" ou de "próxima página".
- Um contato de porta ou janela, um interruptor reed ou uma chave de fim de curso.
- Qualquer sensor com contato seco, como um fluxostato ou uma saída de relé em um detector de movimento.
As saídas agem sobre ele:
- Um relé que libera uma fechadura elétrica, liga uma torre luminosa ou aciona um buzzer.
- Um LED que ilumina um botão.
O aplicativo na tela faz o trabalho por meio de screenrig.device.gpio e conta ao seu agente o que aconteceu com emit, então "atendimento solicitado" aparece no registro de eventos do projeto. Seu agente cria o aplicativo, envia e o coloca na tela como qualquer outro. A página de hardware mostra o que mais um aplicativo pode acessar.
Quais Players têm GPIO
| Player | GPIO | Pull da entrada | Nível de repouso da saída | Números de pino |
|---|---|---|---|---|
| Raspberry Pi 3, 4 e 5 (Player Linux) | Sim, no header de 40 pinos. O Player encontra sozinho o chip do header | "up", "down" ou "none" | Sim | Os números BCM |
| Outras placas Linux | Sim, com SCREENRIG_GPIO_CHIP | "up", "down" ou "none" | Sim | Os números de linha desse chip |
| Android e Amazon Signage Stick | Onde o dispositivo expõe um chip GPIO sysfs gravável | Não: adicione um resistor | Sim | Os números de linha desse chip |
| BrightSign | Sim: pinos 0 a 7 no conector GPIO, ou um adaptador USB para GPIO da BrightSign | Pull-ups integrados | Sim | Pinos 0 a 7 e as faixas na seção BrightSign |
| macOS, Windows, o app web do Player, Samsung Smart Signage (Tizen), LG webOS Signage | Não | Não | Não | Não |
A flag vai para o controlador da página, ou para o aplicativo que está sozinho na página. Um aplicativo vê capabilities["device.gpio"] como true somente em um Player e em um dispositivo que tenham GPIO, então uma mesma versão também roda em uma tela sem ele.
Configure o Player
Raspberry Pi
Um Raspberry Pi não precisa de configuração. O Player Linux abre sozinho o chip do header de um Pi 3, 4 ou 5, e um pino é o seu número BCM. O usuário do Player precisa de acesso a /dev/gpiochip*. No Raspberry Pi OS, o usuário padrão pertence ao grupo gpio, que concede esse acesso. Uma instalação --kiosk adiciona sua conta apenas aos grupos video e i2c, então dê o grupo gpio a uma conta --kiosk-user diferente e reinicie o Player:
sudo usermod -aG gpio KIOSK_USEROutras placas Linux
Em outra placa, indique o chip que traz as linhas com SCREENRIG_GPIO_CHIP, no ambiente de inicialização do Player:
SCREENRIG_GPIO_CHIP=/dev/gpiochip4Para uma instalação --kiosk, adicione-o ao serviço com sudo systemctl edit screenrig-player-kiosk.service:
[Service]
Environment=SCREENRIG_GPIO_CHIP=/dev/gpiochip4Um pino é então um número de linha desse chip. O usuário do Player precisa de acesso ao arquivo de dispositivo do chip.
Android
O Android tem GPIO quando o dispositivo expõe um chip GPIO sysfs gravável, como uma placa de digital signage ou uma imagem personalizada. Um pino é o número global de linha do chip. Uma TV box padrão não tem esse chip, e o aplicativo vê device.gpio como false. O Player mantém uma linha somente enquanto o aplicativo a usa. O Android não consegue definir o pull de uma entrada: ligue um resistor, como em Ligue um botão.
Escolha um pino
pin é um número inteiro de 0 a 255: o número da linha do chip. Em um Raspberry Pi, é o número BCM, o número GPIO que a documentação do Pi nomeia, e não a posição do pino no header. GPIO17 é o pino físico 11. Linhas comuns:
Número BCM (o pin) | Pino físico | Nota |
|---|---|---|
| 17 | 11 | Uma boa primeira linha |
| 27 | 13 | |
| 22 | 15 | |
| 23 | 16 | |
| 24 | 18 | |
| 25 | 22 | |
| 5 | 29 | |
| 6 | 31 | |
| 12 | 32 | |
| 13 | 33 | |
| 16 | 36 | |
| 26 | 37 | |
| 20 | 38 | |
| 21 | 40 | |
| 2 e 3 | 3 e 5 | Linhas I2C com pull-ups fixos; deixe-as para o I2C |
| 14 e 15 | 8 e 10 | As linhas do console serial |
| 0 e 1 | 27 e 28 | Reservados para a identificação de HAT |
O terra são os pinos físicos 6, 9, 14, 20, 25, 30, 34 e 39, e 3.3 V são os pinos 1 e 17. A documentação do Raspberry Pi lista o header inteiro. Uma linha que outro programa já mantém rejeita com pin_busy, e uma linha que o chip não tem rejeita com pin_not_found.
Acione um relé
Acione um relé por meio de uma placa de relé, e nunca diretamente de um pino. Um pino fornece alguns miliampères a 3.3 V, o que não consegue acionar a bobina de um relé, uma fechadura elétrica, uma torre luminosa nem um buzzer, e o pico de tensão de uma bobina pode danificar a placa. Uma placa de relé traz o transistor e a proteção da bobina.
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)Alimente a carga com a fonte própria dela, por meio dos contatos do relé. Escolha uma placa cuja entrada seja acionada com 3.3 V.
const sr = window.screenrig;
await sr.device.gpio.write(27, true); // relay on
await sr.device.gpio.write(27, false); // relay offA maioria das placas energiza em nível alto. Muitas placas baratas são ativas em nível baixo: o relé energiza quando a entrada é puxada para baixo. Passe idle: true para uma placa ativa em nível baixo, de modo que uma página que sai libere o relé como desligado. Veja Nível de repouso.
await sr.device.gpio.write(27, false, { idle: true }); // active-low board: relay on
await sr.device.gpio.write(27, true, { idle: true }); // relay offUma saída em um BrightSign é 3.3 V por 100 Ω, então um BrightSign aciona uma placa de relé da mesma forma.
Somente 3.3 V
Toda linha GPIO usa lógica de 3.3 V. Os pinos de um Raspberry Pi não toleram 5 V, e 5 V em um pino pode danificar a placa. Conecte apenas contatos secos: um botão, um interruptor ou uma saída de relé que não carrega tensão própria. Um sensor com saída de 5 V, 12 V, 24 V ou tensão da rede elétrica precisa de um conversor de nível, um optoacoplador ou um relé entre ele e o pino.
Debounce
Um contato mecânico faz repique: por alguns milissegundos, um pressionamento oscila entre alto e baixo. O Player filtra o repique de contato, então o manipulador recebe um pressionamento como uma mudança e a liberação como mais uma. Uma linha no Linux ou no Raspberry Pi ignora mudanças que se estabilizam em cerca de 20 ms. Nenhum código seu é necessário, e um pulso mais curto que isso não é um uso para a entrada GPIO.
Monitorar uma linha
onChange(pin, handler, options) monitora uma linha. O manipulador recebe o nível como booleano, true para alto. A primeira chamada traz o nível que a linha tem quando o Player começa a monitorar, e cada chamada seguinte é uma mudança. A chamada retorna uma função que interrompe o monitoramento.
const stop = window.screenrig.device.gpio.onChange(17, function (high) {
doorOpen = high;
}, { pull: "up" });No máximo 16 linhas são monitoradas ao mesmo tempo, e uma 17ª lança invalid_request. Dois manipuladores em uma linha compartilham o pull dela: um segundo manipulador com pull diferente lança invalid_request imediatamente.
Nível de repouso
write(pin, value, options) aceita a opção idle, o nível para o qual o Player leva a linha quando a página a libera. O padrão é baixo. A página libera uma linha quando sai da tela, quando seu contexto termina e quando chama screenrig.destroy(). O Player então libera a linha. A gravação mais recente para um pino define seu nível de repouso.
É por isso que um relé não permanece energizado depois que a página sai. Defina idle como o nível que significa "desligado" para a sua placa: baixo na maioria das placas, alto em uma placa ativa em nível baixo.
Quando a página sai
O que uma página mantém termina com a página. Quando ela sai da tela, suas entradas param e toda saída vai para o nível de repouso e é liberada. Quando o Player para ou o dispositivo perde energia, as linhas vão junto. Planeje a carga considerando isso: escolha uma fechadura elétrica que trave ou destrave da forma que o prédio precisa quando falta energia.
Limites e erros
- Um pino é um número inteiro de 0 a 255.
- No máximo 16 linhas são monitoradas ao mesmo tempo.
writerejeita cominvalid_requestumpin,valueouidleinválido, compin_not_founduma linha que o chip não tem, compin_busyuma linha que outro processo mantém e comgpio_unavailablequando o Player não consegue abrir nenhum chip GPIO.onChangelançainvalid_requestpara uma 17ª linha ou umpullconflitante. Um monitoramento recusado é registrado em log, e o manipulador nunca é executado.- Uma chamada verifica
inert,not_supportedecapability_deniedantes de enviar qualquer coisa. A referência do SDK lista a ordem. Umwritecomidlerejeita comnot_supportedem um Player que não consegue defini-lo.
Exemplo: chamar atendimento
Um botão no GPIO17, ligado ao terra, avisa seu agente de que um cliente quer ajuda, e um LED ou relé de buzzer no GPIO27 responde por cinco segundos. A primeira leitura é o nível que a linha já tem, então o manipulador age somente em uma mudança de alto para baixo.
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 a página sai da tela, a linha 27 é liberada em seu nível de repouso, baixo a menos que você passe idle, então um botão pressionado logo antes de a página sair não deixa o relé ligado.
Seu agente lê cada pressionamento no registro de eventos:
screenrig events list --type application.event --screen-id scr_SCREENExemplo: entrada de porta aberta
Um interruptor reed no GPIO17, ligado ao terra, fecha quando a porta está fechada, então a linha lê baixo com a porta fechada e alto com ela aberta. A página mostra um aviso enquanto a porta está aberta e avisa seu 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
Um player BrightSign executa a mesma API. Os pinos 0 a 7 são as linhas do conector GPIO, o conector dos modelos XT, XD e HD (um soquete DA-15); o pino 0 é a linha 0 do conector e o pino 7 a sua linha 7. Suas entradas têm pull-ups fixos, então pull não é oferecido e um botão ligado ao terra funciona como está. idle funciona como em todo Player. As saídas são 3.3 V por 100 Ω: acione um relé por meio de uma placa de relé.
Um BrightSign acrescenta mais dois bancos de linhas por USB:
| Pinos | O que são |
|---|---|
| 0 a 7 | O conector GPIO |
| 8 a 39 | Expansores GPIO USB, 8 pinos cada, até 4: os pinos 8 a 15 são o primeiro expansor, 16 a 23 o segundo, e assim por diante |
| 100 a 110 | Uma placa de botões BP200 ou BP900, número 0: o pino 100+k é o botão k como entrada, e o LED dele como saída |
| 120 a 130, 140 a 150 e 160 a 170 | Placas de botões 1, 2 e 3, da mesma forma |
Uma gravação no pino 100+k acende o LED do botão k, e um monitoramento no pino 100+k recebe o botão. Uma placa ou um expansor que não está conectado faz seus pinos rejeitarem com pin_not_found.
Experimente no app dev
screenrig app dev simula o GPIO. O ambiente de teste mostra um interruptor de chip GPIO e três linhas simuladas: 17 (baixa), 27 (alta) e 22, que outro processo mantém e por isso responde pin_busy. Os exemplos acima usam 17 e 27. Clique no nível de uma linha para alterá-lo, e seu aplicativo recebe a mudança quando monitora a linha. Uma gravação do aplicativo move a linha, e o painel mostra o nível de repouso que ela definiu. O ambiente de teste aceita pull e idle, então uma versão roda ali antes de chegar a uma tela. Desenvolver localmente descreve os controles.
Referência
screenrig.device.gpio.write()escreenrig.device.gpio.onChange()na referência do SDK.- Hardware que um aplicativo pode usar: todos os Players e todas as capacidades do dispositivo.
- Digital signage com Raspberry Pi: o Pi como tela.
- Linux e Raspberry Pi: instale o Player.
Perguntas
- Uma tela pode acionar um relé?
- Sim, por meio de uma placa de relé. Um aplicativo define uma linha como alta ou baixa, e a placa aciona a fechadura elétrica, a torre luminosa ou o buzzer. Nunca acione um relé diretamente de um pino.
- Um botão precisa de um resistor?
- Em um Raspberry Pi ou outra placa Linux, não: peça o pull-up e ligue o botão ao terra. No Android, adicione um resistor de cerca de 10 kΩ a 3.3 V. Um BrightSign tem pull-ups integrados.
- Qual número devo passar para um pino?
- Em um Raspberry Pi, o número BCM: GPIO17 é 17 e fica no pino físico 11. Em outra placa, o número de linha do chip GPIO dela. Em um BrightSign, as faixas de pinos na seção BrightSign.
- O que acontece com um relé quando a página muda?
- O Player leva a linha ao seu nível de repouso, baixo a menos que o aplicativo tenha escolhido outro, e a libera. Escolha alto para uma placa de relé ativa em nível baixo, de modo que o relé fique desligado.
- O aplicativo precisa ficar em execução o tempo todo?
- O aplicativo escuta enquanto sua página está na tela. Quando a página sai, as entradas param e as saídas vão para o nível de repouso.
- Quanto custa?
- O screenRIG é gratuito. A placa, o botão e o relé são custo seu.