This is a Raspberry Pi breakout board + DIN rail case to use Pis in PLC-like industrial situations.
The design relies on a Raspberry Pi 4 for all functions to work. Pi 5 does also work but won't fit the 3D printed case, while Pi 3 and below don't allow for all functions to be used.
The PiPLC is intended to be used with Home Assistant, as well as OpenPLC. Obviously, since it's just a breakout board for any Pi, you can run whatever software you want, but Home Assistant and OpenPLC are the ones inspiring the design of this project.
For an example use with your own software, check out Grass!
IO featured on board the PLC are:
- 8 x 24 V tolerant optocoupled inputs
- 8 x 16A Relays (250 V AC / 24 V DC)
- KNX TP
- Modbus RTU / RS-485
- I²C
- 2 x analog 3.3 V PWM outputs
All the parts are or will be stocked at Tindie!
If you like my work please consider supporting me!
- GPIO mapping
- Pinout
- I/O
- On board devices
- Example Hardware
- Software
- Raspberry pi configuration
- Making your own
- Tools used
- Sources
- Donations
- License
GPIO Name | PiPLC function | OpenPLC | Home Assistant | Codesys |
---|---|---|---|---|
GPIO_02 |
🟦 I²C SDA | |||
GPIO_03 |
🟦 I²C SCL | |||
GPIO_04 |
🟦 Modbus TX | /dev/ttyAMA3 |
/dev/ttyAMA3 |
|
GPIO_05 |
🟦 Modbus RX | /dev/ttyAMA3 |
/dev/ttyAMA3 |
|
GPIO_06 |
🟦 Modbus RTS | /dev/ttyAMA3 |
/dev/ttyAMA3 |
|
GPIO_07 |
🟥 Q4 | %QX0.3 |
✅ | |
GPIO_08 |
🟥 Q3 | %QX0.2 |
✅ | |
GPIO_09 |
🟨 I5 | %IX0.4 |
✅ | |
GPIO_10 |
🟨 I4 | %IX0.3 |
✅ | |
GPIO_11 |
🟨 I6 | %IX1.5 |
✅ | |
GPIO_12 |
🟥 Q5 | %QX0.4 |
✅ | |
GPIO_13 |
🟨 I7 | %IX0.6 |
✅ | |
GPIO_14 |
🟦 KNX TX | ❌ | /dev/ttyAMA0 |
|
GPIO_15 |
🟦 KNX RX | ❌ | /dev/ttyAMA0 |
|
GPIO_16 |
🟥 Q6 | %QX0.5 |
✅ | |
GPIO_17 |
🟨 I1 | %IX0.0 |
✅ | |
GPIO_18 |
🟧 PWM_0 | %QW0 |
✅ | |
GPIO_19 |
🟧 PWM_1 | %QW1 |
✅ | |
GPIO_20 |
🟥 Q7 | %QX0.6 |
✅ | |
GPIO_21 |
🟥 Q8 | %QX0.7 |
✅ | |
GPIO_22 |
🟨 I3 | %IX0.2 |
✅ | |
GPIO_23 |
🟦 1-Wire | ✅ | ||
GPIO_24 |
🟥 Q1 | %QX0.0 |
✅ | |
GPIO_25 |
🟥 Q2 | %QX0.1 |
✅ | |
GPIO_26 |
🟨 I8 | %IX0.7 |
✅ | |
GPIO_27 |
🟨 I2 | %IX0.1 |
✅ |
Pins marked unusable with OpenPLC are either not broken out, or differ too much from OpenPLC's mapping. As OpenPLC's mapping is immutable, these pins might not be used if PiPLC is used with the OpenPLC runtime and Pi default hardware layer.
1 | 2 | 3 | 4 |
---|---|---|---|
+24 V |
+24 V |
GND |
GND |
The PiPLC is to be supplied with 24 V and requires at least a 1 A power supply under full load.
While it will theoretically work at 12 V, the relays used for Q1-8
require 24V coil voltage to trigger. If you are not placing the relays, feel free to supply your PLC with 12 V though.
Internally, 5V is generated by a TPS54331D
based DC-DC converter.
At J10
12/24V is passed through unprotected from the power input.
At J2
and J8
5 V from the DC-DC can be used to draw up to 500mA (protected through a polyfuse).
At J3
, 3V3 from the RPI can be used to draw up to 500mA (protected through a polyfuse)
1 | 2 | 3 | 4 |
---|---|---|---|
+5 V |
🟦 Modbus B |
🟦 Modbus A |
GND |
Modbus is an industrial communication protocol often used with PLCs communicating with I/O extensions or other PLCs.
The wire based one used here is called Modbus RTU
and is based on half-duplex RS-485 so the header can also be used for that if you dislike Modbus.
OpenPLC natively supports Modbus to talk to I/O, while Home Assistant has a Modbus integration.
Note
To enable Modbus on your Pi, make sure to enable UART3
at GPIO5/06.
This UART is not enabled by default and is only present on Raspberry Pi models 4 and up!
We do NOT enable the ctsrts
option as we don't want to run with hardware handshakes. We do however need to set/unset the DE/NRE
pins of the RS485 transceiver IC. How to do this differs based on the chose OS.
In /boot/config.txt
add:
dtoverlay=uart3
and reboot afterwards
After rebooting you should see the new serial port /dev/ttyAMA3
when executing ls /dev/tty*
For OpenPLC, if you followed the installation guide you should have installed my fork that includes DE/NRE
control via GPIO_6
so there should be nothing else for you to do
Further reading
https://raspberrypi.stackexchange.com/questions/104464/where-are-the-uarts-on-the-raspberry-pi-4
J3
1 | 2 | 3 | 4 |
---|---|---|---|
🟥 Q1 |
🟥 Q1 |
🟥 Q2 |
🟥 Q2 |
J4
1 | 2 | 3 | 4 |
---|---|---|---|
🟥 Q3 |
🟥 Q3 |
🟥 Q4 |
🟥 Q4 |
J5
1 | 2 | 3 | 4 |
---|---|---|---|
🟥 Q5 |
🟥 Q5 |
🟥 Q6 |
🟥 Q6 |
J6
1 | 2 | 3 | 4 |
---|---|---|---|
🟥 Q7 |
🟥 Q7 |
🟥 Q8 |
🟥 Q8 |
8 digital outputs are found at the pottom of the device. These outputs are driven by G5RL-1A-E-TV8
relays theoretically capable of 16 A at 250 V AC / 16 A at 24 V DC.
As with the digital inputs, each output features a status LED found on the HMI subboard.
Warning
As this the PiPLC is an open source passion project and not externally rated by TÜV or a similar agency, usage of these relays in mains powered systems is at your own risk.
All components chosen are rated for 16 A at 250 V AC and should be capable of driving everything in a home environment.
Only certified electricians should ever be performing mains work, and home-built devices should never be connected to mains power unless you know what you are doing.
1 | 2 | 3 | 4 |
---|---|---|---|
🟧 PWM 0 |
🟧 PWM 1 |
GND |
GND |
The PWM outputs are intentionally bare, unprotected GPIO connections of GPIO_18
for PWM 0
and GPIO_19
for PWM 1
so take care not to damage the Pi here.
If choosing to use the GPIO as inputs, bear in mind that the Pi's GPIO are only 3.3 V tolerant.
Choosing to actually use the PWM outputs, you have both hardware PWM's available to you here.
Warning
Unprotected access to GPIO_18
and GPIO_19
. Take care not to damage your Pi!
1 | 2 | 3 | 4 |
---|---|---|---|
+5 V |
GND |
🟦 I²C SDA |
🟦 I²C SCL |
Here you have a protected, somewhat isolated 5 V tolerant I²C header with integrated pullups. This was at first intended for connecting to extensions, but the Modbus header takes care of that now. You do have the option however, to attach whatever I²C device you want, provided the runtime you are using supports I²C communication.
Warning
The I²C contacts are already pulled up to 5 V so do not connect any 3.3 V only I²C devices directly without isolation!
Note
To enable I²C, go into /boot/config.txt
and uncomment dtparam=i2c_arm=on
, or alternatively enable I²C through sudo raspi-config
You might need to install i2c-tools
with sudo apt install i2c-tools
to test your I²C connections.
i2cdetect -y 1
should show the adresses of all found I²C devices afterwards
1 | 2 | 3 | 4 |
---|---|---|---|
+ 3.3 V |
GND |
🟦 1-Wire |
🟦 1-Wire |
This header contains GPIO_04
for native 1-Wire capability.
1-Wire is usually used for temperature sensors, like DS18B20
, or battery voltage sensing, but is sometimes also used for access control with iButtons.
Warning
Unprotected access to GPIO_04
. Take care not to damage your Pi!
Note
To enable 1-Wire, add the following to /boot/config.txt
:
dtoverlay=w1-gpio,gpiopin=23
reboot
You should be able to find any connected 1-Wire devices automatically with ls /sys/bus/w1/devices/
afterwards
J10
1 | 2 | 3 | 4 |
---|---|---|---|
+24 V |
+24 V |
+24 V |
+24 V |
J11
1 | 2 | 3 | 4 |
---|---|---|---|
🟨 I4 |
🟨 I3 |
🟨 I2 |
🟨 I1 |
J12
1 | 2 | 3 | 4 |
---|---|---|---|
🟨 I8 |
🟨 I7 |
🟨 I6 |
🟨 I5 |
8 digital inputs are found at the top of the device. These inputs are 5-24 V tolerant current sinking inputs through EL817C
optocouplers.
J10 features 24 V outputs to easily supply switches or other sensors feeding back into J11-J12 as inputs.
All inputs feature a status//Order is intentional to match the GPIO mapping table of PiPLC at https://github.com/chrismettal/piplc#gpio-mapping //while having all relays mapped "in order" from left to right LED driven by the optocoupler output, thus not loading the input.
On the Raspberry side, pullups need to be enabled on the GPIOs to enable reading from these input stages.
The inputs require 5mA of input current to reliably trigger at 24 V.
Utilizing knxd to run a NCN5121 KNX transceiver chip the PiPLC can talk to KNX networks natively, without going through an actual KNX-IP gateway first. (Internally, knxd looks like a KNX-IP gateway, but it won't route through your actual LAN)
For Home Assistant, there is an addon for knxd, so Home Assistant sees the internal NCN5121 as a KNX-IP gateway @ localhost.
See the knxd documentation for specifics on how to use the driver if you are not using Home Assistant.
In this board, the NC5121
is NOT supplied through the KNX supply, but through the Pi's 3v3
rail. This means that it doesn't need to be taken into account when calculating the KNX power supply needs.
Note
To enable KNX, make sure to disable bluetooth and the serial console on your Pi
This is required to enable full UART0
at GPIO14/15
In /boot/config.txt
add:
dtoverlay=pi3-disable-bt
In /boot/cmdline.txt
remove:
console=serial0,115200
or console=ttyAMA0,115200
if found
reboot
In your OS, /dev/ttyAMA0
can now be used as your KNX interface
A PCF8523
based realtime clock is present on the board so the PiPLC can keep track of time even when its 24 V input drops.
Note
To enable the real time clock on your Pi, add the following to /boot/config.txt
:
dtoverlay=i2c-rtc,pcf8523
And reboot afterwards.
Enabling RTC in the Pi and setting the time correctly is explained well in Adafruit's RTC guide.
This is the testing "schematic" used for all software examples. It demonstrates all interfaces present on-board and all testing of PiPLC was done in this configuration.
GPIO Name | PiPLC function | Device |
---|---|---|
GPIO_02 - 03 |
🟦 I²C | PCA9685 16 Ch. PWM servo driver |
GPIO_04 - 06 |
🟦 Modbus | EBYTE MA01-XACX0440 I/O Module |
GPIO_04 - 06 |
🟦 Modbus | ARCELI SHT20 Temp + Humidity probe |
GPIO_24 |
🟥 Q1 | 230 V Light |
GPIO_08 |
🟥 Q3 | Stacklight Green Channel |
GPIO_07 |
🟥 Q4 | Stacklight Yellow Channel |
GPIO_12 |
🟥 Q5 | Stacklight Red Channel |
GPIO_17 |
🟨 I1 | S0 Home power meter |
GPIO_27 |
🟨 I2 | Light switch |
GPIO_22 |
🟨 I3 | Emergency Stop NO |
GPIO_10 |
🟨 I4 | Emergency Stop NC |
GPIO_09 |
🟨 I5 | Toggle Switch left |
GPIO_11 |
🟨 I6 | Toggle Switch right |
GPIO_13 |
🟨 I7 | Green button |
GPIO_26 |
🟨 I8 | Red button |
GPIO_14 - 15 |
🟦 KNX | 4 Ch. Relay |
GPIO_18 |
🟧 PWM_0 | Dimmable LED |
GPIO_19 |
🟧 PWM_1 | Dimmable LED |
GPIO_23 |
🟦 1-Wire | DS18B20 Temperature probe |
USB | USB | Arduino Uno (OpenPLC Slave Firmware) |
RJ45 Jack | EtherCAT | TBD |
Wifi | LAN access | Android Tablet as HMI |
Wifi | LAN access | Programming device (Laptop) |
There is an example chinesium Modbus I/O module on the testing board with the following information:
Parameter | Value |
---|---|
Device Type | Generic Modbus RTU Device |
Slave ID | 32 |
COM Port | /dev/ttyAMA3 |
Baudrate | 9600 |
Parity | None |
Data bits | 8 |
Stop bits | 1 |
Transmission Pause | 0 |
Discrete Inputs | Address 0, Size 0 |
Coils | Address 0, Size 4 |
Input Registers | Address 0, Size 0 |
Holding Registers - Read | Address 0, Size 0 |
Holding Registers - Write | Address 0, Size 0 |
OpenPLC is a Fully IEC 61131-3
compliant, open source, multi-hardware programmable logic controller suite.
Consisting of a separate runtime and editor, it can run on regular PCs as a soft PLC, as well as a multitude of embedded systems. (Think Beckhoff XAR / XAE)
I am currently creating a hardware layer for PiPLC at https://github.com/Chrismettal/OpenPLC_v3. This should allow easy adressing of all IO while enabling native use of Modbus and other interfaces. The regular "Rpi" layer should also be compatible, but I²C, Modbus and KNX might not work, and I1-8 / Q1-8 adressing might be a bit unintuitive (See GPIO mapping table)
Click to expand
-
You are going to need a fresh installation of Raspberry Pi OS on your Pi 4. There is an official getting started guide that is being kept up to date, so the first steps are not further described here.
-
Execute
git clone https://github.com/chrismettal/OpenPLC_v3
on your Pi. This will clone a forked version of the OpenPLC runtime that contains some changes to make it compatible with PiPLC. Should these changes get merged, this link will be changed to point to the official version. -
cd OpenPLC_v3
to enter the just cloned folder -
./install rpi
will start the full OpenPLC installation. (This will take a few minutes) -
After a reboot, your OpenPLC installation's webinterface should be accessible on port 8080 on your Pi. Either try to access it at
127.0.0.1:8080
locally on your pi, or access it through your Pi's IP adress in your host computer. -
The default credentials will be
Name: openplc
,Password: openplc
. You might want to change these right after logging in for the first time. To do so, use the "Users" tab and edit the default "openplc" account:
- Head over to the "Hardware" tab to select the hardware layer. Select and save the "PiPLC" layer (Exact name might differ once merged upstream):
-
That should be it for a base installation. You should now have access to D1-8 and Q1-8 already, but you won't see Modbus RTU yet for slave devices. Instructions how to enable the Modbus COM port are found at J2 | Modbus.
-
After enabling UART3 as described above and rebooting your Pi, you should see
/dev/ttyAMA3
be available as a COM port for Modbus slaves:
- That's all there is to install the base OpenPLC install. There is currently no easy way to enable KNX or 1-Wire connectivity, and while I²C connectivity from OpenPLC is possible, it is currently not implemented in the hardware layer. All of these might be done in future within said hardware layer. See the usage example below for further information. Also see the OpenPLC getting started guide for general instructions on how to upload code to your OpenPLC instance
Check out /src/OpenPLC
!
Home Assistant is an open source smart-home automation software, that provides logic, visualization and automation in a single place. It allows you to connect practically everything to your home under one interface, awakening your smart home.
Home Assistant seems to move away from local hardware IO a bit, instead focussing on devices in your LAN / WiFi. That doesn't mean though, that it isn't fully capable of running on an actual PLC, giving you control of your devices without a middle man or WiFi shenanigans. This is where the NC5121
KNX interface comes into play, which enables you to talk to a vast variety of off-the-shelf decentralised ACTUAL smart home components (No supplier apps, no accounts, no telemetry) without needing to go through an KNX-IP interface first.
Click to expand
-
Follow the official first steps for a standard Home Assistant Raspberry Pi installation
-
Also follow the official onboarding steps to create your Home Assistant account and generally be able to use the system
-
Power down your Home Assistant install and take out the SD card
-
Install the SD card in a linux computer
-
Mount the first partition (Should be a 32MB one) temporarily to your system:
mkdir ~/TempMount
sudo mount -t vfat /dev/sdx1 ~/TempMount
-
In the now mounted
TempMount
directory, you will findConfig.txt
where we can set dtoverlays to enable additional serial ports etc. -
Follow both the KNX enabling guide as well as the Modbus enabling guide, adding their specific dtoverlays to
Config.txt
. This will make sure the Pi knows to enable the required UART connections there. -
You can now unmount the drive with
sudo umount ~/TempMount
and put the SD card back in your Pi before booting Home Assistant back up -
To enable KNX communication, you'll need to install the knxd addon.
-
Configure the
knxd
daemon as shown in the following picture. The/dev/ttyAMA0
interface makes sure we are talking to our on-boardNC5121
. Theoretically you could also use a KNX-USB interface if you weren't using the PiPLC board. Don't forget to start the daemon and set it to autostart.
- Once the
knxd
deamon is running install theKNX
integration:
-
During initial setup of the
KNX
integration, it should find your localknxd
daemon instance as a valid interface. -
To control / read your local GPIO, you'll want to install the following custom integration:
- To read 1-wire sensors through GPIO, you'll want to install the following custom integration:
TODO Upload example configuration.yaml
Codesys, like OpenPLC is a IEC 61131-3
compliant PLC runtime, compatible with PiPLC. It is not open source and the license for the RPI runtime costs about 55€. PiPLC was designed for OpenPLC but Codesys (as of 2024-01) is a much more robust runtime with more features.
As Codesys is proprietary, I won't be focussing much on it, but I want to make sure that most functions work well with PiPLC.
Click to expand
-
Setup your Pi with a fresh install of Pi OS. I only had luck using the "legacy" 32 Bit Debian Buster install and not the most recent (as of 2024-02) Debian Bookworm. (Wiringpi?)
-
Follow the Codesys Pi FAQ to install the runtime on your Pi as well as to get your engineering system set up
-
After enabling UART3 as described above and rebooting your Pi, you can set
/dev/ttyAMA3
to be your Modbus master port:
TODO Modbus port image TODO I²C port settings TODO 1-Wire port settings
Check out /src/CODESYS
!
# PiPLC
dtoverlay=uart3 # Enable UART3 for Modbus
dtoverlay=pi3-disable-bt # Disable Bluetooth so that UART0 is free for KNX
dtoverlay=w1-gpio,gpiopin=23 # Enable the 1-Wire pus on pin 23
dtoverlay=i2c-rtc,pcf8523 # Enable the I²C RTC
gpio=24,25,8,7,12,16,20,21=op,dl # Set all relay pins to outputs and turn them off
gpio=17,27,22,10,9,11,13,26=ip,pu # Set all digital input pins as pulled-up inputs
remove any mention of I²S or SPI if found, otherwise relay GPIOs might be driven HIGH on boot. Sometimes dtparam=spi=on
is set which will ruin your day so comment that one out if found.
remove console=serial0,115200
and/or console=ttyAMA0,115200
if found.
A full PiPLC consists of several subboards that need to be manufactured individually. Theoretically only the mainboard is technically required, as you could use wires to manually connect the Pi to the PLC as well as just not using the HMI as it is only a status display at the moment, but the existing 3D printable case assumes all boards to be used.
Only the main board has SMD parts that need to be assembled, so only one board will need to go through PCBA.
All boards are designed to be manufactured by JLCPCB, with BOMs using LCSC partnumbers attached. ALso all boards are to be manufactured with regular 1.6mm thickness, lead free HASL and 1oz copper weight.
This board houses all logic and is the only one that benefits from a PCBA service. All other boards plug into here, including the Raspberry Pi.
While not strictly required, this board houses frontpanel LEDs for status view of digital inputs and outputs, as well as 5V and 24V power status LEDs.
Additionally, the Wago header to plug into a KNX network is housed on this board.
Purely for decoration / labelling. No electrical connections here. Can theoretically be replaced by a sticker.
Riser board to give the Pi enough clearance to connect face-down to the mainboard. Can theoretically be replaced by a ribbon cable.
Riser board to connect the HMI board to the mainboard. Can theoretically be replaced by a ribbon cable
A 3D printable case is provided in /3d_printing
.
The case just snapfits together, after all boards were installed using M3x5mm screws.
Currently it will only fit a Raspberry Pi 4 and will not work with a Pi 5! You could modify the case to make a Pi 5 fit but I haven't done that yet.
The DIN-Rail mount on the back is not optimal yet so the compliant snap-action might now work, but since all boards I have manufactured are now deployed, I haven't yet gone around to updating the case.
The case is intended to be printed in a isolating and/or flame retardant filament like PC
or PETG VO
.
The following commands can be used to test your hardware configuration without installing PLC code or a full Home Assistant install. These are to be executed on a regular Pi OS install with raspi-gpio
installed.
- Enable pull ups on all input pins
raspi-gpio set 17,27,22,10,9,11,13,26 pu
- Set all output relay pins to be outputs
raspi-gpio set 24,25,8,7,12,16,20,21 op
- Read state of all input pins
raspi-gpio get 17,27,22,10,9,11,13,26
- Set individual relays HIGH/LOW (See GPIO mapping)
raspi-gpio set 24 dh
/ raspi-gpio set 24 dl
- Detect connected I²C devices (Should show found addresses in the grid if properly connected)
i2cdetect -y 1
- FreeCAD 0.21.2
- KicadStepUp Workbench 10.20.7
- KiCAD 7.0.9
- Wago 243-211 KNX Connector 3D file - https://grabcad.com/library/knx-connector-1
- Raspberry Pi 3D file - https://grabcad.com/library/raspberry-pi-4-model-b-1
- PCB Standoffs 3D files - https://grabcad.com/library/ettinger-standoff-nickel-plated-brass-m-f-m2-m8-1/details?folder_id=12725833
If you like my work please consider supporting me!
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.