Using the GPIOs on your ZED Box Mini
The ZED Box Mini exposes 2 GPIOs (General Purpose Input/Output) that can be used for various purposes, such as controlling external devices or reading sensor data.
The GPIO pins are accessible via the GPIO
header located on the back side of the ZED Box Mini. A full description of the pinout is available in the Connectivity Guide.
- #03 - GPIO_11 [CMOS-3.3V]
- #04 - GPIO_12 [CMOS-3.3V]
GPIO_11
and GPIO_12
can be used as general-purpose I/O pins. They are 3.3V compliant and can be configured as either inputs or outputs.
📌 Note: If you purchased the ZED Box Mini or the Mini Carrier Board before October 2025, please upgrade your device by using the flash script available in the Flash to Reset/Upgrade section of the documentation. This is required to enable the
GPIO_11
andGPIO_12
pins.
To control the GPIO pins, you must install the latest gpiod library from the source and its C++ and Python bindings. The binary version available in the Ubuntu 22.04 repository is outdated and does not provide the required development libraries.
mkdir -p ~/libgpiod
cd ~/libgpiod
# Download the latest stable version of libgpiod (replace x.y.z with the actual, i.e 2.2.2)
wget https://mirrors.edge.kernel.org/pub/software/libs/libgpiod/libgpiod-x.y.z.tar.xz
tar -xvf ./libgpiod-x.y.z.tar.xz
cd ./libgpiod-x.y.z/
./configure --enable-bindings-cxx --enable-bindings-python --enable-tools
make -j6
sudo make install
📌 Note: To use the pins as inputs you must use a pull-up or pull-down resistor (10kΩ is a good value for the resistor) according to the expected signal:
- Use a pull-up resistor to detect when the pin is connected to GND (read low values).
- Use a pull-down resistor to detect when the pin is connected to VCC (read high values).
Without a pull-up or pull-down resistor, the pin will be latched, keeping the latest value read, until it is explicitly changed.
Add the current user to the gpio
group to access the GPIO pins without using sudo
:
sudo usermod -aG gpio $USER
Command Line Interface (CLI) examples #
Set a pin HIGH, then wait for the user to press ENTER:
GPIO_11
(PQ.06):gpioset --mode=wait gpiochip0 106=1
GPIO_12
(PN.01):gpioset --mode=wait gpiochip0 85=1
Set a pin LOW, then wait for the user to press ENTER:
GPIO_11
(PQ.06):gpioset --mode=wait gpiochip0 106=0
GPIO_12
(PN.01):gpioset --mode=wait gpiochip0 85=0
Remove --mode=wait
to execute the command without waiting for user input. This is useful for floating pins.
Read the GPIO level:
GPIO_11
(PQ.06):gpioget gpiochip0 106
GPIO_12
(PN.01):gpioget gpiochip0 85
Read two values at the same time:
gpioget gpiochip0 106 85
You can find the full documentation of each CLI command on the official guide.
Python example #
The following Python script demonstrates how to control and read the GPIO pins using the gpiod
library. It toggles the state of GPIO_11
and GPIO_12
every second for 10 seconds, then reads their values for another 10 seconds.
You can use the VCC_3V3
pin (pin #07) of the GPIO
header to stimulate the GPIO pins during the reading phase and verify their functionality in real-time.
import time
import gpiod
from gpiod.line import Direction, Value
# Get information about the GPIO chip
with gpiod.Chip("/dev/gpiochip0") as chip:
info = chip.get_info()
print(f"GPIO Chip: {info.name} [{info.label}] - {info.num_lines} lines")
# Define GPIO lines
line11 = 106 # GPIO_11
line12 = 85 # GPIO_12
# Set the lines as OUTPUT and set initial values to HIGH
request_out = gpiod.request_lines(
"/dev/gpiochip0",
consumer="example",
config={
line11: gpiod.LineSettings(direction=Direction.OUTPUT, output_value=Value.ACTIVE),
line12: gpiod.LineSettings(direction=Direction.OUTPUT, output_value=Value.ACTIVE)
}
)
# Toggle GPIO_11 and GPIO_12 values for 10 seconds
total=10
for i in range(total):
if i%2 == 1:
output11=Value.ACTIVE
output12=Value.INACTIVE
else:
output11=Value.INACTIVE
output12=Value.ACTIVE
print(f"[{i+1}/{total} Set Value - GPIO_11: {output11} / GPIO_12: {output12}", end ='\r')
# Set GPIO_11 LOW
request_out.set_value(line11, output11)
# Set GPIO_12 HIGH
request_out.set_value(line12, output12)
# Wait 1 second
time.sleep(1)
print()
# Set both lines to LOW before releasing them
request_out.set_values(
values={
line11: Value.INACTIVE,
line12: Value.INACTIVE
}
)
# Release the lines
request_out.release()
# Set the lines as INPUT
request_in = gpiod.request_lines(
"/dev/gpiochip0",
consumer="example",
config={
line11: gpiod.LineSettings(direction=Direction.INPUT),
line12: gpiod.LineSettings(direction=Direction.INPUT)
}
)
# Read GPIO_11 and GPIO_12 values for 10 seconds
duration=10.0
start = time.time()
exit = False
while (exit==False):
now = time.time()
elapsed = now-start
if(elapsed>10):
exit = True
# Read GPIO11
value11 = request_in.get_value(line11)
# Read GPIO12
value12 = request_in.get_value(line12)
# Print the current values with remaining time
remaining = int(duration-elapsed)
print(f"Read Value - GPIO_11: {value11} / GPIO_12: {value12} - to end: {remaining} sec", end ='\r')
print()
The output will look like this:
$ python3 test_gpio.py
GPIO Chip: gpiochip0 [tegra234-gpio] - 164 lines
[10/10 Set Value - GPIO_11: Value.ACTIVE / GPIO_12: Value.INACTIVE
Read Value - GPIO_11: Value.INACTIVE / GPIO_12: Value.INACTIVE - to end: 0 sec
The first line shows the GPIO chip information, the second line shows the status of the toggling operation, and the last line shows the read values of the GPIO pins. The information will update in place while the script is running.
You can find the full documentation of the Python binding API in the official guide.
C++ example #
The following C++ program demonstrates how to control GPIO_11
and GPIO_12
using the gpiod
library. It toggles the state of GPIO_11
and GPIO_12
every second for 10 seconds, then reads their values for another 10 seconds.
You can use the VCC_3V3
pin (pin #07) of the GPIO
header to stimulate the GPIO pins during the reading phase and verify their functionality in real-time.
#include <iostream>
#include <string>
#include <gpiod.hpp>
#include <thread>
#include <chrono>
// Function to toggle single GPIO line value
gpiod::line::value toggle_value(::gpiod::line::value v);
// Function to toggle multiple GPIO line values
void toggle_values(gpiod::line::values &values);
// Function to print GPIO line offsets and their corresponding values
void print_values(gpiod::line::offsets const &offsets, gpiod::line::values const &values);
// Main function to demonstrate GPIO line manipulation
int main(void) {
// Set the GPIO chip system path
const std::filesystem::path chip_path("/dev/gpiochip0");
// Define the GPIO line offsets to be used
const ::gpiod::line::offsets line_offsets = {
106, // GPIO_11
85 // GPIO_12
};
// Retrieve a GPIO chip by its path and print its name and label
gpiod::chip chip(chip_path);
auto info = chip.get_info();
std::cout << "GPIO chip: " << info.name() << " [" << info.label() << "] ("
<< info.num_lines() << " lines)" << ::std::endl;
// Initialize GPIO line values
gpiod::line::values values = {
gpiod::line::value::ACTIVE, // GPIO_11
gpiod::line::value::INACTIVE // GPIO_12
};
// Create a request to toggle multiple GPIO lines
auto request =
chip.prepare_request()
.set_consumer("test_gpio")
.add_line_settings(
line_offsets,
::gpiod::line_settings().set_direction(
::gpiod::line::direction::OUTPUT))
.set_output_values(values)
.do_request();
// Toggle the GPIO lines for ten seconds
const int duration = 10;
for (int i = 0; i < duration; i++) {
std::cout << "\r[" << (i + 1) << "/" << duration << "] Set Value: ";
print_values(line_offsets, values);
std::this_thread::sleep_for(std::chrono::seconds(1));
toggle_values(values);
request.set_values(line_offsets, values);
}
std::cout << std::endl;
// Reconfigure the GPIO lines as inputs
request.reconfigure_lines(gpiod::line_config().add_line_settings(
line_offsets,
gpiod::line_settings()
.set_direction(::gpiod::line::direction::INPUT)));
// Read and print the GPIO line values for ten seconds
auto start = std::chrono::steady_clock::now();
int64_t elapsed=0;
do {
// Read the current values of the GPIO lines
auto read_values = request.get_values(line_offsets);
// Print the read values
std::cout << "\rRead Value: ";
print_values(line_offsets, read_values);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
// Update elapsed time (sec)
elapsed = (std::chrono::steady_clock::now() - start).count() / 1'000'000'000;
std::cout << " - " << elapsed << " sec " << std::flush;
} while (elapsed < std::chrono::seconds(duration).count());
std::cout << std::endl;
return EXIT_SUCCESS;
}
gpiod::line::value toggle_value(::gpiod::line::value v)
{
return (v == gpiod::line::value::ACTIVE) ?
gpiod::line::value::INACTIVE :
gpiod::line::value::ACTIVE;
}
void toggle_values(gpiod::line::values &values)
{
for (size_t i = 0; i < values.size(); i++)
values[i] = toggle_value(values[i]);
}
void print_values(gpiod::line::offsets const &offsets,
gpiod::line::values const &values)
{
for (size_t i = 0; i < offsets.size(); i++)
std::cout << (offsets[i]==106?"GPIO_11":"GPIO_12") << ": " << values[i] << " " << std::flush;
}
Build and Run #
Create a file named test_gpio.cpp
and copy the C++ code above into it. Then, compile and run the program using the following commands:
g++ -o test_gpio test_gpio.cpp -lgpiodcxx -lgpiod
run the example:
./test_gpio
The output will look like this:
$ ./test_gpio
GPIO chip: gpiochip0 [tegra234-gpio] (164 lines)
[10/10] Set Value: GPIO_11: INACTIVE GPIO_12: ACTIVE
Read Value: GPIO_11: INACTIVE GPIO_12: INACTIVE - 10 sec
The first line shows the GPIO chip information, the second line shows the status of the toggling operation, and the last line shows the read values of the GPIO pins. The information will update in place while the script is running.
Other examples and more complex use cases can be found in the libgpiod Source Code repository.
You can find the full documentation of the C++ binding API in the official guide.
If you have any questions or need assistance with GPIO programming, please visit the StereoLabs Forums to connect with the community and get support from our experts.