Utilizar GPIO para entrada binária
Os pinos de E/S para fins gerais (GPIO) podem ser configurados para receber sinais elétricos como entrada. No seu nível mais básico, isto é útil para cenários que detetam a abertura/fecho de um circuito. Estes circuitos podem incluir botões de pressão, interruptores de alternar, interruptores de junco, interruptores de pressão e outros dispositivos que representam valores binários (ligados/desligados) ao concluir um circuito.
Neste tutorial, irá utilizar o .NET e os pinos GPIO do Raspberry Pi para detetar a abertura e o fecho de um circuito.
Pré-requisitos
- Computador de quadro único (SBC) baseado em ARM (ARMv7 ou superior)
- Fios jumper
- Breadboard (opcional)
- Placa simultânea raspberry Pi GPIO (opcional)
- SDK .NET 7 ou posterior
Nota
Este tutorial é escrito partindo do princípio de que o dispositivo de destino é Raspberry Pi. No entanto, este tutorial pode ser utilizado para qualquer SBC baseado em Linux que suporte .NET, como Orange Pi, ODROID e muito mais.
Certifique-se de que o SSH está ativado no seu dispositivo. Para Raspberry Pi, consulte Configurar um Servidor SSH na documentação do Raspberry Pi.
Preparar o hardware
Utilize os componentes de hardware para criar o circuito, conforme descrito no diagrama seguinte:
A imagem acima ilustra uma ligação direta entre um pino no chão e o pino 21.
Dica
O diagrama ilustra uma fuga de breadboard e GPIO para fins ilustrativos, mas sinta-se à vontade para apenas ligar um pino moído e afixar 21 com um fio de saltador no Raspberry Pi.
Veja o seguinte diagrama de pinout, conforme necessário:
Imagem cortesia Raspberry Pi Foundation.
Criar a aplicação
Conclua os seguintes passos no seu ambiente de desenvolvimento preferencial:
Crie uma nova Aplicação de Consola .NET com a CLI do .NET ou o Visual Studio. Dê-lhe o nome InputTutorial.
dotnet new console -o InputTutorial cd InputTutorial
Adicione o pacote System.Device.Gpio ao projeto. Utilize a CLI de .NET a partir do diretório do projeto ou do Visual Studio.
dotnet add package System.Device.Gpio --version 2.2.0-*
Substitua o conteúdo do ficheiro Program.cs pelo seguinte código:
using System.Device.Gpio; using System.Threading.Tasks; const int Pin = 21; const string Alert = "ALERT 🚨"; const string Ready = "READY ✅"; using var controller = new GpioController(); controller.OpenPin(Pin, PinMode.InputPullUp); Console.WriteLine( $"Initial status ({DateTime.Now}): {(controller.Read(Pin) == PinValue.High ? Alert : Ready)}"); controller.RegisterCallbackForPinValueChangedEvent( Pin, PinEventTypes.Falling | PinEventTypes.Rising, OnPinEvent); await Task.Delay(Timeout.Infinite); static void OnPinEvent(object sender, PinValueChangedEventArgs args) { Console.WriteLine( $"({DateTime.Now}) {(args.ChangeType is PinEventTypes.Rising ? Alert : Ready)}"); }
No código anterior:
- Uma declaração de utilização cria uma instância de
GpioController
. Ausing
declaração garante que o objeto é eliminado e que os recursos de hardware são libertados corretamente.-
GpioController
é instanciado sem parâmetros, o que indica que deve detetar em que plataforma de hardware está a ser executada e utilizar o esquema de numeração de pinos lógico.
-
- O pino GPIO 21 é aberto com
PinMode.InputPullUp
.- Esta ação abre o marcador com uma resistência PullUp ativada. Neste modo, quando o pino estiver ligado ao solo, irá devolver
PinValue.Low
. Quando o pino é desligado do solo e o circuito está aberto, o pino devolvePinValue.High
.
- Esta ação abre o marcador com uma resistência PullUp ativada. Neste modo, quando o pino estiver ligado ao solo, irá devolver
- O estado inicial é escrito numa consola com uma expressão ternary. O estado atual do pino é lido com
Read()
. Se forPinValue.High
, escreve aAlert
cadeia na consola. Caso contrário, escreve aReady
cadeia. -
RegisterCallbackForPinValueChangedEvent()
regista uma função de chamada de retorno para osPinEventTypes.Rising
eventos ePinEventTypes.Falling
no pin. Estes eventos correspondem aos estados afixados dePinValue.High
ePinValue.Low
, respetivamente. - A função de chamada de retorno aponta para um método chamado
OnPinEvent()
.OnPinEvent()
utiliza outra expressão ternary que também escreve as cadeias ouReady
correspondentesAlert
. - O thread principal permanece suspenso indefinidamente enquanto aguarda por eventos de afixação.
- Uma declaração de utilização cria uma instância de
Crie a aplicação. Se estiver a utilizar a CLI de .NET, execute
dotnet build
. Para criar no Visual Studio, prima Ctrl+Shift+B.Implemente a aplicação no SBC como uma aplicação autónoma. Para obter instruções, veja Implementar aplicações .NET no Raspberry Pi. Confirme que concede permissão de execução executável com
chmod +x
.Execute a aplicação no Raspberry Pi ao mudar para o diretório de implementação e executar o executável.
./InputTutorial
A consola apresenta texto semelhante ao seguinte:
Initial status (05/10/2022 15:59:25): READY ✅
Desligue o pino 21 do solo. A consola apresenta texto semelhante ao seguinte:
(05/10/2022 15:59:59) ALERT 🚨
Voltar a ligar o pino 21 e o solo. A consola apresenta texto semelhante ao seguinte:
(05/10/2022 16:00:25) READY ✅
Termine o programa premindo Ctrl+C.
Parabéns! Utilizou o GPIO para detetar entradas com o System.Device.Gpio
pacote NuGet! Existem muitas utilizações para este tipo de entrada. Este exemplo pode ser utilizado com qualquer cenário em que um comutador se ligue ou quebre um circuito. Eis um exemplo de utilização com um interruptor magnético, que é frequentemente utilizado para detetar portas ou janelas abertas.
Fio de tripwire a laser
Expandindo um pouco mais o conceito de exemplo anterior, vamos ver como isto pode ser aplicado à criação de um tripwire a laser. A criação de um tripwire a laser requer os seguintes componentes adicionais:
- Ky-008 laser transmitter module (Módulo de transmissor a laser KY-008)
- Módulo do sensor do recetor de laser (ver nota abaixo)
- 2 10 000 Ω resistências
Nota
O módulo sensor recetor de laser é o nome genérico aplicado a um módulo comum encontrado em muitos revendedores de Internet. O dispositivo pode variar em nome ou fabricante, mas deve assemelhar-se a esta imagem.
Ligar hardware do tripwire a laser
Ligue os componentes conforme detalhado no diagrama seguinte.
Preste muita atenção aos 10 000 Ω resistências. Estes implementam um separador de tensão. Isto acontece porque o módulo do recetor de laser produz 5 V para indicar que o feixe está avariado. O Raspberry Pi só suporta até 3,3 V para entrada GPIO. Uma vez que enviar o 5V completo para o pino pode danificar o Raspberry Pi, a corrente do módulo do recetor é transmitida através de um separador de tensão para reduzir para metade a tensão para 2,5 V.
Aplicar atualizações de código fonte
Quase pode utilizar o mesmo código que anteriormente, com uma exceção. Nos outros exemplos, utilizámos PinMode.InputPullUp
para que, quando o pino estiver desligado do solo e o circuito estiver aberto, o pino devolva PinValue.High
.
No entanto, no caso do módulo do recetor de laser, não estamos a detetar um circuito aberto. Em vez disso, queremos que o pino atue como um sink para a corrente proveniente do módulo do recetor de laser. Neste caso, vamos abrir o marcador com PinMode.InputPullDown
. Desta forma, o pino devolve PinValue.Low
quando não está a receber nenhuma corrente e PinValue.High
quando recebe atual do módulo do recetor de laser.
controller.OpenPin(pin, PinMode.InputPullDown);
Importante
Certifique-se de que o código implementado no Raspberry Pi inclui esta alteração antes de testar um tripwire a laser. O programa funciona sem ele, mas utilizar o modo de entrada errado arrisca-se a danificar o Raspberry Pi!
Obter o código-fonte
A origem deste tutorial está disponível no GitHub.