Uso de GPIO en entradas binarias
Se pueden configurar pines de E/S de uso general (GPIO) para recibir señales eléctricas como entrada. En su nivel más básico, esto es útil en escenarios donde se detecta la apertura y el cierre de un circuito. Estos circuitos pueden incluir botones pulsadores, conmutadores de alternancia, interruptores de láminas, conmutadores de presión y otros mecanismos que representan valores binarios (es decir, activado/desactivado) y que completan un circuito.
En este tutorial, usará .NET y los pines de GPIO de su Raspberry Pi para detectar la apertura y el cierre de un circuito.
Requisitos previos
- Equipo de placa única (SBC) basado en ARM (ARMv7 o superior)
- Cables de puente
- Placa de pruebas (opcional)
- Placa adaptadora GPIO de Raspberry Pi (opcional)
- SDK de .NET 7 o versiones posteriores.
Nota
En este tutorial, se presupone que el dispositivo de destino es Raspberry Pi. Sin embargo, se puede usar con cualquier equipo SBC basado en Linux que admita .NET, como Orange Pi, ODROID, etc.
Asegúrese de que SSH está habilitado en el dispositivo. Para Raspberry Pi, consulte Configuración de un servidor SSH en la documentación de Raspberry Pi.
Preparación del hardware
Use los componentes de hardware para crear el circuito como se muestra en el diagrama siguiente:
En la imagen anterior se muestra una conexión directa entre un pin de tierra y el pin 21.
Sugerencia
El diagrama muestra una placa de pruebas y una placa adaptadora GPIO a modo ilustrativo, pero no dude en conectar un pin de tierra y el pin 21 con un cable de puente en la Raspberry Pi si así lo desea.
Consulte el siguiente diagrama de pines según sea necesario:
Imagen de Raspberry Pi Foundation.
Creación de la aplicación
Complete los pasos siguientes en el entorno de desarrollo que prefiera:
Cree una aplicación de consola de .NET mediante la CLI de .NET o Visual Studio. Llámela InputTutorial.
dotnet new console -o InputTutorial cd InputTutorial
Agregue el paquete System.Device.Gpio al proyecto. Use la CLI de .NET desde el directorio del proyecto o Visual Studio.
dotnet add package System.Device.Gpio --version 2.2.0-*
Reemplace el contenido de Program.cs por el código siguiente:
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)}"); }
En el código anterior:
- Una declaración using crea una instancia de
GpioController
. La declaraciónusing
garantiza que el objeto se deseche y que los recursos de hardware se liberen correctamente.- Se crea una instancia de
GpioController
sin parámetros, lo que indica que debe detectar en qué plataforma de hardware se ejecuta y usar el esquema de numeración de pines lógica.
- Se crea una instancia de
- El pin 21 se abre con
PinMode.InputPullUp
.- Esto abre el pin con una resistencia PullUp acoplada. En este modo, cuando el pin está conectado a tierra, devolverá
PinValue.Low
. Cuando el pin no está conectado a tierra y el circuito está abierto, el pin devuelvePinValue.High
.
- Esto abre el pin con una resistencia PullUp acoplada. En este modo, cuando el pin está conectado a tierra, devolverá
- El estado inicial se escribe en una consola mediante una expresión ternaria. El estado actual del pin se lee con
Read()
. Si esPinValue.High
, escribe la cadenaAlert
en la consola. De lo contrario, escribe la cadenaReady
. -
RegisterCallbackForPinValueChangedEvent()
registra una función de devolución de llamada para los eventosPinEventTypes.Rising
yPinEventTypes.Falling
en el pin. Estos eventos equivalen a los estados de pinPinValue.High
yPinValue.Low
respectivamente. - La función de devolución de llamada apunta a un método denominado
OnPinEvent()
.OnPinEvent()
usa otra expresión ternaria que también escribe las cadenasAlert
oReady
correspondientes. - El subproceso principal se suspende indefinidamente mientras se esperan eventos de pin.
- Una declaración using crea una instancia de
Compile la aplicación. Si usa la CLI de .NET, ejecute
dotnet build
. Para realizar la compilación en Visual Studio, presione Ctrl+Mayús+B.Implemente la aplicación en el equipo SBC como una aplicación independiente. Para obtener instrucciones, vea Implementación de aplicaciones .NET en Raspberry Pi. Asegúrese de conceder el permiso execute ejecutable mediante
chmod +x
.Para ejecutar la aplicación en Raspberry Pi, cambie al directorio de implementación y ejecute el archivo ejecutable.
./InputTutorial
La consola muestra un texto parecido al siguiente:
Initial status (05/10/2022 15:59:25): READY ✅
Desconecte el pin 21 de tierra. La consola muestra un texto parecido al siguiente:
(05/10/2022 15:59:59) ALERT 🚨
Vuelva a conectar el pin 21 a tierra. La consola muestra un texto parecido al siguiente:
(05/10/2022 16:00:25) READY ✅
Presione Ctrl+C para finalizar el programa.
¡Enhorabuena! Ha usado GPIO para detectar entradas mediante el paquete NuGet System.Device.Gpio
. Este tipo de entrada se puede usar de muchas formas. Este ejemplo se puede usar en cualquier escenario en el que un conmutador conecte o interrumpa un circuito. En este ejemplo de aquí se usa con un conmutador de láminas magnético, que suele emplearse para detectar puertas o ventanas abiertas.
Cable detonador láser
Por ampliar un poco más el concepto del ejemplo anterior, veamos cómo se podría aplicar esto para crear un cable detonador láser. Para crear un cable detonador láser, se necesitan los siguientes componentes adicionales:
- Un módulo transmisor de láser KY-008
- Un módulo sensor receptor de láser (ver la nota de abajo)
- Dos resistencias de 10 000 Ω
Nota
Módulo sensor receptor de láser es el nombre genérico con el que hacemos referencia a un módulo común que se encuentra fácilmente en Internet. El nombre o el fabricante del dispositivo puede variar, pero debe parecerse al de esta imagen.
Conexión de los componentes del cable detonador láser
Conecte los componentes como se detalla en el siguiente diagrama.
Preste mucha atención a las resistencias de 10 000 Ω. Implementan un divisor de voltaje. Esto se debe a que el módulo receptor de láser genera una salida de 5 V para indicar que el haz se ha interrumpido. Raspberry Pi solo admite entradas de GPIO de 3,3 V como máximo. Enviar la salida de 5 V completa al pin podría dañar la Raspberry Pi, de ahí que la corriente del módulo receptor pase por un divisor de voltaje, para reducir el voltaje a 2,5 V.
Aplicación de actualizaciones de código fuente
Casi podemos usar el mismo código de antes, con una excepción. En los otros ejemplos, usamos PinMode.InputPullUp
para que cuando el pin no esté conectado a tierra y el circuito esté abierto, el pin devuelva PinValue.High
.
Sin embargo, en el caso del módulo receptor de láser, no estamos detectando un circuito abierto, sino que queremos que el pin actúe como receptor de la corriente procedente del módulo receptor de láser. En este caso, abriremos el pin con PinMode.InputPullDown
. De este modo, el pin devuelve PinValue.Low
cuando no está recibiendo corriente y PinValue.High
cuando reciba corriente del módulo receptor de láser.
controller.OpenPin(pin, PinMode.InputPullDown);
Importante
Asegúrese de que el código implementado en la Raspberry Pi incluye este cambio antes de probar un cable detonador láser. El programa funciona sin él, pero usar modo de entrada incorrecto podría dañar la Raspberry Pi.
Obtención del código fuente
El código fuente de este tutorial está disponible en GitHub.