emelianov / modbus-esp8266

Most complete Modbus library for Arduino. A library that allows your Arduino board to communicate via Modbus protocol, acting as a master, slave or both. Supports network transport (Modbus TCP) and Serial line/RS-485 (Modbus RTU). Supports Modbus TCP Security for ESP8266/ESP32.
Other
519 stars 186 forks source link

TCP/IP connection issue #298

Open SanPlatano opened 1 year ago

SanPlatano commented 1 year ago

Hi.

Ill try to make a bridge for RTU to TCP but when i use the modbus poll, to check the Modbus TCP, i cant connect with modbus TCP, only with UDP. And i really lost in the port selection, because the modbus poll need this in modbus tcp (or udp). The modbus poll in UDP, always says "timeout error"

`#ifdef ESP8266

include

else ESP32

include

endif

include

include

define tcp_preg 4

define tcp_flame 1

define tcp_rst 1

define rtu_preg 2

define rtu_flame 5

define rtu_rst 0

define ciclonik_slave 10

ModbusRTU mb; ModbusIP mbtcp;

bool cb(Modbus::ResultCode event, uint16_t transactionId, void* data) { // Callback to monitor errors if (event != Modbus::EX_SUCCESS) { Serial.print("Request result: 0x"); Serial.print(event, HEX); } return true; }

void setup() { Serial.begin(115200); pinMode(8,OUTPUT); Serial1.begin(19200,8E1,18,17); WiFi.begin("SSID", "PASS);

while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected");
Serial.println("IP address: "); Serial.println(WiFi.localIP());

mb.begin(&Serial1,8); mb.client(); mbtcp.server(); mbtcp.addHreg(tcp_preg); mbtcp.addIsts(tcp_flame); mbtcp.addCoil(tcp_rst); }

void loop() {

if (!mb.slave()) {

mb.pullHreg(ciclonik_slave, rtu_preg, tcp_preg); //(slave id, del registro, hacia el registro) mb.pullIsts(ciclonik_slave, rtu_flame, tcp_flame); mb.pullCoil(ciclonik_slave, rtu_rst, tcp_rst); }

mb.task(); mbtcp.task();

} `

rysiulg commented 1 year ago

I've make it to work -use example RTU to TCP -i had to made some modification to start working..., but i also want to make bridge work transparently and simultanopusly with program initiated read/write ;) To make bridge working you must catch raw and transmit it to RTU/TCP

examples/Bridge/TCP-to-RTU-Simulator/TCP-to-RTU-Simulator.ino (I've removed Stream parts as what i see it isn't used and after below mod it start worked -change mb_tcp to tcp ;)) emodbus library have bridge implemented and it is working, but i've missing there api like addhreg...

This is my changes to example: Modbus::ResultCode cbTcpRaw(uint8_t data, uint8_t len, void custom) { auto src = (Modbus::frame_arg_t*) custom; if (disable_MBTCP.state) { //this part check if bool diable_MBTCP.state is true than local transmition is active and return busy to tcp modbus sprintf(log_chars, PSTR("BUSY BUSY BUSY Bridge Ask from TCP IP: %s MB_ID: %d, Fn: %02X, len: %d"),IPAddress(src->ipaddr).toString(), slaveRunning, data[0], len); transRunning = 0; slaveRunning = 0; mb_tcp.setTransactionId(src->transactionId); // Set transaction id as per incoming request mb_tcp.errorResponce(src->ipaddr, (Modbus::FunctionCode)data[0], Modbus::EX_SLAVE_DEVICE_BUSY); mb_tcp.disconnect(MODBUS_TCP.eventSource()); log_message(log_chars); //send to logs Serial1 and webserial etc... return Modbus::EX_SLAVE_DEVICE_BUSY; }

if (transRunning) { // Note that we can't process new requests from TCP-side while waiting for responce from RTU-side. mb_tcp.setTransactionId(transRunning); // Set transaction id as per incoming request mb_tcp.errorResponce(src->ipaddr, (Modbus::FunctionCode)data[0], Modbus::EX_SLAVE_DEVICE_BUSY); return Modbus::EX_SLAVE_DEVICE_BUSY; } bool result_MB_RTU_trans = false; result_MB_RTU_trans = mb.rawRequest(src->slaveId, data, len, cbRtuTrans);

if (!result_MB_RTU_trans) { //i've added this to reset transrunning and slaverunning to 0 Serial.println("Wrong RTU response"); mb_tcp.setTransactionId(transRunning); // Set transaction id as per incoming request //Modbus::FunctionCode datatmp = data[0]; mb_tcp.errorResponce(src->ipaddr, (Modbus::FunctionCode)data[0], cbRtuTransEvent); mb_tcp.disconnect(mb_tcp.eventSource()); transRunning = 0; slaveRunning = 0; return cbRtuTransEvent; } if (transRunning) { mb_tcp.setTransactionId(transRunning); // Set transaction id as per incoming request

ifndef debugbridge

sprintf(log_chars,PSTR("ERR2 Bridge function src->unitId: %d and send error acknowledge. Trans: %d %d"),src->unitId, transRunning, src->transactionId);
log_message(log_chars);
#endif
//uint16_t succeed = tcp.rawResponce(src->ipaddr, data, len, slaveRunning);
mb_tcp.errorResponce(src->ipaddr, (Modbus::FunctionCode)data[0], Modbus::EX_ACKNOWLEDGE);
return Modbus::EX_ACKNOWLEDGE;

} transRunning = src->transactionId; slaveRunning = src->slaveId; srcIp = src->ipaddr; log_message((char*)PSTR("Bridge cbTCP_RAW Completed OK. transrunningi claverunning set...")); return Modbus::EX_SUCCESS;
}

Rest is the same as in example and it works in MODBUS TCP to MODBUS_RTU -all IDs ;)

Eduardo-bat commented 3 months ago

Hi, @rysiulg. Could you please explain how/where should disable_MBTCP and cbRtuTransEvent be declared and updated?