Skip to content

onlogic/Jetson-GPIO-Examples

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Utilizing GPIO for Aetina Jetson systems

This guide will walk you through utilizing GPIO pins on the 15-pin header located on the rear of your Jetson device with the libgpiod C library, specifically the command line interface and official python binding to demonstrate key concepts. This demo was created using an Orin NX running Jetpack 6.0 [L4T 36.3].

Warning

Any Python Code in this repository is purely for demonstration and testing purposes. Please ensure to visit the libgpiod repository for more info on python-based bindings. DO NOT USE FOR SAFETY CRITICAL APPLICATIONS.

What is libgpiod?

libgpiod is a C library designed to interact with linux GPIO devices. Since linux 4.8, the sysfs interface has been depricated and it is recommended to use charcter devices instead. This also means that the CLI tool shown below was also depricated. This demo will walk through some basic demos to show functionality interacting with the GPIO.

Basic Installation Steps

The old version of gpiod(v1.5.4) was depricated and the below sample code has been based on the currently supported release, You will need at least v2.0.2. Depending on your installed version of Jetpack, you likely have a depricated version of libgpiod installed for system functions. We want to make sure the user calls upon a recent version:

  • Open a terminal session
  • First we should ensure are system is up to date sudo apt-get upgrade
  • libgpiod depends on python3-dev , this should already been installed, but just in case we can run sudo apt install python3-dev
  • Next we can install gpiod. pip install gpiod. Running pip list --user should show the package.
    • Ensure this installs a version later than 2.0.2.
    • If you see 1.5.4 being installed, you can run pip uninstall gpiod and then pip install gpiod== to check if you can install a recent version.
    • If you encounter an error that the package is not available, You should upgrade your Jetson to a newer version of Jetpack before continuing. Reference our Jetpack 6 upgrade guide for more information.

Jetson GPIO Pin Basics

Before we dive into samples, let's take a brief look at the GPIO pins available. Each Aetina Jetson system has GPIO located the rear of the system. For all systems there is a DB-15 connector multi-purpose I/O, which is where are GPIO pins are. You can reference the system manuals for PIN addresses, but for simplicity they are listed below.

Nano/NX GPIO Pins

Physical Pin GPIO Name Linux Pin Name gpiochip0 line #
1 GPIO01 PQ.05 105
2 GPIO11 PQ.06 106
3 GPIO12 PN.01 85
4 GPIO13 PH.00 43
5 GPIO05 PZ.07 137

AGX GPIO Pins

Physical Pin GPIO Name Linux Pin Name
1 GPIO17 PP.04
2 GPIO11 PAC.05
3 PWM01 PR.00
4 GPIO27 PN.01
5 GPIO35 PH.00

We will use NX GPIO01 for the following examples. We can call upon these pins to set an output (High/Active = 3.3V) (Low/Inactive = 0V) or set as an input.

Libgpiod Identifying Pins - Python (Current)

Since we can no longer user the CLI tool to gather information on our pins. We should run the following if we want to use lines or identify chips.

import gpiod

with gpiod.Chip("/dev/gpiochip0") as chip:
    info = chip.get_info()
    print(f"{info.name} [{info.label}] ({info.num_lines} lines)")

This assumes you already know which chip the GPIO is on. If you'd like to check if a chip exists you can use the following, replacing x with the chip you'd like to identify.

gpiod.is_gpiochip_device("/dev/gpiochipX")

Libgpiod Identifying Pins - Command Line (Depricated)

To interface with GPIO pins we need to know the chip it is on and then the line (We can use either the GPIO Name (ex. PQ.05) or the chip line (105) in most cases). Reminder: This requires the depricated version of the package. You can install it with python sudo apt-get install gpiod. Ensure your applications are calling on the user installed 2.0+ version or the below code examples will not work.
gpioinfo will allow us to list all of the chips and their lines. Let's find the info we need for GPIO01. Here we can see that gpiochip0 contains our address.
gpioinfo cli
Scrolling down to PQ.05 shows us that corresponding line for chip gpiochip0 is 105.
gpioinfo cli

There are additional cli commmands avaiable such as gpioget and gpioset for temporarily reading and setting values. gpiomon which waits for edge events and gpionofity which waits for state changes. More info on usage can be found on the libgpiod readme.

Libgpiod Python Sample Code

Let's breakdown a simple output script, based on official examples. The following uses line #, but remember we can also use the name shown above.

import gpiod
import time
from gpiod.line import Direction, Value

LINE = 105

with gpiod.request_lines(
    "/dev/gpiochip0",
    consumer="basic-demo",
    config={
        LINE: gpiod.LineSettings(
            direction=Direction.OUTPUT, output_value=Value.ACTIVE
        )
    },
) as request:
    while True:
        request.set_value(LINE, Value.ACTIVE)
        print("Active")
        time.sleep(10)
        request.set_value(LINE, Value.INACTIVE)
        print("Inactive")
        time.sleep(10)
        print("Complete")

An important note about gpiod, quitting forcefully will cause the pin to hang in the last known state. If you try to immediately run code against the same pin from the same terminal window after force quiting you will recieve an error "IOError: [Errno 16] Device or resource busy". With v2.0.2+ releasing the pin is as simple as opening up a new terminal window. Always design a way for your code to exit gracefully if using GPIO pins.

# First we are importing the necessary packages
import gpiod 
import time

# In this example we will use:
# Direction, which means is it an input or an output
# Value which is the high or low state for output pins.
from gpiod.line import Direction, Value

#Here we will set a global variable for the line we want to use.
LINE = 105

# Here we are defining our request for the line.
# We first define the target chip, remember line 105 is contained in gpiochip0
# Creating a GPIO virtual device (consumer) to request the GPIO
# The creating a configuration for what we want are line to do. setting the direction as output and the initial value as Active (High)
with gpiod.request_lines(
    "/dev/gpiochip0",
    consumer="basic-demo",
    config={
        LINE: gpiod.LineSettings(
            direction=Direction.OUTPUT, output_value=Value.ACTIVE
        )
    },

# Now we can call our request
) as request: 
    while True:
        #We are calling request to set the value, of LINE 105, and set the Value to High
        request.set_value(LINE, Value.ACTIVE)
        print("Active")
        time.sleep(10)
        #Here we are doing the same call as above, but this time we are setting teh Value to Low
        request.set_value(LINE, Value.INACTIVE)
        print("Inactive")
        time.sleep(10)
        print("Complete")

Using a multimeter, we can check that the code is working correctly. During active we should see 3.3V, whereas during inactive we should see 0V. Now you see how we can how we can create a basic output example, let's look at some other requests. If we wanted to reconfigure the direction of a line from an output to an input, we could do so with the following:

request.reconfigure_lines(
            config={line_offset: gpiod.LineSettings(
                    direction=Direction.INPUT
                )
            }
        )

If we wanted to then read the value of the input we could call:

as request:
        value = request.get_value(LINE)
        print("{}={}".format(LINE, value))

These are just a few examples of what's possible with libgpiod. For further examples, check out the official libgpiod examples repository.

About

Getting Started Guide for Utilizing Aetina Jetson GPIO Pins

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages