HomeRaspberry PiToggling lights with DockerPi 4 Channel Relay

Toggling lights with DockerPi 4 Channel Relay

Add relays to your Raspberry Pi

What will happen if you add I2C to four relays and mix it up in a Raspberry Pi HAT form factor? You will ger a DockerPi 4 Channel Relay HAT. What’s the relay array good for? To toggle things on and off! Let’s take a closer look at this expansion board.

DockerPi 4 Channel Relay HAT

A thing of relay beauty

The DockerPi 4 Channel Relay comes with 4 relays rated for 250VAC/30VDC and 3A each. It’s not a mind-blowing power rating, but you should be able to toggle lights and devices up to 750W. As usual, you have the option to wire the relay in NO|NC configuration.

The DockerPi 4 Channel Relay HAT latches to Raspberry Pi’s GPIO and utilises pins 3, 5 to connect the relays via an I2C interface (you can implement the I2C bus on any pair of pins software-wise). Thanks to onboard toggles, you can assign 4 different addresses to each HAT to stack it up to 4 stacks tall (16 relays in total). That’s are a decent use of 2 pins!

Each relay comes with an LED showing the operational status, and the board comes with a 4-pin DockerPi power header, which transfers 12V if the DockerPi Power Board is used.

52pi offers a series of cross-compatible hats that you can put on your Raspberry Pi devices. I got my hands on the on a couple of them:

Buy 52pi 4 Channel Relay HAT

Buy it using these links to support NotEnoughTech.

Getting Raspberry Pi ready

Before you start using the I2C, head to: sudo raspi-config and enable I2C in interfaces menu. Also on Rasbian “lite” builds you will need to instal the driver too:

sudo apt-get install i2c-tools

You can control the relays using i2c-tools directly from the bash. To compose the command you will need to check the device address set by the DockerPi 4 Channel Relay toggles.

i2cset -y 1 0x10 0x01 0xFF

  • 0x10|0x11|0x12|0x13 – device address (individual to each board if stacked)
  • 0x01|0x02|0x03|0x04 -relay address
  • 0x00|0xFF – state ON|OFF

So if you want to toggle the 3rd relay on the boars with device map 0x11 you have to use:

 i2cset -y 1 0x11 0x03 0xFF 

Bear in mind your actual toggle command with also depend on the NO|NC configuration.

  • NO – Relay is Open (is not passing current when powered down)
  • NC – Relay is Closed (is passing current when powered down)

The 52pi Wiki page provides the instructions on how to use the DockerPi 4 Channel Relay with Python, Java and C, but you can also use I2C nodes in NodeRED:

import time as t
import smbus
import sys

bus = smbus.SMBus(DEVICE_BUS)

while True:
        for i in range(1,5):
            bus.write_byte_data(DEVICE_ADDR, i, 0xFF)
            bus.write_byte_data(DEVICE_ADDR, i, 0x00)
    except KeyboardInterrupt as e:
        print("Quit the Loop")
import java.io.IOException;
import java.util.Arrays;

import com.pi4j.io.i2c.I2CBus;
import com.pi4j.io.i2c.I2CDevice;
import com.pi4j.io.i2c.I2CFactory;
import com.pi4j.io.i2c.I2CFactory.UnsupportedBusNumberException;
import com.pi4j.platform.PlatformAlreadyAssignedException;
import com.pi4j.util.Console;

public class I2CRelay {

    // relay's register address.
    public static final int DOCKER_PI_RELAY_ADDR = 0x10; 

    // channel of relay.
    public static final byte DOCKER_PI_RELAY_1 = (byte)0x01;
    public static final byte DOCKER_PI_RELAY_2 = (byte)0x02;
    public static final byte DOCKER_PI_RELAY_3 = (byte)0x03;
    public static final byte DOCKER_PI_RELAY_4 = (byte)0x04;

    // Relay status
    public static final byte DOCKER_PI_RELAY_ON = (byte)0xFF;
    public static final byte DOCKER_PI_RELAY_OFF = (byte)0x00;

    public static void main(String[] args) throws InterruptedException, 
PlatformAlreadyAssignedException, IOException, UnsupportedBusNumberException {

        final Console console = new Console();

        I2CBus i2c = I2CFactory.getInstance(I2CBus.BUS_1);
        I2CDevice device = i2c.getDevice(DOCKER_PI_RELAY_ADDR);

        console.println("Turn on Relay!");
        device.write(DOCKER_PI_RELAY_1, DOCKER_PI_RELAY_ON);


        console.println("Turn off Relay!");
        device.write(DOCKER_PI_RELAY_1, DOCKER_PI_RELAY_OFF);

Compile it: javac I2CRelay.java -classpath .:classes:/opt/pi4j/lib/'*'

and run: sudo java -classpath .:classes:/opt/pi4j/lib/'*' I2CRelay

#include <stdio.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>

#define DEVCIE_ADDR  0x10
#define RELAY1  0x01
#define RELAY2  0x02
#define RELAY3  0x03
#define RELAY4  0x04
#define ON      0xFF
#define OFF     0x00

int main(void){
    printf("Turn on Relays in C\n");
    int fd;
    int i = 0;
    fd = wiringPiI2CSetup(DEVICE_ADDR);
       for (i=1; i<=4; i++){
          printf("turn on relay No.$d", i);
          wiringPiI2CWriteReg8(fd, i, ON);
          printf("turn off relay No.$d", i);
          wiringPiI2CWriteReg8(fd, i, OFF);
    return 0;

Compile! gcc relay.c -lwiringPi -o relay

Relays in action

I hooked up four 12V LED bulbs to my power supply. Then in my configuration. I used NC and COM pins for testing as I wanted to observe the behaviours of the board while the Raspberry Pi is switched off and disconnected from power.

DockerPi 4 Channel Relay HAT will remember your configuration even if the Raspberry Pi is turned off and retain the relay state. As soon as the power supply is disconnected, the HAT will revert back to NO|NC behaviour (based on the way you have connected your devices).

Buy 52pi 4 Channel Relay HAT

Buy it using these links to support NotEnoughTech.


DockerPi 4 Channel Relay HAT is well designed. It lacks the relays that could operate more power-hungry devices, but I don’t think I would feel comfortable connecting a washing machine or another current monster directly to the Raspberry Pi. It’s nice to see the stacking interface, and 16 relays should be more than plenty for your home automation! Let me know what do you think about the DockerPi 4 Channel Relay in this Reddit thread.


Nothing says "Thank you" better than keeping my coffee jar topped up!


Support me on Patreon and get an early access to tutorial files and videos.


Bitcoin (BTC)

Use this QR to keep me caffeinated with BTC: 1FwFqqh71mUTENcRe9q4s9AWFgoc8BA9ZU


Programable, ESP32 based awesome dev platform with 4.7 e-ink display by M5Stack

More HATs


Argon One M.2

Enclose Raspberry Pi 4 inside this great case with custom I/O, cooling and GPIO and M.2 SSD support

More cases on


Best Raspberry Pi Projects

How to use Raspberry PI as WOL (wake on lan) server

While you could wake up your PC from a mobile directly, having a dedicated server capable of doing so is the best solution. The reason is simple. You can hook up as many devices as you wish with a single endpoint. This is why Raspberry Pi is perfect for this.

Slow Internet Warning

From time to time my Internet grinds to a stop. Since Raspberry Pi 4 comes with a 1Gbps Ethernet, I decided to take advantage of it and create a reporting system in NodeRED that will monitor and report when the ISP is not keeping the contractual agreements. Works with Alexa, Google Home, Android and Windows 10.

How fast Raspberry Pi NAS is?

Let's see how fast Raspberry Pi NAS really is?

Argon18: Argon ONE SSD modification

Argon One case just got better - now you can boot it from USB without ruining the design thanks to Argon 18: Argon One SSD modification


It took me 2 months to boot CM4 from NVMe

Complete beginners guide to Compute Module 4 boot from NVMe.

Raspberry Pi Zero 2 W vs other Zero boards

It's time to test the Raspberry Pi Zero 2 W against other Raspberry Pi boards from Zero series: power, WiFi, temperature and core performance

C/C++ and MicroPython SDK for Raspberry Pi Pico on Windows

A guide to SDK toolchain for Raspberry Pi Pico and C/C++ , Micropython on Windows.

A comprehensive guide to Grafana & InfluxDB

How to use Grafana and InfluxDB on Raspberry Pi for IoT sensors in home automation

How to boot Raspberry Pi 4 from USB

How to set up and boot Raspberry Pi 4 from USB drive - headless guide.