Training
Learning path
This learning path aims to explain learners how to deploy AI at the edge using Azure services.
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
General-purpose I/O (GPIO) pins can be configured to receive electrical signals as input. At its most basic level, this is useful for scenarios that detect the opening/closing of a circuit. Such circuits might include push buttons, toggle switches, reed switches, pressure switches, and other devices that represent binary (on/off) values by completing a circuit.
In this tutorial, you'll use .NET and your Raspberry Pi's GPIO pins to detect the opening and closing of a circuit.
Note
This tutorial is written assuming the target device is Raspberry Pi. However, this tutorial can be used for any Linux-based SBC that supports .NET, such as Orange Pi, ODROID, and more.
Ensure SSH is enabled on your device. For Raspberry Pi, refer to Setting up an SSH Server in the Raspberry Pi documentation.
Use the hardware components to build the circuit as depicted in the following diagram:
The image above depicts a direct connection between a ground pin and pin 21.
Tip
The diagram depicts a breadboard and GPIO breakout for illustrative purposes, but feel free to just connect a ground pin and pin 21 with a jumper wire on the Raspberry Pi.
Refer to the following pinout diagram as needed:
Image courtesy Raspberry Pi Foundation.
Complete the following steps in your preferred development environment:
Create a new .NET Console App using either the .NET CLI or Visual Studio. Name it InputTutorial.
dotnet new console -o InputTutorial
cd InputTutorial
Add the System.Device.Gpio package to the project. Use either .NET CLI from the project directory or Visual Studio.
dotnet add package System.Device.Gpio --version 3.2.0-*
Replace the contents of Program.cs with the following code:
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)}");
}
In the preceding code:
GpioController
. The using
declaration ensures the object is disposed and hardware resources are released properly.
GpioController
is instantiated with no parameters, indicating that it should detect which hardware platform it's running on and use the logical pin numbering scheme.PinMode.InputPullUp
.
PinValue.Low
. When the pin is disconnected from ground and the circuit is open, the pin returns PinValue.High
.Read()
. If it's PinValue.High
, it writes the Alert
string to the console. Otherwise, it writes the Ready
string.RegisterCallbackForPinValueChangedEvent()
registers a callback function for both the PinEventTypes.Rising
and PinEventTypes.Falling
events on the pin. These events correspond to pin states of PinValue.High
and PinValue.Low
, respectively.OnPinEvent()
. OnPinEvent()
uses another ternary expression that also writes the corresponding Alert
or Ready
strings.Build the app. If using the .NET CLI, run dotnet build
. To build in Visual Studio, press Ctrl+Shift+B.
Deploy the app to the SBC as a self-contained app. For instructions, see Deploy .NET apps to Raspberry Pi. Make sure to give the executable execute permission using chmod +x
.
Run the app on the Raspberry Pi by switching to the deployment directory and running the executable.
./InputTutorial
The console displays text similar to the following:
Initial status (05/10/2022 15:59:25): READY ✅
Disconnect pin 21 from ground. The console displays text similar to the following:
(05/10/2022 15:59:59) ALERT 🚨
Reconnect pin 21 and ground. The console displays text similar to the following:
(05/10/2022 16:00:25) READY ✅
Terminate the program by pressing Ctrl+C.
Congratulations! You've used GPIO to detect input using the System.Device.Gpio
NuGet package! There are many uses for this type of input. This example can be used with any scenario where a switch connects or breaks a circuit. Here's an example using it with a magnetic reed switch, which is often used to detect open doors or windows.
Extending the previous example concept a bit further, let's take a look at how this could be applied to creating a laser tripwire. Building a laser tripwire requires the following additional components:
Note
Laser receiver sensor module is the generic name applied to a common module found at many internet retailers. The device may vary in name or manufacturer, but should resemble this image.
Connect the components as detailed in the following diagram.
Pay close attention to the 10K Ω resistors. These implement a voltage divider. This is because the laser receiver module outputs 5V to indicate the beam is broken. Raspberry Pi only supports up to 3.3V for GPIO input. Since sending the full 5V to the pin could damage the Raspberry Pi, the current from the receiver module is passed through a voltage divider to halve the voltage to 2.5V.
You can almost use the same code as earlier, with one exception. In the other examples, we used PinMode.InputPullUp
so that when the pin is disconnected from ground and the circuit is open, the pin returns PinValue.High
.
However, in the case of the laser receiver module, we're not detecting an open circuit. Instead, we want the pin to act as a sink for current coming from the laser receiver module. In this case, we'll open the pin with PinMode.InputPullDown
. This way, the pin returns PinValue.Low
when it's getting no current, and PinValue.High
when it receives current from the laser receiver module.
controller.OpenPin(pin, PinMode.InputPullDown);
Important
Make sure the code deployed on your Raspberry Pi includes this change before testing a laser tripwire. The program does work without it, but using the wrong input mode risks damage to your Raspberry Pi!
The source for this tutorial is available on GitHub.
.NET feedback
.NET is an open source project. Select a link to provide feedback:
Training
Learning path
This learning path aims to explain learners how to deploy AI at the edge using Azure services.
Documentation
Read environmental conditions from a sensor - .NET
Learn how to read temperature, barometric pressure, and humidity with the .NET IoT Libraries.
Learn how to blink an LED with the .NET IoT Libraries.
Learn how to display characters on a liquid crystal display with the .NET IoT Libraries.