Click image for larger version

Name:	cover_img.png
Views:	523
Size:	863.4 KB
ID:	1565
Overview


Modbus/TCP is widely used in industrial.

We can make Modbus/TCP device using Arduino.

In my project, I make a devices that support:
  • 8 digital output port with Relay (NO/NC)
  • 8 digital input port with Photocoupler (Wet/Dry contact)
  • WiFi and Ethernet

The number of input and output port can be extended more because we can stack more Relay board and Input board on Arduino.

This device is equivalent to the commercial device, namely CIE-H10 Demonstration


In demonstration, I used a Modbus/TCP app on Ardroid, called Modmap.

We can use any kind of Modbus/TCP app or software on any platform to communicate with this devices



Modmap User Interface



Schematics

hardware_N7VCY6OzFa.jpg



Code
Code:
#include <Phpoc.h>
#include <PhpocExpansion.h>
#include <ArduinoModbus.h>

PhpocServer tcpServer(502);
ModbusTCPServer modbusTCPServer;
ExpansionPhotoInput inputs[8] = {
    ExpansionPhotoInput(1/*expansionId*/, 0),
    ExpansionPhotoInput(1/*expansionId*/, 1),
    ExpansionPhotoInput(1/*expansionId*/, 2),
    ExpansionPhotoInput(1/*expansionId*/, 3),
    ExpansionPhotoInput(2/*expansionId*/, 0),
    ExpansionPhotoInput(2/*expansionId*/, 1),
    ExpansionPhotoInput(2/*expansionId*/, 2),
    ExpansionPhotoInput(2/*expansionId*/, 3)
};
ExpansionRelayOutput outputs[8] = {
    ExpansionRelayOutput(3/*expansionId*/, 0),
    ExpansionRelayOutput(3/*expansionId*/, 1),
    ExpansionRelayOutput(3/*expansionId*/, 2),
    ExpansionRelayOutput(3/*expansionId*/, 3),
    ExpansionRelayOutput(4/*expansionId*/, 0),
    ExpansionRelayOutput(4/*expansionId*/, 1),
    ExpansionRelayOutput(4/*expansionId*/, 2),
    ExpansionRelayOutput(4/*expansionId*/, 3)
};

void setup() {
    Serial.begin(9600);
    while (!Serial)
        ;

    Serial.println("Modbus TCP Server LED");

    // initialize PHPoC [WiFi] Shield:
    Phpoc.begin(PF_LOG_SPI | PF_LOG_NET);
    Expansion.begin();

    // start the server
    tcpServer.begin();

    // start the Modbus TCP server
    if (!modbusTCPServer.begin()) {
        Serial.println("Failed to start Modbus TCP Server!");
        while (1);
    }

    // configure 8 coil start at address 0x08 for 8 output port
    modbusTCPServer.configureCoils(0x08, 8);
    // configure input and output holding registers
    modbusTCPServer.configureHoldingRegisters(0x00, 9);
}

void loop() {
    // listen for incoming clients
    PhpocClient client = tcpServer.available();

    if (client) {
        // a new client connected
        Serial.println("new client");

        // let the Modbus TCP accept the connection
        modbusTCPServer.accept(client);

        while (client.connected()) {
            // poll for Modbus TCP requests, while client connected
            modbusTCPServer.poll();

            /*---------DIGITAL OUTPUT PORT------------*/
            // 1. Read the control value from remote master and control 8 output ports
            for(int address = 0x08; address < 0x10; address++)
            {
                int outputCoinValue = modbusTCPServer.coilRead(address);

                if (outputCoinValue)
                    outputs[address - 0x08].on(); // Turn ON relay
                else
                    outputs[address - 0x08].off(); // Turn OFF relay
            }

            // 2. Read the read value of output ports and update current state
            uint16_t outputRegisterValue = 0;
            for(int address = 0x08; address < 0x10; address++)
            {
                uint16_t state = (int)outputs[address - 0x08].isOn();
                outputRegisterValue |= state << (address - 0x08);
            }

            modbusTCPServer.holdingRegisterWrite(0x08, outputRegisterValue);

            /*---------DIGITAL INPUT PORT------------*/
            // 1. Read the read value of input ports and update current state
            uint16_t inputRegisterValue = 0;
            for(int address = 0x00; address < 0x08; address++)
            {
                uint16_t state = (int)inputs[address].isOn();
                inputRegisterValue |= state << (address);
            }

            modbusTCPServer.holdingRegisterWrite(0x00, inputRegisterValue);
        }

        Serial.println("client disconnected");
    }
}