Skip to main content

Easy-Peasy Peripheral Interfacing with Pi, Python and Pmods!


The perfect combination for cooking up peripheral interfacing recipes in no time at all.

The Pmod — peripheral module — is an open specification standard by Digilent that is designed for interfacing peripherals with FPGA and microcontroller host platforms. Available in 6-pin and 12-pin versions, with a characteristically compact form factor, they provide a neat solution to system prototyping and with many engineers owning at least a small selection of Pmods.

Just as the diverse array of available Pmods makes it possible to quickly prototype a wealth of hardware configurations, the eminently approachable Python programming language and its bountiful software ecosystem make it possible to rapidly prototype applications.

Throw a Raspberry Pi into the mix also and you’ve got a powerful prototyping platform. However, there are a couple of things, on the hardware and software side, which would make integration and rapid prototyping just that bit easier. So let’s start with the former and enter the Pmod HAT!

DesignSpark Pmod HAT


The Pmod HAT (144-8419) has three 2x6-pin Pmod ports with support for I2C, SPI, UART and GPIO interfacing. It can be used with any model of Raspberry Pi that has a 40-pin GPIO connector, with power being supplied via either this or a barrel connector and external 5VDC power supply.

The ports are labelled as follows:

  • JA: supports SPI and GPIO Pmods.
  • JB: supports SPI and GPIO Pmods, plus 6-pin I2C Pmods on the bottom row.
  • JC: supports UART and GPIO Pmods.

There are also two jumpers:

  • JP1 & JP2: Enables pull-up resistors on JB2 I2C when shorted.
  • JP3: Enables writing to the onboard EEPROM.

The EEPROM stores a device tree fragment which is used to identify the board and configure the O/S and drivers accordingly. For those not familiar with the device tree concept, it is a compiled database that is used to describe an ARM-based system and provides functionality similar to the BIOS of an Intel/AMD computer. This would only be modified with more advanced use cases.

So, now we have a convenient way of plumbing together the hardware that avoids having to use messy jumper wires, what about the software? Enter DesignSpark.Pmod!



DesignSpark.Pmod is a Python library that:

  • Provides simple, consistent interfaces for supported Pmods
  • Checks that Pmod and port capabilities match
  • Checks for port usage conflicts
  • Is provided with examples to get you started

Pin multiplexing is standard with many (most?) modern SoCs and it can bring great flexibility but at the expense of having to do some initial setup to configure I/O pins for your particular use. While Pmods can be interfaced via one of a number of different methods and when you combine these two things together, it does mean that you do need to take care to not e.g. connect SPI and GPIO Pmods to ports which share host I/O pins and which would, therefore, result in a setup conflict.

What the library does is to check that a Pmod is supported by a particular port on the HAT and that this use would not be in conflict. The initial release also provides convenient interfaces for 6x Pmods and the library has been written in such a way that it can be extended to support more.



First we need to make sure that SPI is enabled and this can be done using raspi-config.

$ sudo raspi-config


  • Option 5 - Interfacing
  • P4 - SPI
  • Enable → YES

Next, we need to install a few Raspbian build dependencies:


$ sudo apt-get update

$ sudo apt-get install python-pip python-dev libfreetype6-dev libjpeg-dev build-essential

Finally, we can use the Python package manager to install DesignSpark.Pmod and dependencies:

$ sudo -H pip install designspark.pmod

Note that the official docs can be found at:

This website should always be referred to for the latest documentation.

The associated PyPi project page and GitHub development repository are located at:

Interfacing with Pmods

At the time of writing six Pmods are supported by the library and next, we’ll take a quick look at these and basic methods for interfacing with them.




PmodAD1 (134-6443) is a two channel 12-bit ADC that features Analog Devices’ AD7476A, with a sampling rate of up to 1 million samples per second, and a 6-pin SPI Pmod interface.

To read from this we simply need to import the library, create an object with the AD1 module on a suitable port, then use the readA1Volts() method to get an ADC reading. E.g.:

from DesignSpark.Pmod.HAT import createPmod

adc = createPmod('AD1','JBA')

volts = adc.readA1Volts()

In this example using port “JAA”, which is the top row of the 2x6 pin JA connector.

Note that at the present time only ADC channel A1 is supported due to the way that SPI is configured when used with a Pi.




The PmodHB3 (Digilent part no.410-069) is a 2A H-bridge circuit for DC motor drive up to 12V, with a 6-pin GPIO interface.

Once again we import the library and then to spin the motor in the forward direction simply:

motor = createPmod('HB3','JAA')

The number passed to the forward method is the duty cycle. There are also methods to spin in the reverse direction, stop, change the PWM frequency and clean up.



Like the AD1, the Pmod ISNS20 (136-8069) is another 6-pin SPI Pmod, but this time a ±20A DC or AC input, high accuracy current sensor. After importing the library, to read from this we would:

isens = createPmod('ISNS20','JBA')
mA = isens.readMilliAmps()





By now you should be used to this and to read an integer value from the PmodMIC3 (Digilent part no.410-312) ADC we would import the library, following which:

mic = createPmod('MIC3','JBA')
int = mic.readIntegerValue()





The PmodOLEDrgb (134-6481) is an organic RGB LED module with a 96×64 pixel display and that is capable of 16-bit colour resolution. It is the first 12-pin Pmod we will have encountered. It is also the first which will require a couple of additional libraries for use.

To draw “Hello, World!” in a bounding box we would simply:

from DesignSpark.Pmod.HAT import createPmod
from luma.core.render import canvas
from luma.oled.device import ssd1331
oled = createPmod('OLEDrgb','JA')
device = oled.getDevice()
with canvas(device) as draw:
   draw.rectangle(device.bounding_box, outline="white", fill="black")
   draw.text((16,20), "Hello, World!", fill="white")
   while True:

The luma.core and luma.oled libraries provide a lot of really great functionality that can be used with this Pmod and checking out the associated documentation is highly recommended.



Finally, PmodTC1 (134-6476) is another 6-pin SPI Pmod, this time featuring a cold-junction thermocouple-to-digital converter designed for a classic K-Type thermocouple wire. The wire provided with the module has an impressive temperature range of -73°C to 482°C.

After importing the library to read from this we would:

therm = createPmod('TC1','JBA')
cel = therm.readCelcius()

Complete basic examples for each of the above Pmods, along with a couple that is slightly more advanced — which includes an analog clock face example for the OLEDrgb module — are provided together with API documentation via Read the Docs.

Wrapping up

So there we have it, thanks to the DesignSpark Pmod HAT and supporting library, we can now interface Pmods and prototype applications using a Raspberry Pi and Python faster than ever before. It should also now be reasonably straightforward to add support for additional Pmods to the library and if you would like to contribute support for a new module get in touch.

Andrew Back

Open source (hardware and software!) advocate, Treasurer and Director of the Free and Open Source Silicon Foundation, organiser of Wuthering Bytes technology festival and founder of the Open Source Hardware User Group.