Connect to the Dev Board Mini I/O pins

The Dev Board Mini provides access to several peripheral interfaces through the 40-pin expansion header, including GPIO, I2C, UART, and SPI. This page describes how you can interact with devices connected to these pins.

Because the Dev Board Mini runs Mendel Linux, you can interact with the pins from user space using Linux interfaces such as device files (/dev) and sysfs files (/sys). There are also several API libraries you can use to program the peripherals connected to these pins. This page describes a few API options, including python-periphery, Adafruit Blinka, and libgpiod.

Note: If most of your GPIO experience comes from boards like the Raspberry Pi, beware that—although the pin layout on this board might be the same—the vast majority of GPIO APIs out there are board-specific or must be updated for new boards. So the APIs you've used before probably won't work with this board.
Figure 1. Default pin functions on the 40-pin header
Warning: When handling the GPIO pins, be cautious to avoid electrostatic discharge or contact with conductive materials (metals). Failure to properly handle the board can result in a short circuit, electric shock, serious injury, death, fire, or damage to your board and other property.

Header pinout

Table 1 shows the header pinout, including the device or sysfs file for each pin, plus the character device numbers. If you'd like to see the SoC pin names instead, refer to section 4.9 in the Dev Board Mini datasheet. You can also see the pinout by typing pinout from the board's shell terminal.

All pins are powered by the 3.3 V power rail, with a max current of ~16 mA on most pins (although the default configuration is 2-4 mA max for most pins).

Note: Pins 8, 10, 29, 31, and 37 should not be used to drive resistive loads directly, due to weak drive strength.
Table 1. Pinout for the Dev Board Mini 40-pin header, with device file names and character device IDs (chip_number, line_number)
Chip, line Device path Pin function Pin Pin function Device path Chip, line
+3.3 V 1 2 +5 V
/dev/i2c-3 I2C1_SDA 3 4 +5 V
/dev/i2c-3 I2C1_SCL 5 6 Ground
0, 22 /sys/class/gpio/gpio409 GPIO22 7 8 UART0_TX /dev/ttyS0
Ground 9 10 UART0_RX /dev/ttyS0
0, 9 /sys/class/gpio/gpio396 GPIO9 11 12 GPIO36 /sys/class/gpio/gpio423 0, 36
0, 10 /sys/class/gpio/gpio397 GPIO10 13 14 Ground
0, 2 /sys/class/pwm/pwmchip0/pwm2 PWM_C 15 16 GPIO0 /sys/class/gpio/gpio387 0, 0
+3.3 V 17 18 GPIO1 /sys/class/gpio/gpio388 0, 1
/dev/spidev0 SPI_MO 19 20 Ground
/dev/spidev0 SPI_MI 21 22 GPIO7 /sys/class/gpio/gpio394 0, 7
/dev/spidev0 SPI_CLK 23 24 SPI_CSB /dev/spidev0.0
Ground 25 26 GPIO8 /sys/class/gpio/gpio395 0, 8
/dev/i2c-0 I2C2_SDA 27 28 I2C2_SCL /dev/i2c-0
/dev/ttyS1 UART1_TX 29 30 Ground
/dev/ttyS1 UART1_RX 31 32 PWM_A /sys/class/pwm/pwmchip0/pwm0 0, 0
0, 1 /sys/class/pwm/pwmchip0/pwm1 PWM_B 33 34 Ground
0, 37 /sys/class/gpio/gpio424 GPIO37 35 36 GPIO13 /sys/class/gpio/gpio400 0, 13
0, 45 /sys/class/gpio/gpio432 GPIO45 37 38 GPIO38 /sys/class/gpio/gpio425 0, 38
Ground 39 40 GPIO39 /sys/class/gpio/gpio426 0, 39

Program with python-periphery

The python-periphery library provides a generic Linux interface that's built atop the sysfs and character device interface, providing APIs to control GPIO, PWM, I2C, SPI, and UART pins.

By default, the python-periphery package is included with the Mendel system image on the Dev Board Mini. So no installation is required.

The following sections show how to instantiate an object for each pin on the Dev Board Mini header.

GPIO

You can instantiate a GPIO object using either the sysfs path (deprecated) or the character device numbers.

The following code instantiates each GPIO pin as input using the character devices:

gpio22 = GPIO("/dev/gpiochip0", 22, "in")  # pin 7
gpio9 = GPIO("/dev/gpiochip0", 9, "in")    # pin 11
gpio36 = GPIO("/dev/gpiochip0", 36, "in")  # pin 12
gpio10 = GPIO("/dev/gpiochip0", 10, "in")  # pin 13
gpio0 = GPIO("/dev/gpiochip0", 0, "in")    # pin 16
gpio1 = GPIO("/dev/gpiochip0", 1, "in")    # pin 18
gpio7 = GPIO("/dev/gpiochip0", 7, "in")    # pin 22
gpio8 = GPIO("/dev/gpiochip0", 8, "in")    # pin 26
gpio37 = GPIO("/dev/gpiochip0", 37, "in")  # pin 35
gpio13 = GPIO("/dev/gpiochip0", 13, "in")  # pin 36
gpio45 = GPIO("/dev/gpiochip0", 45, "in")  # pin 37
gpio38 = GPIO("/dev/gpiochip0", 38, "in")  # pin 38
gpio39 = GPIO("/dev/gpiochip0", 39, "in")  # pin 40
Note: Do not use pin 37 (gpio432) to drive resistive loads directly, due to weak drive strength.

For example, here's how to turn on an LED when you push a button:

from periphery import GPIO

led = GPIO("/dev/gpiochip0", 39, "out")  # pin 40
button = GPIO("/dev/gpiochip0", 13, "in")  # pin 36

try:
  while True:
    led.write(button.read())
finally:
  led.write(False)
  led.close()
  button.close()

For more examples, see the periphery GPIO documentation.

PWM

The following code instantiates each of the PWM pins:

pwm_a = PWM(0, 0)  # pin 32
pwm_b = PWM(0, 1)  # pin 33
pwm_c = PWM(0, 2)  # pin 15

For usage examples, see the periphery PWM documentation.

I2C

The following code instantiates each of the I2C ports:

i2c1 = I2C("/dev/i2c-3")  # pins 3/5
i2c2 = I2C("/dev/i2c-0")  # pins 27/28

For usage examples, see the periphery I2C documentation.

SPI

The following code instantiates the SPI port:

spi0 = SPI("/dev/spidev0.0", 0, 10000000)  # pins 19/21/23/14 (Mode 0, 10MHz)

For usage examples, see the periphery SPI documentation.

UART

The following code instantiates each of the UART ports:

uart0 = Serial("/dev/ttyS0", 115200)  # pins 8/10 (115200 baud)
uart1 = Serial("/dev/ttyS1", 9600)    # pins 29/31 (9600 baud)

For usage examples, see the periphery Serial documentation.

Program with Adafruit Blinka

The Blinka library not only offers a simple API for GPIO, PWM, I2C, and SPI, but also provides compatibility with a long list of sensor libraries built for CircuitPython. That means you can reuse CircuitPython code for peripherals that was originally used on microcontrollers or other boards such as Raspberry Pi.

To get started, install Blinka and libgpiod on your Dev Board Mini as follows:

sudo apt-get install python3-libgpiod

pip3 install adafruit-blinka

Then you can turn on an LED when you push a button as follows (notice this uses pin names from the pinout above):

import board
import digitalio

led = digitalio.DigitalInOut(board.GPIO39)  # pin 40
led.direction = digitalio.Direction.OUTPUT

button = digitalio.DigitalInOut(board.GPIO13)  # pin 36
button.direction = digitalio.Direction.INPUT

try:
  while True:
    led.value = button.value
finally:
  led.value = False
  led.deinit()
  button.deinit()

For more information, including example code using I2C and SPI, see the Adafruit guide for CircuitPython libraries on Coral. But we suggest you skip their setup guide and install Blinka as shown above. And beware that their guide was written for the Coral Dev Board, so some pin names are different on the Dev Board Mini. Also check out the Blinka API reference.

Program GPIOs with libgpiod

You can also interact with the GPIO pins using the libgpiod library, which provides both C++ and Python API bindings. But libgpiod is for GPIOs only, not any digital protocols. (The Blinka library uses libgpiod as its implementation for GPIOs.)

There's currently no online API docs for libgpiod, but the source code is fully documented. If you clone the repo, you can build C++ docs with Doxygen. For Python, you can install the libgpiod package and print the API docs as follows:

sudo apt-get install python3-libgpiod

python3 -c 'import gpiod; help(gpiod)'

Then you can turn on an LED when you push a button as follows:

import gpiod

CONSUMER = "led-demo"
chip = gpiod.Chip("0", gpiod.Chip.OPEN_BY_NUMBER)

led = chip.get_line(39)  # pin 40
led.request(consumer=CONSUMER, type=gpiod.LINE_REQ_DIR_OUT, default_vals=[0])
button = chip.get_line(13)  # pin 36
button.request(consumer=CONSUMER, type=gpiod.LINE_REQ_DIR_IN)

try:
  while True:
    led.set_value(button.get_value())
finally:
  led.set_value(0)
  led.release()
  button.release()