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 and GPIO_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.