GpioDriver for other boards and virtual GpioController and virtual GpioPin

May 10, 2026 ยท View on GitHub

This project contains some full function(PULL-UP, PULL-DOWN) generic GPIO drivers, and it can provide faster GPIO access.

Documentation

Usage of virtual GpioController and virtual GpioPin

When you have multiple GpioControllers and want to use them together in a specific binding, the VirtualGpioController allows to create a GpioController from a set of GpioPins already open from different controllers. Usage is straight forward and the class is fully compatible with a normal GpioController.

// Create pins from 2 different GpioControllers
var pinFromA = gpioControllerA.Open(42, PinMode.Output);
var pinFromB = gpioControllerB.Open(24, PinMode.Input);
var pinFromC = gpioControllerC.Open(12, PinMode.Input);
VirtualGpioController gpio = new();
// pin number will be 0 in this case
gpio.Add(pinFromA);
// pin number will be 12 in this case
gpio.Add(12, pinFromB);
// the pin number will be 13 in this case
gpio.Add(pinFromC);

When adding an existing GpioPin, by default, the new pin allocation will directly follow the higher pin number already existing. You can also use this method to change the numbering of your board. Note that the VirtualGpioController is only operating in the logical numbering.

Board specific drivers

BoardDriver
Orange Pi 4OrangePi4Driver
Orange Pi 5OrangePi5Driver
Orange Pi 5BOrangePi5BDriver
Orange Pi 5 PlusOrangePi5PlusDriver
Orange Pi 5 ProOrangePi5ProDriver
Orange Pi 5 MaxOrangePi5MaxDriver
Orange Pi 5 UltraOrangePi5UltraDriver
Orange Pi LiteOrangePiLiteDriver
Orange Pi Lite 2OrangePiLite2Driver
Orange Pi ZeroOrangePiZeroDriver
Orange Pi Zero 2OrangePiZero2Driver
Rock Pi 4B PlusRockPi4BPlusDriver
Orange Pi PCOrangePiPCDriver

Benchmarks

The test uses different GPIO drivers to quickly switch the state of GPIO, and uses an oscilloscope to measure the average frequency of GPIO externally.

SunxiDriver

Benchmarking with Orange Pi Zero, select GPIO 6 (Logical). The operating system is Armbian buster, Linux kernel version is 5.10.16, and .NET version is 5.0.3.

DriversLanguageLibrary VersionTest DateAverage Frequency
SunxiDriverC#-2020-02-20185 KHzsunxi
SysFsDriverC#System.Device.Gpio 1.3.02020-02-20692 Hzsysfs
LibGpiodDriverC#System.Device.Gpio 1.3.0 - libgpiod 1.2-32020-02-2081 KHzlibgpiod
wiringOPC35de0152020-02-221.10 MHzwiringOP

RockchipDriver

Benchmarking with Orange Pi 4, select GPIO 150 (Logical). The operating system is Armbian buster, Linux kernel version is 5.10.16, and .NET version is 5.0.3.

DriversLanguageLibrary VersionTest DateAverage Frequency
RockchipDriverC#-2020-02-22516 KHzrockchip
SysFsDriverC#System.Device.Gpio 1.3.02020-02-224.27 KHzsysfs
LibGpiodDriverC#System.Device.Gpio 1.3.0 - libgpiod 1.2-32020-02-22174 KHzlibgpiod
wiringOPC35de0152020-02-22584 KHzwiringgOP

Usage

Hardware required

  • Orange Pi Zero
  • Switch
  • Male/Female Jumper Wires

Circuit

circuit

  • Switch 1 - Board Pin7 (GPIO 6)
  • Switch 2 - GND

Code

using System;
using System.Device.Gpio;
using Iot.Device.BoardLed;
using Iot.Device.Gpio.Drivers;

// Set debounce delay to 5ms
int debounceDelay = 50000;
int pin = 7;

Console.WriteLine($"Let's blink an on-board LED!");

using GpioController controller = new GpioController(new OrangePiZeroDriver());
using BoardLed led = new BoardLed("orangepi:red:status");

controller.OpenPin(pin, PinMode.InputPullUp);
led.Trigger = "none";
Console.WriteLine($"GPIO pin enabled for use: {pin}.");
Console.WriteLine("Press any key to exit.");

while (!Console.KeyAvailable)
{
    if (Debounce())
    {
        // Button is pressed
        led.Brightness = 1;
    }
    else
    {
        // Button is unpressed
        led.Brightness = 0;
    }
}

bool Debounce()
{
    long debounceTick = DateTime.Now.Ticks;
    PinValue buttonState = controller.Read(pin);

    do
    {
        PinValue currentState = controller.Read(pin);

        if (currentState != buttonState)
        {
            debounceTick = DateTime.Now.Ticks;
            buttonState = currentState;
        }
    }
    while (DateTime.Now.Ticks - debounceTick < debounceDelay);

    if (buttonState == PinValue.Low)
    {
        return true;
    }
    else
    {
        return false;
    }
}