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.

I2C pins

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:

52pi 4 Channel Relay
Support NotEnoughTech
Buy 52pi P4Channel Relay Board
Control up to 16 deviecs via I2C interface

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:

52pi PowerBoard
Support NotEnoughTech
Buy 52pi PowerBoard
Control the power of the RPI with an IR remote and cool the CPU
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.util.Arrays;

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 -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

Exec It:./relay

Relays in action

Red Red Red and more Red

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).


This product has been provided to me for the purpose of the review. As usual, with all my reviews I reserve the right to an honest critique of the product.

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.

52pi 4 Channel Relay
Support NotEnoughTech
Buy 52pi P4Channel Relay Board
Control up to 16 deviecs via I2C interface
Ease of use