| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
A lightweight and user-friendly C++ wrapper for libgpiod 2.x, designed to make GPIO access on Linux and Raspberry Pi simple, readable, and intuitive.
✔️ Simple GPIO input/output
✔️ One-line pin configuration
✔️ Pin Event (IS_RISING, IS_FALLING)
✔️ Interrupt support (RISING, FALLING, BOTH)
✔️ Non-blocking debouncing function
✔️ Automatic cleanup & securely reset
✔️ No dynamic memory handling required
✔️ Asynchron and without continuous polling
✔️ Works with libgpiod 2.x
Instead of complex gpiod structures, this wrapper provides easy functions like:
| Basic configuration | Description |
|---|---|
| gpiodWrap gpio | Automatic search chip number. |
| gpiodWrap gpio(chipnum) | Specific chip number. |
| Basic function | Description |
|---|---|
| openChip(chipnum) | Open specifically. |
| closeChip() | Returns outputs to a safe state, releases resources. |
| configurePin(pin, direction) | Configured and registered PIN. |
| setPin(pin, HIGH/LOW) | Sets pin high/low. |
| getPin(pin, debounce) | Reads pin optional debouncing. |
| getPinEvent(pin, debounce) | Reads pin edge events with integrated software debouncing and outputs PinEvent. |
| resetPin(pin) | resets the PIN and releases its resources. |
| Interrupt methods | Description |
|---|---|
| bindInterrupt(pin, direction, edge, debounce) | Registers and configures a GPIO pin for interrupt detection with debouncing. |
| watchInterrupt(pin, userCallback void/void(int)) | Interrupt monitoring; passes events to the specified callback. |
| unbindInterrupt(pin) | Disables interrupt for pin and terminates the associated thread. |
| Error handling | Description |
|---|---|
| anyGlobalError() | Returns a global error |
| hasGlobalError(enum) | Returns a specific global error |
| getGlobalErrorNum() | Returns global error number. |
| anyPinError(pin) | Returns a pin error |
| hasPinError(pin, enum) | Returns a specific pin error. |
| getPinErrorNum(pin) | Returns pin error number. |
| clearGlobalErrors() | Clears all global errors |
| clearGlobalError(enum) | Clears specific global error |
| clearPinErrors(pin) | Clears all specific pin errors |
| clearPinError(pin, enum) | Clears specific pin error |
| Komfort functions | Description |
|---|---|
| getStrErr() | Returns error as text. |
| getStrErrPin(pin) | Returns specific pin errors. |
| blinkPin(pin, interval, time) | e.g., implementing an status LED |
| softPwm(pin, percent, frequency) | Dynamic Software PWM control LEDs, BUZZER... |
| detachPin(pin, PinValue, PinValue, interval) | e.g., status LEDs... |
Perfect for hobbyists, students, and projects where you just want GPIO control without becoming a libgpiod expert.
| Requirement | Version |
|---|---|
| libgpiod | ≥ 2.0 |
| C++ | ≥ C++17 |
| CMake | optional for building |
Install libgpiod build-essential cmake(Debian / Raspberry Pi OS):
sudo apt update
sudo apt install -y libgpiod-dev build-essential cmake
gpioinfo -vlibgpiod-2.x self build e.g. RaspberryOS bullseye/bookworm
sudo apt update sudo apt install -y build-essential autoconf automake libtool pkg-config autoconf-archive wget https://mirrors.edge.kernel.org/pub/software/libs/libgpiod/libgpiod-2.3.1.tar.gz tar -xvf libgpiod-2.3.1.tar.gz cd libgpiod-2.3.1 ./configure --enable-tools make -j4 sudo make install sudo ldconfig
No Root Required
//Check the gpio group groups //if it doesn't show up, keep going (don't forget the 'a'). sudo usermod -aG gpio username //Sign up again exit
#include <iostream>
#include <chrono>
#include <thread>
#include "gpiodWrap.hpp"
int main() {
try {
using namespace gpiodwrap;
gpiodWrap gpio;
gpio.configurePin(17, Output);
gpio.setPin(17, HIGH);
std::this_thread::sleep_for(std::chrono::seconds(1));
gpio.setPin(17, LOW);
std::this_thread::sleep_for(std::chrono::seconds(1));
gpio.resetPin(17);
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
// Destructor of gpiodWrap is called automatically
return 0;
}
#include <iostream>
#include <chrono>
#include "gpiodWrap.hpp"
gpiodWrap gpio;
int main() {
using namespace gpiodwrap;
gpio.bindInterrupt(22, PULLUP, FALLING, 60);
gpio.watchInterrupt(pin, [](int pin)
{ std::cout << "Falling-Event on Pin: " << pin << std::endl; });
while (true) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
📁 examples/
├── blink.cpp // Make individual LEDs blink ├── button.cpp // Input example ├── button_led.cpp // Input / Output example ├── buzzer.cpp // Alert example ├── error.cpp // Error handling ├── fade_led.cpp // Dynamic PWM control ├── interrupt.cpp // Kernel-Event ├── led.cpp // Output example ├── mockup.cpp // Event / Debounce stress test ├── pin_event.cpp // Input event falling/rising └── pwm.cpp // Static PWM control
sudo apt update
sudo apt upgrade -y
sudo apt install build-essential -y
sudo apt install cmake -yCMake-System
cd gpioWarp mkdir build cd build cmake .. make or make -j4 output bin/...
mkdir myproject
cd myproject
mkdir src include build
mv ../gpioWrap/gpiodWrap.hpp include
nano CMakeLists.txt
cd build
cmake ..
make or make -j4
cd ../bin/myproject
./myproject
myproject
│
├── CMakeLists.txx
├── build
├── bin
│ └── myproject
├── include
│ └── gpiodWrap.hpp
└── src
└── myproject.cpp
set(SOURCE_NAME myproject)
cmake_minimum_required(VERSION 3.16)
project(${SOURCE_NAME} VERSION 1.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
include_directories(${PROJECT_SOURCE_DIR}/include)
add_executable(${SOURCE_NAME}
src/${SOURCE_NAME}.cpp
)
target_link_libraries(${SOURCE_NAME}
gpiod
)
set_target_properties(${SOURCE_NAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY
${PROJECT_SOURCE_DIR}/bin/${SOURCE_NAME}
)
(The files to be compiled are located in one directory!)
g++ myproject.cpp -o myproject -lgpiodHere's another nice example from a different project where I'm using gpiodWrap.
#include <chrono>
#include "gpiodWrap.hpp"
gpiodWrap gpio;
constexpr int errorLED = 18;
void delay(unsigned long ms) {
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
}
unsigned long millis() {
using namespace std::chrono;
static const auto start = steady_clock::now();
return duration_cast<milliseconds>(steady_clock::now() - start).count();
}
void errReport(unsigned long interval = 500) {
static unsigned long last = 0;
static bool state = true;
if (millis() - last >= interval) {
last = millis();
state = !state;
gpiodwrap::gpio.setPin(faultLED, state ? HIGH : LOW);
}
}
int main() {
using namespace gpiodwrap;
gpio.configurePin(errorLED, Output);
gpio.setPin(errorLED, LOW);
bool syserror = true;
while(true) {
if (syserror) errReport(300);
delay(20);
}
}
Uncontrolled program termination (e.g., via Ctrl + C / SIGINT or SIGTERM) can be hazardous in hardware control applications if outputs connected to motors, relays, or heating elements remain active in an undefined state.
gpiodWrap addresses this by adhering to the Safe-by-Default principle:
Automatic Fail-Safe:
Upon receiving SIGINT or SIGTERM, all active output pins are automatically reverted to a safe, high-impedance input state (INPUT) before the GPIO chip is released.
Decoupled Watchdog Thread:
The POSIX signal handler exclusively modifies atomic flags (100% async-signal-safe). Hardware cleanup is executed asynchronously in a separate watchdog thread—completely free from C library locks or deadlock risks.
Optional Compile-Time Disabling:
If your application logic manages signal handling independently, the built-in signal mechanism can be disabled entirely with zero runtime overhead:
#define GPIODWRAP_NO_SIGNALS #include "gpiodWrap.hpp"
# old school mkdir -p build && cd build cmake .. -DGPIODWRAP_DISABLE_SIGNALS=ON make or make -j4 # Directly in the project directory: cmake -B build -DGPIODWRAP_DISABLE_SIGNALS=ON cmake --build build
g++ -std=c++17 -DGPIODWRAP_NO_SIGNALS main.cpp -o app -lgpiod
Copyright (C) 2026 Raspino-Projekt dev@raspino.org
GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007
You are free to use, modify, and distribute this project under the terms of the GPLv3.
Pull requests and improvements are welcome.
Feel free to fork, enhance, or suggest features.
⭐ If this wrapper helps your project — consider starring it on GitHub!
| Back | FazBrowse Home | New Git URL |