Skip to content

Commit

Permalink
ModbusTCP to ModbusRTU example added
Browse files Browse the repository at this point in the history
  • Loading branch information
emelianov committed Apr 10, 2022
1 parent 861f0d9 commit b7aeef0
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 5 deletions.
17 changes: 13 additions & 4 deletions examples/Bridge/README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
# Bridge functions

## Basic
## [Basic](basic/basic.ino)

Basic 'Bridge'. Indeed this sample pulling data from Modbus Server and stores it to local registers. Local registers can be accessed via Modbus Client instance that running aside.

## True
## [ModbusRTU to ModbusTCP bridge](true/true.ino)

Fullfunctional ModbusRTU to ModbusTCP bridge.

## MultipeServerID
## [Multiple Server ID](MultipeServerID/MultipeServerID.ino)

Respond for multiple ModbusRTU IDs from single device

## [ModbusTCP to Modbus RTU Simulator](TCP-to-RTU-Simulator/TCP-to-RTU-Simulator.ino)

Fullfunctional ModbusTCP to ModbusRTU bridge with on-device ModbusRTU simulator

```c
uint16_t rawRequest(id_ip, uint8_t* data, uint16_t len, cbTransaction cb = nullptr, uint8_t unit = MODBUSIP_UNIT);
uint16_t rawResponce(id_ip, uint8_t* data, uint16_t len, uint8_t unit = MODBUSIP_UNIT);
Expand All @@ -22,7 +26,12 @@ uint16_t errorResponce(id_ip, Modbus::FunctionCode fn, Modbus::ResultCode excode
- `len` Byte count to send
- `unit` UnitId (ModbusTCP/TLS only)
- `fn` function code in responce
- `excode` Exceprion code in responce
- `excode` Exception code in responce
```c
uint16_t setTransactionId(uint16_t id);
```
- `id` Value to replace transaction id sequence (ModbusTCP/TLS only)

```c
union frame_arg_t {
Expand Down
134 changes: 134 additions & 0 deletions examples/Bridge/TCP-to-RTU-Simulator/TCP-to-RTU-Simulator.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/*
ModbusRTU ESP8266/ESP32
ModbusTCP to ModbusRTU bridge with on-device ModbusRTU simulator
*/
#ifdef ESP8266
#include <ESP8266WiFi.h>
#else //ESP32
#include <WiFi.h>
#endif
#include <ModbusTCP.h>
#include <ModbusRTU.h>
//#include <SoftwareSerial.h>
//SoftwareSerial S(13, 15);
#include <StreamBuf.h>
#define BSIZE 1024
uint8_t buf1[BSIZE];
uint8_t buf2[BSIZE];
StreamBuf S1(buf1, BSIZE);
StreamBuf S2(buf2, BSIZE);
DuplexBuf P1(&S1, &S2);
DuplexBuf P2(&S2, &S1);
ModbusRTU sym;

int DE_RE = 2;

ModbusRTU rtu;
ModbusTCP tcp;

IPAddress srcIp;


uint16_t transRunning = 0; // Currently executed ModbusTCP transaction
uint8_t slaveRunning = 0; // Current request slave

bool cbTcpTrans(Modbus::ResultCode event, uint16_t transactionId, void* data) { // Modbus Transaction callback
if (event != Modbus::EX_SUCCESS) // If transaction got an error
Serial.printf("Modbus result: %02X, Mem: %d\n", event, ESP.getFreeHeap()); // Display Modbus error code (222527)
if (event == Modbus::EX_TIMEOUT) { // If Transaction timeout took place
tcp.disconnect(tcp.eventSource()); // Close connection
}
return true;
}

bool cbRtuTrans(Modbus::ResultCode event, uint16_t transactionId, void* data) {
if (event != Modbus::EX_SUCCESS) // If transaction got an error
Serial.printf("Modbus result: %02X, Mem: %d\n", event, ESP.getFreeHeap()); // Display Modbus error code (222527)
return true;
}


// Callback receives raw data
Modbus::ResultCode cbTcpRaw(uint8_t* data, uint8_t len, void* custom) {
auto src = (Modbus::frame_arg_t*) custom;

Serial.print("TCP IP: ");
Serial.print(IPAddress(src->ipaddr));
Serial.printf(" Fn: %02X, len: %d \n\r", data[0], len);

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

rtu.rawRequest(slaveRunning, data, len, cbRtuTrans);

if (src->unitId) {
tcp.setTransactionId(transRunning); // Set transaction id as per incoming request

//uint16_t succeed = tcp.rawResponce(src->ipaddr, data, len, slaveRunning);

tcp.errorResponce(src->ipaddr, (Modbus::FunctionCode)data[0], Modbus::EX_ACKNOWLEDGE);
return Modbus::EX_ACKNOWLEDGE;
}

srcIp = src->ipaddr;

slaveRunning = src->slaveId;

transRunning = src->transactionId;

return Modbus::EX_SUCCESS;

}


// Callback receives raw data from ModbusTCP and sends it on behalf of slave (slaveRunning) to master
Modbus::ResultCode cbRtuRaw(uint8_t* data, uint8_t len, void* custom) {
auto src = (Modbus::frame_arg_t*) custom;
tcp.setTransactionId(transRunning); // Set transaction id as per incoming request
uint16_t succeed = tcp.rawResponce(srcIp, data, len, slaveRunning);
if (!succeed){
Serial.print("fail");
}
Serial.printf("RTU Slave: %d, Fn: %02X, len: %d, ", src->slaveId, data[0], len);
Serial.print("Response TCP IP: ");
Serial.println(srcIp);

transRunning = 0;
slaveRunning = 0;
return Modbus::EX_PASSTHROUGH;
}


void setup() {
Serial.begin(115000);
WiFi.begin("E2", "*****");
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());

tcp.server(); // Initialize ModbusTCP to pracess as server
tcp.onRaw(cbTcpRaw); // Assign raw data processing callback

//S.begin(19200, SWSERIAL_8E1);
//rtu.begin(&S, DE_RE); // Specify RE_DE control pin
sym.begin((Stream*)&P2);
sym.slave(1);
sym.addHreg(1, 100);
rtu.begin((Stream*)&P1); // Specify RE_DE control pin
rtu.master(); // Initialize ModbusRTU as master
rtu.onRaw(cbRtuRaw); // Assign raw data processing callback
}

void loop() {
sym.task();
rtu.task();
tcp.task();
yield();
}
2 changes: 1 addition & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Examples of using callback functions.

Modbus file operations examples.

## [Modbus RTU to Modbus TCP bridge](bridge)
## [ModbusRTU to ModbusTCP bridge and related functions](bridge)

Very basic example of accessing ModbusRTU slave device connected to ESP8266/ESP32 via ModbusTCP server.

Expand Down

0 comments on commit b7aeef0

Please sign in to comment.