How-To Digital Input/Output (DIO)
Description
The Pi-Tron CM5 has four Digital Inputs/Outputs also referred to as DIO. All DIOs are connected to the onboard GPIO expander MCP23017 and can be controlled via I²C commands using the libgpiod library for example. Each DIO can be used either as digital input or as digital output, but not both at the same time. Furthermore, when using a DIO as digital output and the output is set to high the digital input also goes high. This technique allows the user to read back the actual current state of a DIO.
All DIOs operate on 24 volts.
This How-To shows how to enable the GPIO expander chip and access the GPIOs to control the DIOs.

Requirements
- Development computer with network access to the Pi-Tron CM5 or alternatively connect an HDMI monitor, mouse and keyboard.
- To login into the Pi-Tron CM5 via network, it is requires that the SSH server is running.
- 24 volts power supply with 2 pin power plug for the Pi-Tron CM5.
- An active Internet connection to install additional software.
- The the MCP23017 I/O expander is connected to I2C bus 1 and has the address 0x20.
How-To
Preparation
Activate I2C
First make sure the I2C bus 1 is activated. Use the raspi-config program to enable the I2C interface, if this is not already the case. Afterwards reboot the Pi-Tron CM5.




Install the libgpiod library
To access GPIOs on the Raspberry Pi weather they are part of the Raspberry Pi directly or are added via I2C, the libgpiod library offers service programs to read and write GPIOs from the OS console but also via APIs from different programming languages.
sudo apt update
sudo apt install gpiod libgpiod-dev libgpiod-doc
Install the i2c-tools
Installing the i2c-tools allows the user to perform an I2C bus scan to see which addresses (devices) are available on the bus.
sudo apt update
sudo apt install i2c-tools
Add the MCP23017 overlay to the config.txt file
To activate the MCP23017 driver within the Raspberry Pi OS, the corresponding overlay needs to be added to the config.txt file:
sudo nano /boot/firmware/config.txt
At the end of the file add the following line.
dtoverlay=mcp23017,noints=1
Save the changes and leave the editor with Ctrl + O → Enter → Ctrl + X.
Reboot
Reboot the Pi to activate all the changes.
sudo reboot
Accessing the DIOs
The digital inputs and outputs are connected to the I/O expander as follows.
- DIO 1 - Output = EGPIO 0 (GPA0)
- DIO 1 - Input = EGPIO 1 (GPA1)
- DIO 2 - Output = EGPIO 2 (GPA2)
- DIO 2 - Input = EGPIO 3 (GPA3)
- DIO 3 - Output = EGPIO 4 (GPA4)
- DIO 3 - Input = EGPIO 5 (GPA5)
- DIO 4 - Output = EGPIO 6 (GPA6)
- DIO 4 - Input = EGPIO 7 (GPA7)
Overview of the I/O expander wiring.

Circuit diagram of the internal wiring and connections for each DIO.

The DIOs are located on connector X50, the pin layout is as shown in the image below.

Connection examples on how to use the four DIOs as digital output or input. Also observe the polarity of the plug, see image above.
Using inductive loads:
For inductive loads, it must be ensured externally that the voltage at the output is never higher than 40V. This can be achieved, for example, with a free-running diode (1N4004) as shown above. Inductive loads are DC motors, relays, magnetic coils, etc. The ground connections (GND) of external power supply units must be connected directly to the GND connections on the connection strip of the digital outputs.
The I/O expander is connected to I2C bus 1 on the Pi-Tron CM5 and has the address 0x20. Before trying to access the GPIOs, it's a good idea to first check that the I/O expander is really there.
-
Log in into the Pi-Tron CM5 and run the i2cdetect program to see if the I/O expander is present at address 0x20. Note: Instead of seeing the number 20, there should be 2 U's, which means this address is in use by a driver, this is correct.
sudo i2cdetect -y 1 -
The result should look something like the following table:
0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: 50 -- 52 -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- -- -
Once the presents of the I/O expander is confirmed, the next step is to find out how it is named, meaning which device name and number it has received from the system. Usually the device name is something like gpiochipXY, e.g. gpiochip14.
-
Run the program gpiodetect to list all known GPIO devices.
pi@raspberrypi:~ $ gpiodetect gpiochip0 [pinctrl-rp1] (54 lines) gpiochip10 [gpio-brcmstb@107d508500] (32 lines) gpiochip11 [gpio-brcmstb@107d508520] (4 lines) gpiochip12 [gpio-brcmstb@107d517c00] (15 lines) gpiochip13 [gpio-brcmstb@107d517c20] (6 lines) gpiochip14 [mcp23017] (16 lines) gpiochip0 [pinctrl-rp1] (54 lines) -
The I/O expander was assigned the device name gpiochip14, which can be identified by the driver/chip name mcp23017 in square brackets behind the device name. The result also tells us that the I/O expander has 16 lines (GPIOs), however only the GPIO 0 to 7 are of interest.
-
To turn DIO 1 on, run the program gpioset with the following parameters:
gpioset gpiochip14 0=1 -
To turn DIO 1 off, run the program gpioset like this:
gpioset gpiochip14 0=0 -
To read the state of the digital input of DIO 2, use the program gpioget. If the program prints 0 then there is no signal is present, the input is low or off. If a 1 appears, a high signal is applied to DIO 2.
gpioget gpiochip14 3 -
To get a continuous readout, try using the watch command to run gpioget every second and refresh the result on the console.
watch -n 1 gpioget gpiochip14 3 -
This outputs the following information continuously.
Every 1.0s: gpioget gpiochip14 3 raspberrypi: Mon Jan 1 10:00:00 2022 1 -
The above example shows that the input of DIO 2 is high, meaning a 24 volt signal is present. The watch command can be aborted with Ctrl + C.
Python 3 demo
This section shows how to access the GPIOs on the MCP23017 and control the DIOs through Python 3.
-
First update the apt package manager and then install the libgpiod module for Python 3.
sudo apt update sudo apt install python3-libgpiod -
Now create a new Python file in the home folder.
nano dio-test.py -
Enter the following program into the file.
# Python 3 and libgpiod example import gpiod import time # Open gpiochip14 - Adjust this name to the actual device name of the MCP23017 chip=gpiod.Chip("gpiochip14", gpiod.Chip.OPEN_BY_NAME) # Get line object for DIO 1 output (gpio offset 0) line1 = chip.get_line(0) # Request the line as output line1.request(consumer='dio1output', type=gpiod.LINE_REQ_DIR_OUT) # Get line object for DIO 2 input (gpio offset 3) line2 = chip.get_line(3) # Request the line as input line2.request(consumer='dio2input', type=gpiod.LINE_REQ_DIR_IN) # Infinity loop - Use Ctrl + C to abort while True: # Set DIO 1 output to high print("Set DIO 1 output to 1") line1.set_value(1) time.sleep(1) # Get DIO 2 input value print("DIO 2 input value: ", line2.get_value()) time.sleep(1) # Set DIO 1 output to low print("Set DIO 1 output to 0") line1.set_value(0) time.sleep(1) # Get DIO 2 input value print("DIO 2 input value: ", line2.get_value()) time.sleep(5) print("") -
Save the file with Ctrl + O and leave the editor with Ctrl + X.
-
Now run the program.
sudo python3 dio-test.py -
The output on the console should look something like this:
Set DIO 1 output to 1 DIO 2 input value: 1 Set DIO 1 output to 0 DIO 2 input value: 0 Set DIO 1 output to 1 DIO 2 input value: 1 Set DIO 1 output to 0 DIO 2 input value: 0 Set DIO 1 output to 1 DIO 2 input value: 1 Set DIO 1 output to 0 DIO 2 input value: 0 Set DIO 1 output to 1 DIO 2 input value: 1 Set DIO 1 output to 0 DIO 2 input value: 0 -
Press Ctrl + C at any time to about the program.
This concludes the How-To for the Digital Inputs/Outputs (DIO) on the Pi-Tron CM5. Feel free to further try out the gpioset and gpioget programs, experiment with the Python 3 program or make your own program in Python 3 or maybe in C.
Restrictions
- No known Restrictions
Related documentation
- MCP23017 16-Bit I/O Expander: https://ww1.microchip.com/downloads/en/devicedoc/20001952c.pdf
- Covering all aspects of the Raspberry Pi, the official documentation: https://www.raspberrypi.com/documentation
- Documentation for the raspi-config tool: https://www.raspberrypi.com/documentation/computers/configuration.html
- Linux I2C-Tools package: https://i2c.wiki.kernel.org/index.php/I2C_Tools
- Manpages i2c-tools: https://manpages.debian.org/bullseye/i2c-tools/index.html
- Manpages gpiodetect: https://manpages.debian.org/experimental/gpiod/gpiodetect.1.en.html
- Manpages gpioget: https://manpages.debian.org/experimental/gpiod/gpioget.1.en.html
- libgpiod Debian package information: https://packages.debian.org/source/bullseye/libgpiod
- lingpiod git repository: https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git
- Python 3 libgpiod on pypi: https://pypi.org/project/gpiod

