Usar GPIO para a entrada binária
Os pinos GPIO (E/S de uso geral) podem ser configurados para receber sinais elétricos como entrada. Em seu nível mais básico, é útil para cenários que detectam a abertura/fechamento de um circuito. Esses circuitos podem incluir botões de ação, comutadores de alternância, sensores magnéticos, comutadores de pressão e outros dispositivos que representam valores binários (on/off) completando um circuito.
Neste tutorial, você usará o .NET e os pinos GPIO do Raspberry Pi para detectar a abertura e o fechamento de um circuito.
Pré-requisitos
- SBC (computador de placa única) baseado em ARM (ARMv7 ou superior)
- Cabos de jumper
- Breadboard (opcional)
- Placa de contato impresso GPIO do Raspberry Pi (opcional)
- .NET SDK 7 ou posterior
Observação
Este tutorial foi escrito supondo que o dispositivo de destino seja o Raspberry Pi. No entanto, este tutorial pode ser usado para qualquer SBC baseado em Linux com suporte para .NET, como Orange Pi, ODROID e muito mais.
Certifique-se de que o SSH esteja ativado no dispositivo. Para o Raspberry Pi, confira Configuração de um servidor SSH na documentação do Raspberry Pi.
Preparar o hardware
Use os componentes de hardware para criar o circuito, conforme ilustrado no seguinte diagrama:
A imagem acima ilustra uma conexão direta entre um pino terra e um pino 21.
Dica
O diagrama ilustra uma placa de ensaio e uma fuga GPIO para fins ilustrativos, mas sinta-se à vontade para conectar apenas um pino terra e um pino 21 com um fio jumper no Raspberry Pi.
Consulte o seguinte diagrama de pinagem conforme necessário:
Imagem cortesia da Raspberry Pi Foundation.
Criar o aplicativo
Siga estas etapas em seu ambiente de desenvolvimento preferencial:
Crie um aplicativo de console .NET usando a CLI do .NET ou o Visual Studio. Nomeie como InputTutorial.
dotnet new console -o InputTutorial cd InputTutorial
Adicione o pacote System.Device.Gpio ao projeto. Use a CLI do .NET no diretório do projeto ou no Visual Studio.
dotnet add package System.Device.Gpio --version 2.2.0-*
Substitua o conteúdo do 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 uso cria uma instância de
GpioController
. Ausing
declaração garante que o objeto seja descartado e os recursos de hardware sejam liberados corretamente.-
GpioController
é instanciado sem parâmetros, indicando que ele deve detectar qual plataforma de hardware está rodando e usar o esquema de numeração de pino lógico.
-
- O pino GPIO 21 é aberto com
PinMode.InputPullUp
.- Isso abre o pino com um resistor PullUp acoplado. Nesse modo, quando o pino estiver conectado ao terra, ele retornará
PinValue.Low
. Quando o pino está desconectado do terra e o circuito está aberto, o pino retornaPinValue.High
.
- Isso abre o pino com um resistor PullUp acoplado. Nesse modo, quando o pino estiver conectado ao terra, ele retornará
- O status inicial é gravado em um console usando uma expressão ternária. O estado atual do pino é lido com
Read()
. Se forPinValue.High
, ele gravará a cadeia de caracteresAlert
no console. Caso contrário, gravará a cadeia de caracteresReady
. -
RegisterCallbackForPinValueChangedEvent()
registra uma função de retorno de chamada para os eventosPinEventTypes.Rising
ePinEventTypes.Falling
no pino. Esses eventos correspondem aos estados de pinoPinValue.High
ePinValue.Low
, respectivamente. - A função de retorno de chamada aponta para um método denominado
OnPinEvent()
.OnPinEvent()
usa outra expressão ternária que também grava as cadeias de caracteresAlert
ouReady
correspondentes. - O thread principal é suspenso indefinidamente enquanto aguarda os eventos dos pinos.
- Uma declaração de uso cria uma instância de
Crie o aplicativo. Ao usar a CLI do .NET, execute
dotnet build
. Para criar no Visual Studio, pressione Ctrl+Shift+B.Implante o aplicativo no SBC como um aplicativo autônomo. Para obter instruções, confira Implantar aplicativos .NET no Raspberry Pi . Dê a permissão de execução ao executável usando
chmod +x
.Execute o aplicativo no Raspberry Pi alternando para o diretório de implantação e executando o executável.
./InputTutorial
O console exibe um texto semelhante ao seguinte:
Initial status (05/10/2022 15:59:25): READY ✅
Desconecte o pino 21 do terra. O console exibe um texto semelhante ao seguinte:
(05/10/2022 15:59:59) ALERT 🚨
Reconecte o pino 21 e o terra. O console exibe um texto semelhante ao seguinte:
(05/10/2022 16:00:25) READY ✅
Encerre o programa pressionando Ctrl+C.
Parabéns! Você usou o GPIO para detectar a entrada usando o pacote NuGet System.Device.Gpio
! Há muitos usos para esse tipo de entrada. Este exemplo pode ser usado com qualquer cenário em que um comutador se conecta ou interrompe um circuito. Aqui está um exemplo usando-o com um sensor magnético, que geralmente é usado para detectar portas ou janelas abertas.
Mecanismo a laser
Estendendo um pouco mais o conceito do exemplo anterior, veremos como isso pode ser aplicado à criação de um mecanismo a laser. A criação de um mecanismo a laser requer os seguintes componentes adicionais:
- Módulo de transmissor a laser KY-008
- Módulo do sensor do receptor a laser (veja a observação abaixo)
- 2 resistores de 10 mil Ω
Observação
Módulo do sensor do receptor a laser é o nome genérico aplicado a um módulo comum encontrado em muitos revendedores na Internet. O dispositivo pode variar em nome ou fabricante, mas deve ser semelhante a essa imagem.
Conectar um hardware do mecanismo a laser
Conecte os componentes conforme detalhado no diagrama a seguir.
Preste muita atenção aos resistores de 10K Ω. Eles implementam um divisor de tensão. Isso ocorre porque o módulo do receptor a laser gera 5V para indicar que o feixe está interrompido. O Raspberry Pi dá suporte apenas a até 3,3V para a entrada GPIO. Como enviar 5V completos para o pino pode danificar o Raspberry Pi, a corrente do módulo do receptor é passada por um divisor de tensão para reduzir pela metade a tensão para 2,5V.
Aplicar atualizações do código-fonte
Você quase pode usar o mesmo código que anteriormente, com uma exceção. Nos outros exemplos, usamos PinMode.InputPullUp
para que, quando o pino for desconectado do terra e o circuito estiver aberto, o pino retorne PinValue.High
.
No entanto, no caso do módulo do receptor a laser, não estamos detectando um circuito aberto. Em vez disso, queremos que o pino atue como um coletor para a corrente proveniente do módulo do receptor a laser. Nesse caso, abriremos o pino com PinMode.InputPullDown
. Dessa forma, o pino retorna PinValue.Low
quando não recebe corrente e PinValue.High
quando recebe corrente do módulo do receptor a laser.
controller.OpenPin(pin, PinMode.InputPullDown);
Importante
Verifique se o código implantado no Raspberry Pi inclui essa alteração antes de testar um mecanismo a laser. O programa funciona sem ele, mas usar o modo de entrada errado corre o risco de danificar seu Raspberry Pi!
Obter o código-fonte
A fonte deste tutorial está disponível no GitHub.