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:

Um diagrama mostrando um circuito que conecta um pino terra ao pino 21.

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:

Um diagrama mostrando a pinagem do cabeçalho Raspberry Pi GPIO. Imagem cortesia da Fundação Raspberry Pi.
Imagem cortesia da Raspberry Pi Foundation.

Criar o aplicativo

Siga estas etapas em seu ambiente de desenvolvimento preferencial:

  1. 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
    
  2. 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-*
    
  3. 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. A usingdeclaração garante que o objeto seja descartado e os recursos de hardware sejam liberados corretamente.
    • 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 retorna PinValue.High.
    • O status inicial é gravado em um console usando uma expressão ternária. O estado atual do pino é lido com Read(). Se for PinValue.High, ele gravará a cadeia de caracteres Alert no console. Caso contrário, gravará a cadeia de caracteres Ready.
    • RegisterCallbackForPinValueChangedEvent() registra uma função de retorno de chamada para os eventos PinEventTypes.Rising e PinEventTypes.Falling no pino. Esses eventos correspondem aos estados de pino PinValue.High e PinValue.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 caracteres Alert ou Ready correspondentes.
    • O thread principal é suspenso indefinidamente enquanto aguarda os eventos dos pinos.
  4. Crie o aplicativo. Ao usar a CLI do .NET, execute dotnet build. Para criar no Visual Studio, pressione Ctrl+Shift+B.

  5. 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.

  6. 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 ✅
    
  7. Desconecte o pino 21 do terra. O console exibe um texto semelhante ao seguinte:

    (05/10/2022 15:59:59) ALERT 🚨
    
  8. Reconecte o pino 21 e o terra. O console exibe um texto semelhante ao seguinte:

    (05/10/2022 16:00:25) READY ✅
    
  9. 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.

GIF animado demonstrando um sensor magnético abrindo e fechando. O comutador é exposto a um ímã e o aplicativo exibe READY. O ímã é removido e o aplicativo exibe ALERTA. Então, a ação é repetida.

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.

Imagem de um módulo do sensor do receptor a laser

Conectar um hardware do mecanismo a laser

Conecte os componentes conforme detalhado no diagrama a seguir.

Um diagrama mostrando um circuito que obtém a entrada de um módulo do sensor do receptor a laser.

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!

GIF animado com uma demonstração do mecanismo a laser. O emissor do laser acende o módulo do sensor a laser e o aplicativo exibe READY. O raio a laser é interrompido e o aplicativo exibe ALERTA. Em seguida, a ação é repetida.

Obter o código-fonte

A fonte deste tutorial está disponível no GitHub.

Próximas etapas