0

I have a SAMD51P20 based Arduino PLC with WIZnet W5500 based Ethernet shield. I'm using these libraries:

#include <Ethernet.h>
#include <MQTT.h>
#include <ArduinoModbus.h>

MQTT and Modbus-TCP clients run fine individually, but running them at the same time creates problems with both of them.

Is there a software solution to this problem, e.g. using separate sockets for MQTT and Modbus-TCP. WIZnet W5500 has 8 sockets available, but I don't see an API to select a socket for MQTT and Modbus-TCP client.

If not software, is there a hardware solution?


Here is the code snippet:

#include <fmt.h>
#include <P1AM.h>
#include <Ethernet.h>
#include <MQTT.h>
#include <ArduinoModbus.h>
using namespace std;
#define HOST_NAME "WIZnet"
uint8_t macPLC[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
uint8_t ipPLC[] = {192, 168, 0, 41}; 
uint8_t ipModbus[] = {192, 168, 0, 43}; 
char ipMQTT[] = "192.168.0.42";
int unitID = 98;
EthernetClient ethernet;
MQTTClient mqtt;
ModbusTCPClient modbus(ethernet);
int n = 0;
void messageReceived(MQTTClient *client, char topic[], char bytes[], int length) {
 if (length == 8) {
 int32_t commandID;
 float commandArg;
 memcpy(&commandID, &bytes[0], sizeof(commandID));
 memcpy(&commandArg, &bytes[4], sizeof(commandArg));
 Serial.println(fmt::format("{} {}", commandID, commandArg).c_str());
 }
 else
 Serial.println("wrong length!!!");
}
void servoSetup() {
 modbus.coilWrite(unitID, 0x00C, 1);
}
void setup(){ // the setup routine runs once:
 P1.configWD(10000, 1);
 P1.startWD();
 Serial.begin(115200); //initialize serial communication at 115200 bits per second 
 while (!P1.init()) 
 delay(1); //Wait for Modules to Sign on 
 
 Ethernet.begin(macPLC, ipPLC);
 mqtt.begin(ipMQTT, ethernet);
 modbus.setTimeout(500);
 if (!modbus.begin(ipModbus, 502)) 
 Serial.println("Failed to start Modbus TCP client!");
 else
 Serial.println("Connected to Modbus TCP client.");
 P1.petWD();
 while (!mqtt.connect(ipMQTT)) {
 Serial.print(".");
 delay(1000);
 }
 Serial.println("\nConnected to MQTT broker.");
 mqtt.subscribe("plc", 2);
 mqtt.onMessageAdvanced(messageReceived);
 servoSetup();
 delay(2000);
}
void loop() {
 P1.petWD();
 Serial.println(mqtt.loop());
 Serial.println(n++);
 int addr = 0x2407;
 if (!modbus.holdingRegisterWrite(unitID, addr, n)) 
 Serial.println(fmt::format("Modbus write failed: {}", modbus.lastError()).c_str());
 delay(1000);
 if (auto result = modbus.holdingRegisterRead(unitID, addr); result < 0) 
 Serial.println(fmt::format("Modbus read failed: {}", modbus.lastError()).c_str());
 else
 Serial.println(fmt::format("holdingRegisterRead: {}", result).c_str());
 delay(1000);
}

In this case, Modbus-TCP writes and reads have no effect, mqtt.loop() returns 0 and messageReceived() callback is not called. If I comment out MQTT or Modbus-TCP client, the code behaves as expected.

asked Jun 25, 2024 at 7:32
4
  • What kind of problem? The 3-line of code doesn't tell us anything. You need to elaborate more on how you create the client for each connection? Commented Jun 25, 2024 at 7:37
  • @hcheung I posted the full test code. Commented Jun 25, 2024 at 8:26
  • 1
    ModbusTCPClient modbus(ethernet); and mqtt.begin(ipMQTT, ethernet);, you are sharing the same Ethernet client for two services. Create a separate client instance for each service. Commented Jun 25, 2024 at 8:33
  • @hcheung Thank you for looking into it. Commented Jun 25, 2024 at 9:17

1 Answer 1

1

There is no API to set the count of sockets used in the Ethernet library.

The MAX_SOCK_NUM is set in Ethernet.h based on available RAM.

#if defined(RAMEND) && defined(RAMSTART) && ((RAMEND - RAMSTART) <= 2048)
#define MAX_SOCK_NUM 4
#else
#define MAX_SOCK_NUM 8
#endif

So on SAMD51 you have 8 sockets available. Your problem with MQTT and Modbus TCP is elsewhere.

btw. the W5100 can handle only 4 sockets, but that is constrained at runtime.


EDIT: In your sketch you use the same EthernetClient for both libraries. Use two separate EthernetClient objects.

EthernetClient ethernet;
EthernetClient modbusClient;
MQTTClient mqtt;
ModbusTCPClient modbus(modbusClient);
answered Jun 25, 2024 at 8:00
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.