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
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:
- Docker Pi Power Board (review)
- 4 Channel Relay HAT
- ICE Tower Cooler (review)
- IoT Node (GPS, GSM, LoRa) (review soon)
- NightLigt HAT (review soon)
- UPS Pro 18650 board (review)
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
DEVICE_BUS = 1
DEVICE_ADDR = 0x10
bus = smbus.SMBus(DEVICE_BUS)
while True:
try:
for i in range(1,5):
bus.write_byte_data(DEVICE_ADDR, i, 0xFF)
t.sleep(1)
bus.write_byte_data(DEVICE_ADDR, i, 0x00)
t.sleep(1)
except KeyboardInterrupt as e:
print("Quit the Loop")
sys.exit()
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);
Thread.sleep(500);
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(;;){
for (i=1; i<=4; i++){
printf("turn on relay No.$d", i);
wiringPiI2CWriteReg8(fd, i, ON);
sleep(200);
printf("turn off relay No.$d", i);
wiringPiI2CWriteReg8(fd, i, OFF);
sleep(200);
}
}
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).
Conclusion
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.