phpoc_man
Published © GPL3+

Arduino-Powered I/O Modbus/TCP Device Server

Arduino-powered Modbus/TCP device server: 8 digital output relay, 8 digital input with photocoupler. It supports both WiFi and Ethernet.

BeginnerShowcase (no instructions)10,809
Arduino-Powered I/O Modbus/TCP Device Server

Things used in this project

Story

Read more

Schematics

hardware_N7VCY6OzFa.jpg

Code

ModbusTCPDeviceServer.ino

Arduino
#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");
	}
}

Credits

phpoc_man

phpoc_man

62 projects • 408 followers

Comments