Arduino Forum

Using Arduino => Networking, Protocols, and Devices => Topic started by: LamySae on Nov 12, 2017, 09:43 am

Title: Modbus TCP master library
Post by: LamySae on Nov 12, 2017, 09:43 am
Hello everyone,

Actually I'm working on a project based on arduino Uno and ESP8266 UART shield to connect it to a controller dynamic power as a Modbus TCP master to read some registers .

I've already tried a http requests to read data from the webpage of the controller using Ethernet shield but unfortunately the connection failed many times and if it's established, the response is too slow. Hence, I drooped this method.

Then I decided to use Modbus TCP/IP protocol but I got some troubles with the libraries and it seems that this method is not reliable as I want to get data in real time.

As I've decided to use a wireless connection , I change the ethernet shield to an ESP8266 one .
I prefer to not use a Modbus RS485 protocol, but it seems that it's the most reliable . In this case, I should add another serial device with the controller to send data to the socket, but I really don't want to  add more hardware.

Could you please give me your opinions to choose the best method ?
Thank you in advance.



Title: Re: Modbus TCP master library
Post by: pylon on Nov 12, 2017, 08:09 pm
This post includes several very different things.

Quote
I've already tried a http requests to read data from the webpage of the CDP using Ethernet shield but unfortunately the connection failed many times and if it's established, the response is too slow. Hence, I drooped this method.
What does that mean? Don't you think it may be a programming problem? So with a corrected sketch it may be a perfect method?
Don't you think it's time to post a link to that CDP and it's manual in English?

Quote
Then I decided to use Modbus TCP/IP protocol but I got some troubles with the libraries and it seems that this method is not reliable as I want to get data in real time.
Define what "real time" means for you. For most people it simply means that the time to get the information is predictable. It sounds that you think the response must be immediate but in the computer field there is no immediate answer. So specify what time range you think is acceptable in your case. Given your description I would assume it's several seconds.
And who told you that the ModBus TCP protocol is not reliable? It was me who told you that some libraries for ModBus TCP on Arduino are not very reliable but that doesn't mean that the protocol has this deficit.

Quote
My socket should be installed far from the CDP , hence I prefer to not use a Modbus RS485 protocol, but it seems that it's the most reliable .
Where is that information from? ModBus RTU and ModBus TCP show about the same reliability in practical use. Based on my experience I would even say that you can reach higher reliability using ModBus TCP because it doesn't have a strict timing dependency.

Quote
Could you please give me your opinions to choose the best method ?
Tell us the complete specification of your project and stop starting thread by thread which simply splits up the context.
What CDP are you using (links), what distance do you have to between the components, what equipment is already in place (networks, cables, etc.)?
Title: Re: Modbus TCP master library
Post by: pylon on Nov 13, 2017, 07:18 pm
The English manual is available here (http://docs.circutor.com/docs/M98250001-03.pdf).

Some errors I found in your sketch (HTTP):

Code: [Select]
IPAddress  server (10,3,1,15);
IPAddress ip (10,0,1,60);


The default network mask if not specified in the Ethernet library is 255.255.255.0. So this setup will only work if you have a router in your network that is listening on the IP 10.0.1.1 and is able to route traffic to the specified server. The Arduino Ethernet library doesn't know anything about class-based routing (which is not used for the last 15 years at least).

Code: [Select]
  if (client.connect(server, 80)) {
   
    client.println("connected");
    client.println("GET /10.0.1.50 HTTP/1.1");
    client.println("Connection: close");
    client.println();

  } 


The GET line must be the first line sent to the server. In your code you send a "connected" to the server which will disturb it for sure.
Also I doubt that your browser will show you anything if you point it to the URL

http://10.3.1.15/10.0.1.50

That looks like a mix of different IP addresses. On which URL do you expect to get anything from the CDR?


The code that is looking for the power value might work, that depends on the page that is returned. Do you have an example page (HTML) that you may post here?

Quote
I mean by real time the instantaneous response of request , the real power at that moment ( up to 30s).
I'm absolutely sure we will match that goal with the HTTP based solution if the value are available on the web pages.
Title: Re: Modbus TCP master library
Post by: noiasca on Nov 13, 2017, 07:23 pm
just to get a clearer picture of your planed architecture:

The CDP0 reads the inverter(s) via modbus RTU and you want to read the CDP0 by parsing the CDP0's TCP/IP (http) "website"?

And I just browsed through your sketch ... you are dealing with 3 IPs
10.3.1.15  "server"
10.0.1.60  "ip"
10.0.1.50  "in the client's GET request ... "

so what is your servers IP in reality?

Title: Re: Modbus TCP master library
Post by: pylon on Nov 15, 2017, 04:51 pm
Quote
The IP adress of the server is really 10.3.1.15, the CDP isn't in the same network of the server. What should I do in this case ?
Use the 5 parameter begin method for the Ethernet object:

Code: [Select]
  void begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet);


Set the dns_server parameter equally as the gateway as your router probably has a DNS forwarder service.

Quote
A piece of html code (load power)  is in the attachements.
Unfortunately that's not HTML code but a screen shot having the developer tools open. But probably the rest of the code looks similar and in that case your finder search strings won't work. Please post the complete HTML source (it looks like you're using an older version of Firefox, so use Ctrl+U and then Save As...), I will then try to find correct finder search strings.

Quote
I try the Modbus TCP protocol but it doesn't get data until I press 4 ( Fc to read input registers) , I've forced 4 in the code but the communication failed.
In that code you use 10.0.1.50 for the server IP. Do you know what IP you CDP has, in this post you told us it's a 10.3.1.15.

The library you're using has the server IP fixed in the library source code:
Code: [Select]
  byte ServerIp[] = {192,168,200,163};

So you won't get any data from your server with that library.
Title: Re: Modbus TCP master library
Post by: LamySae on Nov 16, 2017, 12:36 pm
Thank you for the clarification.


Quote
byte ServerIp[] = {192,168,200,163};
I didn't find any serverIP in the code source(.cpp)  of the library. I set all the slaveIP as 10.0.1.50
Title: Re: Modbus TCP master library
Post by: pylon on Nov 16, 2017, 06:20 pm
Quote
For the Modbus TCP code, I use 10.0.1.50 for the slave IP which is the CDP in this case. I don't need the server IP ( 10.3.1.15) in the Modbus code.
In ModBus TCP the server is the slave. What IP does the CDP have? If your "server" is not the CDP, what is it then?

Quote
I didn't find any serverIP in the code source(.cpp)  of the library. I set all the slaveIP as 10.0.1.50
Post a link to the library you're using. I've just used Google as you didn't provide the necessary information. in that library the posted code is in line 18 of MgsModbus.cpp.

Quote
You can find it in attachments.
It's more complicated than I expected. The HTML is dynamically updated using Javascript, so you won't find the data in the HTML code the server transmits. The advantage if this is that you probably won't have to parse HTML code to find the values but you can request it in JSON format (I guess).
You have to find out reading the different Javascript files ("./cgi/list_data.cgi" is the first candidate to check I would say).
Title: Re: Modbus TCP master library
Post by: noiasca on Nov 17, 2017, 01:00 pm
I assume one of these JavaScripts will do the AJAX

Code: [Select]

        <script type="text/javascript" src="jquery.ui.i18n.all.js"></script>
<script type="text/javascript" src="./cgi/list_data.cgi"></script>
<script type="text/javascript" src="update.4.01.js"></script>


So check which of these scripts to the update of the id's, and I assume within these scripts you find the resource how to get the data from the CDP. Then do a call in the same way like the JavaScript within your browser. Check what you are getting back, propably a nice JSON object, then parse the JSON with the JSON library.

Title: Re: Modbus TCP master library
Post by: pylon on Nov 17, 2017, 06:39 pm
Quote
I was talking about the serverIP (10.3.1.15) in the http request code , I don't need it in the Modbus code. I'm using the MgsModbus library . Please see the attachments.
What the IP of the CDR? Is it possible that the HTML file was not delivered by the CDR but some other server? So what's behind 10.3.1.15? What's behind 10.0.1.50?

You modified the Mudbus library, did you? The fixed IP is not the only problem that library has... If you modified it, it might be the time to post your modified version.

Quote
I've moved on requesting data from the database which already reads data from CDP registers in Modbus TCP. I guess the delay of waiting database to read from CDP then respond to the Arduino would be meaningful.
Please explain how that database come into the run. Do you have additional equipment you didn't mention earlier? And if your "database" already have a ModBus TCP connection why should the Arduino open an additional one? Please give us more information about the complete project.


BTW: Never, never post code as screenshots! There is a button in the editor (</>) especially for posting code.
Title: Re: Modbus TCP master library
Post by: Watcher on Jan 12, 2018, 09:15 am
Sorry to intervene in the thread, but as I am also trying to interrogate a Solar Inverter with TCP modbus, could someone explain the terms Server Vs Master referring to the modbus terminology?

I find confusing explanations on the net where sometimes the term Server is used and in other cases the term Master...

My Solar inverter documentation is defines the inverter as being the Modbus Server. Obviously the arduino must then be the client. Who will be the Master?

In addition, what would be the recommended library to use?

Thanks and sorry again to hijack the thread! :)

Title: Re: Modbus TCP master library
Post by: LamySae on Jan 12, 2018, 11:52 am
Hi Watcher,
According to Modbus TCP Terminology, the master is the client (arduino) and the slave is the server (solar inverter) in your case.

We use the term master/slave in Modbus RTU terminology and client/server in Modbus TCP .
I used the MgsModbus Library with ethernet shield, It works very well but actually I have to work with wifi module . Unfortunately I didn't find any library for Modbus TCP master, all the libraries work with slave.

You can get the MgsModbus library from this link http://myarduinoprojects.com/modbus.html

Good luck!
Title: Re: Modbus TCP master library
Post by: Watcher on Jan 12, 2018, 12:07 pm
Hi Watcher,
According to Modbus TCP Terminology, the master is the client (arduino) and the slave is the server (solar inverter) in your case.

We use the term master/slave in Modbus RTU terminology and client/server in Modbus TCP .
I used the MgsModbus Library with ethernet shield, It works very well but actually I have to work with wifi module . Unfortunately I didn't find any library for Modbus TCP master, all the libraries work with slave.

You can get the MgsModbus library from this link http://myarduinoprojects.com/modbus.html

Good luck!
Thanks for the info.

The link you provided has an example (example.zip) with one arduino as master and the other as slave.
Did you check it out?
Title: Re: Modbus TCP master library
Post by: LamySae on Jan 12, 2018, 12:45 pm
In MgsModbus.cpp file, change serverIP to the IP adress of your solar inverter.
In MgsModbus_test_master.ino, change IP adress and mac adress to the ethernet shield ones.
In MB.req method, change register adress and all the bytes of the packets that you want to send .
Title: Re: Modbus TCP master library
Post by: Watcher on Jan 12, 2018, 02:06 pm
In MgsModbus.cpp file, change serverIP to the IP adress of your solar inverter.
In MgsModbus_test_master.ino, change IP adress and mac adress to the ethernet shield ones.
In MB.req method, change register adress and all the bytes of the packets that you want to send .
Do you think this will also work with wifi, ie a  esp8266 module instead of an ethernet shield?
Title: Re: Modbus TCP master library
Post by: LamySae on Jan 12, 2018, 02:29 pm
I'm still looking for another library for esp8266 modbus TCP master
Title: Re: Modbus TCP master library
Post by: Watcher on Jan 12, 2018, 04:19 pm
If this one works ok as a master with rs485, maybe we can mkdify it to also accomodate esp8266?
Title: Re: Modbus TCP master library
Post by: Juraj on Jan 12, 2018, 04:20 pm
code from my project for requesting inverter data over ModbusTCP. tested with Ethernet2, WiFiEsp and used with WiFiLink. it should work with any Client implementation even on the esp8266, since the WiFi Link library is only a remote interface to esp8266 WiFi library
Code: [Select]

#include <TimeLib.h>
#include "Events.h"
#include "consts.h"

// Fronius Symo Hybrid SunSpec Modbus

const long EPOCH_2000 = 946696800;

const int METER_UID = 240;

const int MODBUS_CONNECT_ERROR = -10;
const int MODBUS_NO_RESPONSE = -11;

IPAddress symoAddress(192,168,1,107);

boolean requestSymoRTC() {
  int regs[2];
  int res = modbusRequest(1, 40222, 2, regs);
  if (modbusError(res))
    return false;
  setTime(EPOCH_2000 + (unsigned int) regs[0] * 65535 + (unsigned int) regs[1]);
  return true;
}

boolean requestInverter() {
  int regs[2];
  int res = modbusRequest(1, 40083, 2, regs);
  if (modbusError(res))
    return false;
  inverterAC = regs[0] * pow(10, regs[1]); // ac power * scale
  return true;
}

boolean requestMeter() {
  int regs[16];
  int res = modbusRequest(METER_UID, 40076, 16, regs);
  if (modbusError(res))
    return false;
  voltage = regs[3] * pow(10, regs[8] + 1); // ac voltage F3 * scale
  m = -regs[11] * pow(10, regs[15]); // ac power * scale
  return true;
}

boolean requestBattery() {
  int regs[58];
  int res = modbusRequest(1, 40257, 58, regs); //MPPT reg + SF offsset
  if (modbusError(res))
    return false;
  b = (unsigned int) regs[37] * pow(10, regs[0]); // dc power * scale
  soc = regs[54] / 100; // storage register addr - mppt register addr + ChaSta offset
  switch (regs[57]) {  // charge status
    case 4:  // CHARGING
    case 6:  // HOLDING
    case 7:  // TESTING (CALIBRATION)
      break;
    default:
      b = -b;
  }
  return true;
}

boolean modbusError(int err) {

  static int modbusErrorCounter = 0;
  static int modbusErrorCode = 0;

  if (modbusErrorCode != err) {
    modbusErrorCounter = 0;
    modbusErrorCode = err;
  }
  if (err == 0)
    return false;
  modbusErrorCounter++;
  switch (modbusErrorCounter) {
    case 1:
      sprintf(msg, "modbus error %d", err);
    break;
    case 5:
      sprintf(msg, "modbus error %d %d times", err, modbusErrorCounter);
      events.write(MODBUS_EVENT, err, 0);
      stopCause = AlarmCause::MODBUS;
    break;
  }
  return true;
}

/*
 * return
 *   - 0 is success
 *   - negative is comm error
 *   - positive value is modbus protocol exception code
 */
int modbusRequest(byte uid, unsigned int addr, byte len, int *regs) {

  static NetClient modbus;
  static unsigned long lastRequest = 0;

  unsigned long d = millis() - lastRequest;
  if (d < 1000) {
  delay(d);
  }
  lastRequest = millis();

  if (!modbus.connected()) {
    int st = modbus.status();
    modbus.stop();
    modbus.connect(symoAddress, 502);
    if (!modbus.connected()) {
      modbus.stop();
      return MODBUS_CONNECT_ERROR;
    }
    sprintf(msg, "modbus reconnect %d", st);
  }
  byte request[] = {0, 1, 0, 0, 0, 6, uid, 3, (byte) (addr / 256), (byte) (addr % 256), 0, len};
  modbus.write(request, sizeof(request));
  modbus.flush();
  if (!available(modbus)) {
    modbus.stop();
    return MODBUS_NO_RESPONSE;
  }
  for (int i = 0; i < 7; i++) { // skip 7
    if (modbus.read() == -1)
      return -3;
    if (!available(modbus))
      return -1;
  }
  switch (modbus.read()) { // code
    case 3:
      break;
    case -1:
      return -4;
    case 0x83:
      return modbus.read(); // 0x01, 0x02, 0x03 or 0x11
    default:
      return -6;
  }
  if (!available(modbus))
    return -1;
  int l = modbus.read() / 2;
  int i = 0;
  while (true) {
    if (!available(modbus))
      return -1;
    byte hi = modbus.read();
    if (!available(modbus))
      return -1;
    byte lo = modbus.read();
    regs[i++] = hi * 256 + lo;
    if (i == len || i == l)
      break;
  }
  return 0;
}

boolean available(Stream& client) {
  for (int i = 0; i < 20; i++) {
    if (client.available())
      return true;
    delay(50);
  }
  return client.available();
}



it is not a library and it contains other elements of my project like logging events, so if you decide to use it, modify it as you need
Title: Re: Modbus TCP master library
Post by: LamySae on Jan 12, 2018, 05:00 pm
Thank you very much Mr.Juraj
I'll test it
Title: Re: Modbus TCP master library
Post by: LamySae on Jan 12, 2018, 05:11 pm
Mr Juraj,
I didn't find the header files Events.h and consts.h in github
Could you please give us a link to download them ?
Title: Re: Modbus TCP master library
Post by: Juraj on Jan 12, 2018, 05:18 pm
remove them. those are other parts of my project
Title: Re: Modbus TCP master library
Post by: Watcher on Jan 12, 2018, 05:26 pm
Thanks Juraj!

I am having some troubles testing your code though. Maybe I dont understand it very well.

eg. what is this ?

Code: [Select]

static NetClient modbus;


Already removed the two library includes and added SPI.h and Ethernet.h

PS: Hay this is cool.. It looks like we are all 3 online now!
Title: Re: Modbus TCP master library
Post by: Juraj on Jan 12, 2018, 05:34 pm
modbusRequest() is universal for type 0x03 request. the rest is for example.
NetClient is a #define in my project for the Clent type of networking library used. replace it with EthernetClient
Title: Re: Modbus TCP master library
Post by: Watcher on Jan 12, 2018, 05:36 pm
Thanks Juraj!

I am having some troubles testing your code though. Maybe I dont understand it very well.

eg. what is this ?

Code: [Select]

static NetClient modbus;


Already removed the two library includes and added SPI.h and Ethernet.h

PS: Hay this is cool.. It looks like we are all 3 online now!
OK, now removed NetClient above and added a global

EthernetClient  modbus;

and also some Global vars for various vars that are missing and it now compiles..


Still not sure how to use it though :)
Title: Re: Modbus TCP master library
Post by: Juraj on Jan 12, 2018, 05:46 pm
you must know the modbus registers of your system and understand Modbus TCP protocol.
for example readInverter request two registers from address 40083 described in inverter specs and uses them to calculate the inverter AC output
Title: Re: Modbus TCP master library
Post by: Watcher on Jan 12, 2018, 06:07 pm
YEs, I understood that... My inverter is an SMA one... going through the modbus spec now.

Where does the inverter IP go ?
Title: Re: Modbus TCP master library
Post by: Juraj on Jan 12, 2018, 06:12 pm
Where does the inverter IP go ?
it is there in the snippet as SymoAddress
Title: Re: Modbus TCP master library
Post by: Watcher on Jan 12, 2018, 06:20 pm
YEs got it ..Thanks you...

Sorry to have to ask all this.... but just to be sure :


modbusRequest(METER_UID, 40490, 1, regs);

METER_UID is the inverter's modbus address (in my case 126)
40490 is the register number
1 is the number of registrers to read
regs is where to store the result, in this case of length 1 Int (2 bytes)


Is the above correct ?

Cant get the inverter to respond for some reason...


Title: Re: Modbus TCP master library
Post by: Juraj on Jan 12, 2018, 06:30 pm
uid is a device address. in my case the inverter has address 1 and smart meter has address METER_UID. on Fronius I needed to enable the Modbus TCP (check box in web panel)
Title: Re: Modbus TCP master library
Post by: Watcher on Jan 12, 2018, 06:42 pm
Thanks ..

Could you also please explain this packet frame :

 byte request[] = {0, 1, 0, 0, 0, 6, uid, 3, (byte) (addr / 256), (byte) (addr % 256), 0, len};


in particular the first 5 bytes ...



Title: Re: Modbus TCP master library
Post by: Juraj on Jan 12, 2018, 06:52 pm
Transaction identifier   2 bytes   For synchronization between messages of server and client

Protocol identifier   2 bytes   0 for Modbus/TCP

Length field   2 bytes   Number of remaining bytes in this frame

Unit identifier   1 byte   Slave address (255 if not used)

Function code   1 byte   Function codes as in other variants

Data bytes   n byted   Data as response or commands
Title: Re: Modbus TCP master library
Post by: Watcher on Jan 12, 2018, 07:00 pm
ok...

I must be doing something wrong...

I ve tried to read a few registers of  length 1 int and they all give back the value of 4 while the res variable returns  -10..

Not sure what it means...
Title: Re: Modbus TCP master library
Post by: Juraj on Jan 12, 2018, 07:07 pm
did you check if Modbus TCP is enabled on inverter?
Title: Re: Modbus TCP master library
Post by: Watcher on Jan 12, 2018, 07:13 pm
Yes I have enabled it.

Does the -10 result in the res variable mean anything to you ?

Also  is this

if (modbus.read() == -1)


universal for all modbus devices or specific to yours ?
Title: Re: Modbus TCP master library
Post by: Juraj on Jan 12, 2018, 07:18 pm
yes. it has a define on top of the snippet. connect didn't success.

Do you have Java skills? I have a java version you could try from a computer

EDIT: I put it here for future readers. The problem was resolved in other thread (https://forum.arduino.cc/index.php?topic=522730.msg3565261#msg3565261). It had nothing to do with the sketch or modbus protocol. Two devices in network had the IP address of the inverter.
Title: Re: Modbus TCP master library
Post by: Watcher on Jan 12, 2018, 07:19 pm
Nah.... no Java here :)
Title: Re: Modbus TCP master library
Post by: Juraj on Jan 12, 2018, 07:26 pm
try on computer to connect with telnet client to ip of the inverter on port 502
Title: Re: Modbus TCP master library
Post by: Watcher on Jan 12, 2018, 07:29 pm
doesnt connect either...but maybe its nit designed to respond to telnet requests.

I can ping the inverter ok though
Title: Re: Modbus TCP master library
Post by: Juraj on Jan 12, 2018, 07:58 pm
telnet <IP> 502 should connect.

I found this. Do not know if it applies.

Procedure:
1. Start Sunny Explorer on the computer and create a Speedwire system (see Sunny Explorer user manual).
2. Log into the Speedwire system as Installer.
3. Select the SMA inverter to be configured in the system tree.
4. Select the tab Settings.
5. Select the parameter group External Communication.
6. Select [Edit].
☑ You will see the categories TCP Server and UDP Server under the parameter group Modbus.
7. To activate the TCP server, make the following settings in the group Modbus > TCP Server:
• In the Activated drop-down list, select the entry Yes.
• If necessary, change the port in the Port field (default setting: 502).
Title: Re: Modbus TCP master library
Post by: Watcher on Jan 12, 2018, 08:33 pm
telnet <IP> 502 should connect.

I found this. Do not know if it applies.

Procedure:
1. Start Sunny Explorer on the computer and create a Speedwire system (see Sunny Explorer user manual).
2. Log into the Speedwire system as Installer.
3. Select the SMA inverter to be configured in the system tree.
4. Select the tab Settings.
5. Select the parameter group External Communication.
6. Select [Edit].
☑ You will see the categories TCP Server and UDP Server under the parameter group Modbus.
7. To activate the TCP server, make the following settings in the group Modbus > TCP Server:
• In the Activated drop-down list, select the entry Yes.
• If necessary, change the port in the Port field (default setting: 502).
Thats  correct. Thats exactly what i did to enable modbus on both tcp and udp.
Title: Re: Modbus TCP master library
Post by: Watcher on Jan 12, 2018, 08:55 pm
Update:

Telnet connects on port 502!

Arduino still returns -10 !

Tried to use the same sketch and tried to connect to another Telnet server at port 23 and still doesnt connect. Must be something wrong with the connect function...
Will try again tomorrow..

Title: Re: Modbus TCP master library
Post by: Juraj on Jan 13, 2018, 07:59 am
does the ethernet shield connect to nerwork? got IP address?
Title: Re: Modbus TCP master library
Post by: Watcher on Jan 13, 2018, 08:30 am
Good morning!

yes.. I can also ping the Ethernet shield from the computer
Title: Re: Modbus TCP master library
Post by: Juraj on Jan 13, 2018, 08:42 am
show me the sketch please
Title: Re: Modbus TCP master library
Post by: Watcher on Jan 13, 2018, 03:00 pm
ok...please see attached.

This compiles for a Mega board
Title: Re: Modbus TCP master library
Post by: Juraj on Jan 13, 2018, 03:13 pm
#define SMA_PORT 23
?
Title: Re: Modbus TCP master library
Post by: Watcher on Jan 13, 2018, 04:29 pm
This should be 502. I changed it to 23 to test Telnet on an arduino based Telnet server.
Title: Re: Modbus TCP master library
Post by: Juraj on Jan 13, 2018, 05:49 pm
and did you try then again the inverter address and modbus port after telnet connection to inverter from computer connected?
Title: Re: Modbus TCP master library
Post by: Watcher on Jan 13, 2018, 06:14 pm
Something really weird is going on :

1. I can telnet to the inverter on port 502 from the computer from a client like putty and from windows telnet.
2. I cannot telnet connect from arduino with a standard telnet client sketch loaded. I tried this with two different arduino mega's each with its own ethernet shield and connected to different points  of the network with the same result.
3. I can telnet from PC to both arduinos .
4. While trying all the above once or twice I did manage to get the arduino to successfully telnet the inverter but 98% of the times it fails

I think I am pretty confident that the possibility of a hardware issue in the arduino has been eliminated since both arduino setups easily telnet each other and from/to the computer.

So the question is why I can telnet the inverter from PC but not from arduino..

Edit :
I am thinking this could be some kinda timing issue. What if the timeout after connection attempt from the arduino is shorter that it is from the PC? Anyway to change it?
Title: Re: Modbus TCP master library
Post by: Juraj on Jan 13, 2018, 07:56 pm
The telnet port 23 is enabled on inverter? You can connect from computer to inverter on port 23?

Yes the timing. I copy/pasted a wrong version

Code: [Select]

int modbusRequest(byte uid, unsigned int addr, byte len, int *regs) {

  static NetClient modbus;
  if (!modbus.connected()) {
//    modbus.stop();
    modbus.connect(symoAddress, 502);
    if (!modbus.connected()) {
      modbus.stop();
      return MODBUS_CONNECT_ERROR;
    }
  }
  byte request[] = {0, 1, 0, 0, 0, 6, uid, 3, (byte) (addr / 256), (byte) (addr % 256), 0, len};
  modbus.write(request, sizeof(request));
  modbus.flush();
  if (!available(modbus)) {
    modbus.stop();
    return MODBUS_NO_RESPONSE;
  }
  for (int i = 0; i < 7; i++) { // skip 7
    if (modbus.read() == -1)
      return -3;
    if (!available(modbus))
      return -1;
  }
  switch (modbus.read()) { // code
    case 3:
      break;
    case -1:
      return -4;
    case 0x83:
      return modbus.read(); // 0x01, 0x02, 0x03 or 0x11
    default:
      return -6;
  }
  if (!available(modbus))
    return -1;
  int l = modbus.read() / 2;
  int i = 0;
  while (true) {
    if (!available(modbus))
      return -1;
    byte hi = modbus.read();
    if (!available(modbus))
      return -1;
    byte lo = modbus.read();
    regs[i++] = hi * 256 + lo;
    if (i == len || i == l)
      break;
  }
  return 0;
}

boolean available(Stream& client) {
  for (int i = 0; i < 5000; i++) {
    if (client.available())
      return true;
    delay(1);
  }
  return client.available();
}

Title: Re: Modbus TCP master library
Post by: Watcher on Jan 13, 2018, 08:28 pm
No, port 23 doesn't  connect on inverter.  When i said i can telnet the inverter, i meant on port 502, not on 23.

I didnt understand. What is the last  snippet  for? Any different from  the one i used?
Title: Re: Modbus TCP master library
Post by: Juraj on Jan 13, 2018, 08:30 pm

different timing
Title: Re: Modbus TCP master library
Post by: Watcher on Jan 14, 2018, 08:39 am
I have tried the above sketch with a modbus server simulator on my android device and it works fine.

However ,for some reason, it still refuses to connect with the Inverter.

The same happens, that is, it doesn't connect  when i try to connect with a telnet client (at port 502) from the arduino, but it connects straight away from a telnet client on the computer which I can not explain.



Title: Re: Modbus TCP master library
Post by: Juraj on Jan 14, 2018, 09:03 am
check the IP address of the inverter in the sketch digit by digit.

are all devices in the same network?
Title: Re: Modbus TCP master library
Post by: Watcher on Jan 14, 2018, 09:22 am
Yes.. and Yes... !

Code: [Select]
byte subnet[] = { 255, 255, 255, 0 }; 
byte mac[] = {0xDE, 0xFE, 0xBE, 0xFF, 0xFE, 0xED };
byte DNS[]={ 192, 168, 10, 254 };
byte gateway[] = { 192, 168, 10, 254 };     


IPAddress local_IP (192,168,10,180);
IPAddress SMA_Address(192,168,10,5);

#define SMA_PORT 502
Title: Re: Modbus TCP master library
Post by: Watcher on Jan 14, 2018, 09:27 am
Decided to try out different Ethernet timing settings in case this affects the connection.

added :
Code: [Select]

#include <utility/w5100.h>


and in setup()
Code: [Select]

W5100.setRetransmissionTime(2000);   //2000 is the default value, equivalent to 200ms
W5100.setRetransmissionCount(8);     //8 is the default value





Trying different values for re-transmit and count.. No luck so far...
Title: Re: Modbus TCP master library
Post by: Juraj on Jan 14, 2018, 09:31 am
in inverter modbus settings is access from all IP addresses enabled? not only from your computer
Title: Re: Modbus TCP master library
Post by: Watcher on Jan 14, 2018, 09:37 am
in inverter modbus settings is access from all IP addresses enabled? not only from your computer
On the Inverter , the only available settings to change are

TCP Enable/disable,
UDP Enable/disable

and Port Number (default 502)

Title: Re: Modbus TCP master library
Post by: Watcher on Jan 14, 2018, 09:42 am
Trying different timing settings as in post #57 above, I managed to successfully connect read the value of a modbus register with

W5100.setRetransmissionTime(1500);   and
W5100.setRetransmissionCount(9); 


But connection is not consistent. If I reset the arduino and try again, it doesnt connect even with the above settings and I need to try a few times. Once the connection is achieved, then subsequent reads are done ok.

 


Title: Re: Modbus TCP master library
Post by: Watcher on Jan 14, 2018, 09:56 am
Running out of ideas here...

With the tolerance  (!) Of the forum moderators, i might cross-post this issue in the peogramming section of the forum...:)
Title: Re: Modbus TCP master library
Post by: Watcher on Jan 15, 2018, 08:38 am
Posted the issue in a new thread in the programming section of the forum here:

https://forum.arduino.cc/index.php?topic=522730.new#new
Title: Re: Modbus TCP master library
Post by: Juraj on Jan 16, 2018, 09:46 am
Also  is this

if (modbus.read() == -1)


universal for all modbus devices or specific to yours ?
this is Stream.read() method of arduino core. It is inherited in all Serial classes, network client classes and other Stream implementations
Title: Re: Modbus TCP master library
Post by: OcGuru on Apr 30, 2018, 10:25 pm
Hello,

I use this sketch to read out another Arduino modbus IP slave.


How can i adjust the sketch so the master read outs the slave every second?

Thanks in Advance,

OcGuru
Title: Re: Modbus TCP master library
Post by: Juraj on Apr 30, 2018, 10:32 pm
my project from which the code origins is here (https://github.com/jandrassy/Regulator/tree/master/Regulator). get inspired