Raspberry Pi and RS485 Relay Output Modules

The Raspberry Pi is finding it's way into more and more industrial applications. Most relay modules have either very few contacts available and/or are limited by the GPIO pins used.

By using a RS485 interface from the RPi like the Pi-SPi-RS485 and RS485 modules like the VP-EC-8KO interface that support the Modbus protocol, up to 253 modules at 8 relays per module giving a total of 2,024 relays from one interface is a possibility!

Raspberry Pi RS485 Interface Pi0SPi-RS485 and VP-EC-8KO Relay Module

There are limitations to the above example given.

1. The RS485 hardware protocol supports up to 32 "Unit Loads" before a repeater/amplifier must be used. The RS485 Drivers used in Pi-SPi-RS85 and VP-EC-8KO modules shown in the above picture use the Texas Instruments SN65HVD72DR half duplex IC which according to the TI data sheet allow for up to 200 unit loads.

2. The RS485 hardware protocol states that the maximum distance between the furthest ends of the RS485 transmission line cannot exceed 4000 feet, otherwise a repeater/amplifier must be used.

There are many resources available that explain the Modbus RTU protocol.

So, if your application requires some serious outputs (the VP-EC-8KO has 10 Amp SPDT contacts with MOV protection) and your distance is under 4000 feet between all modules and you need say a few hundred relays that are easily configured, the above solution is a perfect fit for you.

Another feature of the VP-EC-8KO that makes it field ready is the optional DIN rail enclosure that's available.

Here is a code sample done in "C" to drive the VP-EC-8KO relay module using an RPi 3. The code sample shown below uses the Modbus RTU Function "15" which is "Write Multiple Coils".

The MODBUS_ID RELAY is program set to be a number from 1 to 253, the dipswitch on the VP-EC-8KO is set (binary) to be the Modbus ID. The module also has a jumper selectble BAUD Rate of either 9600 or 19,200.

Finally, the variable Relay_Status is the byte that writes the 8 relay statuses. For example, Relay 1 and 3 ON and all others OFF, Relay_Status would = 0x05.

void VP_EC_8KO_Relay_Output(void) {
    unsigned char i, index;
    char tx_buffer[11];
    unsigned int checksum;
    //  Open Serial Port and Initialize
    //  fd = serialOpen("/dev/ttyAMA0", 19200);     // for RPi < 3
     fd = serialOpen("/dev/ttyS0", 19200);            // for RPi 3
     if(fd < 0)
        printf("Error opening Serial Port \nn");
    index = 0;   
    tx_buffer[index++] = MODBUS_ID_RELAY;    // MODBUS ID for slave relay module
    tx_buffer[index++] = 15;              // Function 15 = write multiple coils
    tx_buffer[index++] = 0;                // Start Address High Byte
    tx_buffer[index++] = 0;                // Start Address Low Byte
    tx_buffer[index++] = 0;                // Qty Coils High Byte
    tx_buffer[index++] = 8;                // Qty Coils Low Byte
    tx_buffer[index++] = 1;                // Byte Count
    tx_buffer[index++] = Relay_Status;   // Data Byte (8 Coils)   
    checksum = MB_crc16(tx_buffer,index);   
    // Checksum Low Byte, High Byte,    Sent Little Endian
    tx_buffer[index++] = (unsigned char)(checksum & 0x00ff);            
    tx_buffer[index++] = (unsigned char)((checksum >> 8) & 0x00ff);       
    digitalWrite(DIR_RS485, HIGH);                // Set RS485 to TX
    delay(5);                                    // Allow lines to settle

    for(i=0; i<index; i++) {
        serialPutchar(fd, tx_buffer[i]);
    delay(50);                                    // Allow last byte stop bit
    digitalWrite(DIR_RS485, LOW);                // Set RS485 to RX   


Leave a comment

Please note, comments must be approved before they are published