You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have a project where i am trying to connect multiple clients to one Modbus TCP server. However the current library does not support one server having multiple clients, So i tried to set multiple server up one for every clients. This seems to work well. It is not the cleanest code because i have to edit the registers of both servers when the data changes.
Is there a way to connect multiple client to one server?
I am using an STM32F303 on a NUCLEO-BOARD to test.
#include <SPI.h>
#include <Ethernet.h>
#include <ArduinoModbus.h>
#include <Adafruit_MAX31865.h>
// Use software SPI: CS, DI, DO, CLK
Adafruit_MAX31865 thermo = Adafruit_MAX31865(6, A0, A1, A3);
// The value of the Rref resistor. Use 430.0 for PT100 and 4300.0 for PT1000
#define RREF 400.0
// The 'nominal' 0-degrees-C resistance of the sensor
// 100.0 for PT100, 1000.0 for PT1000
#define RNOMINAL 100.0
byte mac[] = {
0x80, 0x20, 0xE1, 0xEF, 0xFE, 0xED};
// Default to use W5100. Must change to false for W5500, W5100S, for faster SPI clock
#define USE_W5100 false
/**
* @brief The pins used for the pulse interrupts.
*/
const int interruptPin1 = 0;
const int interruptPin2 = 1;
const int interruptPin3 = 9;
const int interruptPin4 = 4;
const int interruptPin5 = 5;
const int interruptPin6 = A2;
const int interruptPin7 = 7;
const int interruptPin8 = 8;
uint16_t interruptNumber = 0;
unsigned long previousTime = micros();
uint16_t interruptNumber1 = 0;
uint16_t interruptNumber2 = 0;
uint16_t interruptNumber3 = 0;
uint16_t interruptNumber4 = 0;
uint16_t interruptNumber5 = 0;
uint16_t interruptNumber6 = 0;
uint16_t interruptNumber7 = 0;
uint16_t interruptNumber8 = 0;
unsigned long previousTime1 = 0;
unsigned long previousTime2 = 0;
unsigned long previousTime3 = 0;
unsigned long previousTime4 = 0;
unsigned long previousTime5 = 0;
unsigned long previousTime6 = 0;
unsigned long previousTime7 = 0;
unsigned long previousTime8 = 0;
EthernetServer ethServer(502);
ModbusTCPServer modbusTCPServer;
ModbusTCPServer modbusTCPServer1;
EthernetClient client1;
bool client1_connected = false;
EthernetClient client2;
bool client2_connected = false;
/**
* @brief The maximum number of Modbus TCP clients.
*/
#define MAX_MB_CLIENTS 2
/**
* @brief This structure represents a Modbus client.
*/
struct DbmaticClient
{
EthernetClient client = NULL;
/**
* @brief The modbus TCP server instance for this client.
*/
ModbusTCPServer mbServer;
/**
* @brief True when the client is connected, false if not.
*/
bool connected = false;
int slaveId = 0;
};
void setup()
{
Serial.begin(115200);
Ethernet.init(10);
Serial.println("Initialize Ethernet with DHCP:");
if (Ethernet.begin(mac) == 0)
{
Serial.println("Failed to configure Ethernet using DHCP");
bool isW5500 = (Ethernet.hardwareStatus() == EthernetW5500);
Serial.print(F("Ethernet type is "));
Serial.println(isW5500 ? F("W5500") : F("W5100"));
if (Ethernet.hardwareStatus() == EthernetNoHardware)
{
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
}
else if (Ethernet.linkStatus() == LinkOFF)
{
Serial.println("Ethernet cable is not connected.");
}
}
Serial.print("My IP address: ");
Serial.println(Ethernet.localIP());
ethServer.begin();
pinMode(interruptPin1, INPUT_PULLUP);
pinMode(interruptPin2, INPUT_PULLUP);
pinMode(interruptPin3, INPUT_PULLUP);
pinMode(interruptPin4, INPUT_PULLUP);
pinMode(interruptPin5, INPUT_PULLUP);
pinMode(A2, INPUT_PULLUP);
pinMode(interruptPin7, INPUT_PULLUP);
pinMode(interruptPin8, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin1), interrupt1Callback, FALLING);
attachInterrupt(digitalPinToInterrupt(interruptPin2), interrupt2Callback, FALLING);
attachInterrupt(digitalPinToInterrupt(interruptPin3), interrupt3Callback, FALLING);
attachInterrupt(digitalPinToInterrupt(interruptPin4), interrupt4Callback, FALLING);
attachInterrupt(digitalPinToInterrupt(interruptPin5), interrupt5Callback, FALLING);
attachInterrupt(digitalPinToInterrupt(A2), interrupt6Callback, FALLING);
attachInterrupt(digitalPinToInterrupt(interruptPin7), interrupt7Callback, FALLING);
attachInterrupt(digitalPinToInterrupt(interruptPin8), interrupt8Callback, FALLING);
// start the Modbus TCP server
if (!modbusTCPServer.begin(1))
{
Serial.println("Failed to start Modbus TCP Server!");
while (1)
;
}
modbusTCPServer.configureHoldingRegisters(0x00, 100);
Serial.println("Start Modbus TCP Server!");
delay(1000);
if (!modbusTCPServer1.begin(2))
{
Serial.println("Failed to start Modbus TCP Server!");
while (1)
;
}
modbusTCPServer1.configureHoldingRegisters(0x00, 100);
Serial.println("Start Modbus TCP Server 1!");
// for(int i = 0; i < MAX_MB_CLIENTS; ++i) {
// setupDbmaticClient(mbClient + i, i);
// }
thermo.begin(MAX31865_2WIRE);
Serial.println("Boot complete");
}
void handle_connect()
{
EthernetClient client = ethServer.accept();
if(client) {
if(!client1_connected) {
Serial.println("Connecting client 1");
client1 = client;
client1_connected = true;
Serial.print("the connected client1 state: ");
Serial.println(client1.connected());
modbusTCPServer.accept(client1);
Serial.println(client1.connected());
return;
} else if (!client2_connected) {
Serial.println("Connecting client 2");
client2 = client;
client2_connected = true;
Serial.print("the connected client2 state: ");
Serial.println(client2.connected());
modbusTCPServer1.accept(client2);
Serial.println(client2.connected());
return;
}
client.stop();
Serial.println("Closed new client because al connection slots are in use");
}
}
void handle_modbus()
{
if(client1.connected()){
modbusTCPServer.poll();
}
if(client2.connected()){
Serial.println("Polling for client 2");
modbusTCPServer1.poll();
}
if(!client1.connected() && client1_connected){
client1_connected = false;
Serial.println("Client 1 closing the connection");
client1.stop();
}
if(!client2.connected() && client2_connected){
client2_connected = false;
Serial.println("Client 2 closing the connection");
client2.stop();
}
}
unsigned long last_temp_reading = 0;
void handle_temp()
{
if (millis() - last_temp_reading <= 1000)
{
return;
}
uint16_t rtd = thermo.readRTD();
float ratio = rtd;
ratio /= 32768;
// Serial.print("Temperature = ");
// Serial.println(thermo.temperature(RNOMINAL, RREF));
// Check and print any faults
uint8_t fault = thermo.readFault();
if (fault)
{
Serial.print("Fault 0x");
Serial.println(fault, HEX);
if (fault & MAX31865_FAULT_HIGHTHRESH)
{
Serial.println("RTD High Threshold");
}
if (fault & MAX31865_FAULT_LOWTHRESH)
{
Serial.println("RTD Low Threshold");
}
if (fault & MAX31865_FAULT_REFINLOW)
{
Serial.println("REFIN- > 0.85 x Bias");
}
if (fault & MAX31865_FAULT_REFINHIGH)
{
Serial.println("REFIN- < 0.85 x Bias - FORCE- open");
}
if (fault & MAX31865_FAULT_RTDINLOW)
{
Serial.println("RTDIN- < 0.85 x Bias - FORCE- open");
}
if (fault & MAX31865_FAULT_OVUV)
{
Serial.println("Under/Over voltage");
}
thermo.clearFault();
}
last_temp_reading = millis();
}
void loop()
{
handle_connect();
handle_modbus();
handle_temp();
}
void interrupt1Callback()
{
interruptNumber1++;
modbusTCPServer.holdingRegisterWrite(0x00, interruptNumber1);
unsigned long currentTime = micros();
int pulseTime = int((currentTime - previousTime1) / 10);
previousTime1 = currentTime;
modbusTCPServer.holdingRegisterWrite(0x20, int(pulseTime / 100));
modbusTCPServer.holdingRegisterWrite(0x21, pulseTime & 0xFFFF);
modbusTCPServer1.holdingRegisterWrite(0x20, int(pulseTime / 100));
modbusTCPServer1.holdingRegisterWrite(0x21, pulseTime & 0xFFFF);
}
void interrupt2Callback()
{
interruptNumber2++;
modbusTCPServer.holdingRegisterWrite(0x01, interruptNumber2);
unsigned long currentTime = micros();
int pulseTime = int((currentTime - previousTime2) / 10);
previousTime2 = currentTime;
modbusTCPServer.holdingRegisterWrite(0x22, int(pulseTime / 100));
modbusTCPServer.holdingRegisterWrite(0x23, pulseTime & 0xFFFF);
modbusTCPServer1.holdingRegisterWrite(0x22, int(pulseTime / 100));
modbusTCPServer1.holdingRegisterWrite(0x23, pulseTime & 0xFFFF);
}
void interrupt3Callback()
{
interruptNumber3++;
modbusTCPServer.holdingRegisterWrite(0x02, interruptNumber3);
unsigned long currentTime = micros();
int pulseTime = int((currentTime - previousTime3) / 10);
previousTime3 = currentTime;
modbusTCPServer.holdingRegisterWrite(0x24, int(pulseTime / 100));
modbusTCPServer.holdingRegisterWrite(0x25, pulseTime & 0xFFFF);
modbusTCPServer1.holdingRegisterWrite(0x24, int(pulseTime / 100));
modbusTCPServer1.holdingRegisterWrite(0x25, pulseTime & 0xFFFF);
}
void interrupt4Callback()
{
interruptNumber4++;
modbusTCPServer.holdingRegisterWrite(0x03, interruptNumber4);
unsigned long currentTime = micros();
int pulseTime = int((currentTime - previousTime4) / 10);
previousTime4 = currentTime;
modbusTCPServer.holdingRegisterWrite(0x26, int(pulseTime / 100));
modbusTCPServer.holdingRegisterWrite(0x27, pulseTime & 0xFFFF);
modbusTCPServer1.holdingRegisterWrite(0x26, int(pulseTime / 100));
modbusTCPServer1.holdingRegisterWrite(0x27, pulseTime & 0xFFFF);
}
void interrupt5Callback()
{
interruptNumber5++;
modbusTCPServer.holdingRegisterWrite(0x04, interruptNumber5);
unsigned long currentTime = micros();
int pulseTime = int((currentTime - previousTime5) / 10);
previousTime5 = currentTime;
modbusTCPServer.holdingRegisterWrite(0x28, int(pulseTime / 100));
modbusTCPServer.holdingRegisterWrite(0x29, pulseTime & 0xFFFF);
modbusTCPServer1.holdingRegisterWrite(0x28, int(pulseTime / 100));
modbusTCPServer1.holdingRegisterWrite(0x29, pulseTime & 0xFFFF);
}
void interrupt6Callback()
{
interruptNumber6++;
modbusTCPServer.holdingRegisterWrite(0x05, interruptNumber6);
unsigned long currentTime = micros();
int pulseTime = int((currentTime - previousTime6) / 10);
previousTime6 = currentTime;
modbusTCPServer.holdingRegisterWrite(0x2A, int(pulseTime / 100));
modbusTCPServer.holdingRegisterWrite(0x2B, pulseTime & 0xFFFF);
modbusTCPServer1.holdingRegisterWrite(0x2A, int(pulseTime / 100));
modbusTCPServer1.holdingRegisterWrite(0x2B, pulseTime & 0xFFFF);
}
void interrupt7Callback()
{
interruptNumber7++;
modbusTCPServer.holdingRegisterWrite(0x06, interruptNumber7);
unsigned long currentTime = micros();
int pulseTime = int((currentTime - previousTime7) / 10);
previousTime7 = currentTime;
modbusTCPServer.holdingRegisterWrite(0x2C, int(pulseTime / 100));
modbusTCPServer.holdingRegisterWrite(0x2D, pulseTime & 0xFFFF);
modbusTCPServer1.holdingRegisterWrite(0x2C, int(pulseTime / 100));
modbusTCPServer1.holdingRegisterWrite(0x2D, pulseTime & 0xFFFF);
}
void interrupt8Callback()
{
interruptNumber8++;
modbusTCPServer.holdingRegisterWrite(0x07, interruptNumber8);
unsigned long currentTime = micros();
int pulseTime = int((currentTime - previousTime8) / 10);
previousTime8 = currentTime;
modbusTCPServer.holdingRegisterWrite(0x2E, int(pulseTime / 100));
modbusTCPServer.holdingRegisterWrite(0x2F, pulseTime & 0xFFFF);
}
The text was updated successfully, but these errors were encountered:
DriesVandb
changed the title
Multiple clients to one modbus TCP server on stm32
Multiple clients to one modbus TCP server
Apr 13, 2023
I have a project where i am trying to connect multiple clients to one Modbus TCP server. However the current library does not support one server having multiple clients, So i tried to set multiple server up one for every clients. This seems to work well. It is not the cleanest code because i have to edit the registers of both servers when the data changes.
Is there a way to connect multiple client to one server?
I am using an STM32F303 on a NUCLEO-BOARD to test.
The text was updated successfully, but these errors were encountered: