-->
Page 1 of 1

modbus tcp to rtu gateway

PostPosted: Sat Jan 27, 2018 3:33 am
by frank_dunn1
Hi I am trying to make a modbus tcp to rtu gateway . It is kind of working but the response I get back from my rtu slave is always the previous transaction's reply . Would anybody be interested to help me , I cannot find the problem ?

Re: modbus tcp to rtu gateway

PostPosted: Sat Jan 27, 2018 11:07 am
by rudy
I did a search and I found what looked to be a few implementations available for the ESP8266. Maybe they would be easier than rolling your own.

https://github.com/JhonControl/Arduino_ ... aveTCP-RTU

http://pdacontrolen.com/tutorial-esp826 ... tu-master/

viewtopic.php?f=11&t=2442


I don't know much about modbus, and don't have any modbus devices, so I doubt I would be much help as far as your problem. But it sounds like it might not be too hard a problem. If you post your code maybe someone can see what the problem is.

Re: modbus tcp to rtu gateway

PostPosted: Sun Jan 28, 2018 7:11 am
by frank_dunn1
the problem i have can be simulated with a tcp master and a rtu slave , no real hardware required .
I had a look at the links , it seems to be different . My aim is to have a esp8266 device act as a modbus tcp server (slave) , it acts as a rtu master . It should work as a transparent modbus gateway .


Code: Select all#include <SoftwareSerial.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>

const char* ssid = "..........";
const char* password = "..............";

// Start a TCP Server on port 502
WiFiServer server(502);
WiFiClient client ;

const long interval = 50 ;           // interval (milliseconds)
size_t len = 255;
uint8_t sbuf[255];
uint8_t rtu_buf[255];
uint8_t rtu_len;
uint16_t calcCRC(uint8_t u8_buff_size)
{
  uint32_t tmp, tmp2, flag;
  tmp = 0xFFFF;
  for (uint8_t i = 0; i < u8_buff_size; i++)
  {
    tmp = tmp ^ rtu_buf[i];
      for (uint8_t j = 1; j <= 8; j++)
    {
      flag = tmp & 0x0001;
      tmp >>= 1;
      if (flag)
        tmp ^= 0xA001;
    }
  }
  tmp2 = tmp >> 8;
  tmp = (tmp << 8) | tmp2;
  tmp &= 0xFFFF;

  return tmp;
}


void setup() {
  pinMode(D0,OUTPUT); //re rs485
 
 
  Serial.begin(115200);
  WiFi.begin(ssid,password);
 
  //Wait for connection
  while(WiFi.status() != WL_CONNECTED) {
    delay(100);
    //swSer.print(".");
  }
 
  server.begin();
 
}

void loop() {
      bailout:
      Serial.flush();
      yield();
      if (!client.connected()) {
      client = server.available();
      }
      else{     
   
    if (client.available() > 0) {
     
      int readnum = client.read(sbuf,client.available());
      rtu_len = sbuf[5];
      for (int i=0 ;i<readnum-6;i++){
        rtu_buf[i] = sbuf[i+6];
      }
      int value = calcCRC(rtu_len);
      rtu_buf[rtu_len]  = (value & 0xFF00) >> 8;
      rtu_buf[rtu_len+1] = value & 0x00FF;
      Serial.flush();
      digitalWrite(D0,HIGH);
      delay(1);
      Serial.write(rtu_buf,rtu_len + 2);
      Serial.flush();
      digitalWrite(D0,LOW);
      memset(rtu_buf, 0, 50);
      unsigned long currentMillis = millis();
      while(!Serial.available()){
        yield();
         if( millis() - currentMillis  > interval){
          goto bailout;
         }
        }
        int i = 6;
        currentMillis = millis();
       
        while (Serial.available() > 0)  {
          rtu_buf[i] = Serial.read();
          i ++;
          yield();
          if( millis() - currentMillis  > interval){
           
          goto bailout;
         }
           }
           if ( i > 10){
           rtu_len = i- 2;
           rtu_buf[5] = rtu_len -6 ;
           rtu_buf[0] = sbuf[0];
           rtu_buf[1] = sbuf[1];
           client.write((const uint8_t*)rtu_buf,rtu_len);
           Serial.flush();
           }
           
           //Unfortunately there is a bad function overload in the library,
           //but you can just typecast the clientbuf to overcome this problem.....
           //   eg ... client.write((const uint8_t*)clientBuf, sizeof(clientBuf));
  }
 }
}