Modbus TCP Master Communication Reading Register from Modbus slave

Hello together,

I´ve been trying for several days to establish a Modbus connection to get values from my wood heating system. ETA Stückholzkessel

My Hardware:

Arduino Uno R3
Arduino Ethernet Shield

My Software:

Arduino 1.0.5

My Library:

My Arduino Projects - Website dedicated to my arduino projects - A ModBus TCP library for the Arduino system /example.zip /MgsModbus_test_Master

I try to get information (temperature exhaust, temperatur outdoor, percentage heating puffer) with Function Code 0x03 (Read Holding Register) from Start Adress 1000, 6 Registers, so I need the value from Register 1000,1001,1002,1003,1004,1005,1006.
But it doesn´t work. I can´t get the data form holding registers :cry: :cry: :cry: :cry:

Ethernet/TCP Connection from Arduino 192.168.178.12 / 255.255.255.0 to Modbus slave wood heating system 192.168.178.54 / 255.255.255.0 works.

What´s my mistake?

MgsModbus_test_Master.ino (3.31 KB)

What´s my mistake?

You print out the data before making the request. Try to call function 3 again and you may get your data.

Post a link to the technical documentation.

hey thanks for very fast answering.
I have to add the line like this? See picture below

I will try it in the next days on the wood heating system :-).
@mikb55: Do you want the technical documentation of the wood heating system?

I have to add the line like this? See picture below

No, not really. I don't see in your pictures what bytes were sent from the PC to the Arduino. Please add a line to the sketch that gives that out.

I would also try to snoop the packets on the network with a tool like WireShark, that helps to see what's really being sent or not.

pylon:
No, not really. I don't see in your pictures what bytes were sent from the PC to the Arduino. Please add a line to the sketch that gives that out.

I would also try to snoop the packets on the network with a tool like WireShark, that helps to see what's really being sent or not.

Hello, I did a record with wireshark and i found no communication with the IP 192.168.178.12. I think the problem is, it gives no connection between Arduino and the heating system IP 192.168.178.54.

cause in the MgsModbus.cpp I found the lines:

//****************** ?? ******************
if (MbmClient.connect(ServerIp,502)) {
//#ifdef DEBUG
Serial.println("connected with modbus slave");
Serial.print("Master request: ");
for(int i=0;i<MbmByteArray[5]+6;i++) {
if(MbmByteArray < 16){Serial.print("0");}
_ Serial.print(MbmByteArray*,HEX);_
_
if (i != MbmByteArray[5]+5) {Serial.print(".");} else {Serial.println();}_
_
}_
_
//#endif _
_
for(int i=0;i<MbmByteArray[5]+6;i++) {_
_ MbmClient.write(MbmByteArray);
}
MbmCounter = 0;
MbmByteArray[7] = 0;
MbmPos = Pos;
MbmBitCount = Count;
} else {
#ifdef DEBUG*
* Serial.println("connection with modbus master failed");
#endif
MbmClient.stop();
}
}
so in the Arduino-COM-terminal must display "connected with modbus slave"
but it isn´t. Only the line 54.0.0.0 stands in the terminal.
Other Persons got the same problem, see Modbus TCP (not serial) master help needed - Networking, Protocols, and Devices - Arduino Forum
_@pylon: You answered at this topic on Oct 31, 2014, 04:57 pm.

I did the suggestion with "Remove line 18 and replace "ServerIp" in line 82 by "remSlaveIP"." but it doesn´t work.
wish everybody Merry christmas :slight_smile:_

cause in the MgsModbus.cpp I found the lines:

In the original there are no comment slashes (//) in front of the ifdef and endif lines. If you want to enable debugging set DEBUG to 1:

#define DEBUG 1

so you get all the output.

Other Persons got the same problem, see Modbus TCP (not serial) master help needed - Networking, Protocols, and Devices - Arduino Forum
@pylon: You answered at this topic on Oct 31, 2014, 04:57 pm.

I did the suggestion with "Remove line 18 and replace "ServerIp" in line 82 by "remSlaveIP"." but it doesn´t work.

I didn't remember this thread.

I get the impression the code you're trying to use was never finished.

Anyway, at least your line

Mb.remSlaveIP = (192,168,178,54);

should be corrected to

Mb.remSlaveIP = IPAddress(192,168,178,54);

Then the IP address should be printed correctly.

If I compile your code on a recent IDE (1.6.13) it prints the warning that the sketch uses almost the whole memory (RAM) for global variables. Most of this is just strings for the serial interface. You can eliminate that waste of memory easily by using the F() macro. Example:

Serial.println("0 - print the first 12 words of the MbData space");

gets

Serial.println(F("0 - print the first 12 words of the MbData space"));

Do that for all strings used as parameters to a print() or println() method.

Please post the results you get after having done all these changes.

Hello pylon,

I had done all your exchanges. The Arduino Terminal shows this.

Serial interface started
Ethernet interface started
My IP address: 192.168.178.12.
address: 0Data: 1
address: 1Data: 2
address: 2Data: 3
address: 3Data: 4
address: 4Data: 5
address: 5Data: 6
address: 6Data: 0
address: 7Data: 0
address: 8Data: 0
address: 9Data: 0
address: 10Data: 0
address: 11Data: 0
0 - print the first 12 words of the MbData space
1 - FC 1 - read the first 5 coils from the slave and store them in the lower byte of MbData[1]
2 - FC 2 - read the first 5 discrete inputs from the slave and store them in the higer of the MbData[1]
3 - FC 3 - read the first 5 registers from the slave and store them in MbData[3..7
4 - FC 4 - read the first 5 input registers from the slave and store them in MbData[8..12]
5 - FC 5 - write coil 0 of the slave with the bit valeu of MbData[0.0]
6 - FC 6 - write register 0 of the slave with MbData[2]
7 - FC 15 - write 5 coils of the slave starting with coil 0 with GetBit(16..20
8 - Fc 16 - write 5 registers of the slave starting on register 0 with MbData[0..4]
192.168.178.54

'Here, I typed a "3" to call FC 3.

connected with modbus slave
Master request: 00.01.00.00.00.06.01.03.03.E8.00.06
03.00.00.00.00.01.00
recieve klaar

'Here, I typed a "0" to print the words of MbData space.

address: 0Data: 1
address: 1Data: 2
address: 2Data: 3
address: 3Data: 4
address: 4Data: 5
address: 5Data: 6
address: 6Data: 0
address: 7Data: 0
address: 8Data: 0
address: 9Data: 0
address: 10Data: 0
address: 11Data: 0

I did a record with wireshark. But I don´t see a modbus telegramm (port: 502) sent by Arduino (IP: 192.168.178.012)

When I use a Windows programm for modbus master (see: start of the thread, picture Modbus_Daten.png). I get the data and I see the modbus telegramms in the wireshark window.

This is quite weird. The Arduino thinks that it has a connection to 192.168.178.54 on port 502 and it sends a byte sequence to it (00.01.00.00.00.06.01.03.03.E8.00.06). It even thinks it gets an answer back (03.00.00.00.00.01.00), the problem is, this answer isn't what it expects it to be. The bigger problem is that the library is so bad, it doesn't check for a correct length but just accesses bytes outside the received message.
The library you used has some more drawbacks, it looks quite unfinished to me. For example, the slave bus ID is hard coded to 1. I cannot find any documentation for your heating system regarding the modbus interface. What ID does it use? Where do you have the register addresses from? Can you post a link to the technical documentation? The answer you got from the heating system looks like it doesn't really support the ModBus protocol.

I did a record with wireshark. But I don´t see a modbus telegramm (port: 502) sent by Arduino (IP: 192.168.178.012)

I guess the problem is that you connect your network using a switch and not a hub. With a switch you don't see any traffic not originating from or targeting your PC. With a smart switch you can define your PC's port as a mirroring port to see all traffic but most cheap switches don't have this option.

Hello pylon,

The bigger problem is that the library is so bad

.
That´s true :cry: I think the modbus serial is finished, but modbus TCP isn´t.

I cannot find any documentation for your heating system regarding the modbus interface.

See, attachment ETAtouch_modbusTcp.pdf. I got this file per e-mail from the manufacturer.

What ID does it use? Where do you have the register addresses from?

You find it in the pdf page from 4, 2.3 Register assigment. ETA modbus adresses start from 1000 to 65000.

I guess the problem is that you connect your network using a switch and not a hub. With a switch you don't see any traffic not originating from or targeting your PC. With a smart switch you can define your PC's port as a mirroring port to see all traffic but most cheap switches don't have this option.

Oh sorry, you´re right. I use a WLAN Access Point with 4 Lan-Ports. It works like a switch :-(.

The answer you got from the heating system looks like it doesn't really support the ModBus protocol.

No, it works. Because with the PC I get the data. See attachment, Wireshark_Aufnahme.pcapng.
And the Arduino query

(00.01.00.00.00.06.01.03.03.E8.00.06)

are the complete Modbus/TCP bytes in the TCP sequement of the ethernet frame. What is with the Ethernet header, IP header, TCP header and Ethernet trailer? See, galil-presentation-the-evolution-of-ethernet-in-motion-and-io-control-webinar-17-638.jpg
Can I send the complete hex data like
client.write(0x00, 0x24, 0x96, 0x01, 0xb8, 0x20, 0x00, 0x16,
0xd3, 0xce, 0x19, 0x63, 0x08, 0x00, 0x45, 0x00,
0x00, 0x34, 0x03, 0xcc, 0x40, 0x00, 0x80, 0x06,
0x11, 0x66, 0xc0, 0xa8, 0xb2, 0x0a, 0xc0, 0xa8,
0xb2, 0x36, 0xc0, 0x81, 0x01, 0xf6, 0x04, 0x88,
0xe3, 0xc1, 0x9a, 0x19, 0x84, 0x22, 0x50, 0x18,
0x3f, 0x86, 0xbc, 0x43, 0x00, 0x00, 0x00, 0x70,
0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x03, 0xe8,
0x00, 0x06)
and I create/build the telegramm on my own?
Just increase the Modbus/TCP Transaction Identifier "0x00, 0x70", then I change the IP-Adresses from 192.168.178.10 "0xc0, 0xa8, 0xb2, 0x0a" to 192.168.178.12 maybe I have to adjust/include the CRC Check from the Transmission Control Protocol.

Thanks for helping :wink:

ETAtouch_modbusTcp.pdf (282 KB)

galil-presentation-the-evolution-of-ethernet-in-motion-and-io-control-webinar-17-638.jpg

I must rename the wireshark record from "Wireshark_Aufnahme.pcapng" to "Wireshark_Aufnahme.txt" because *.pcapng files are not supported.

Wireshark_Aufnahme.txt (13 KB)

That´s true :cry: I think the modbus serial is finished, but modbus TCP isn´t.

There are more bad ModBus RTU libraries than there are libraries that work. None of them (at least what my searches showed) is implementing the protocol in full, all of them just handle subsets. So "finished" is definitely not the right term here.

What is with the Ethernet header, IP header, TCP header and Ethernet trailer?

Everything related to Ethernet and TCP layer is handled inside the WizNet5100 chip in the standard Arduino world. If you really need control over that, you may use the RAW interface of the chip (I haven't done much with it yet) or take another hardware (p.e. ENC28J60). But as far as I understood the ModBus TCP protocol you don't need to tweak any of the lower layers, the whole protocol is in the application layer.

No, it works. Because with the PC I get the data. See attachment, Wireshark_Aufnahme.pcapng.

To me it looks like the system supports the ModBus basics but in an error case it doesn't follow the ModBus specification.

The MsgModbus library doesn't set the Transaction ID correctly but simply uses 0x0001 for every message it sends. It also wastes a lot of memory by setting the send and receive buffers very big (260 bytes) and your sketch wastes the rest by using huge strings in RAM (together more than 1.8kB is used before the sketch starts, the UNO has only 2kB)
I would start saving some memory by reducing the buffers to about 100 bytes and moving all strings to the flash using the F() macro:

Serial.println("This is just a string");

gets

Serial.println(F("This is just a string"));

Then run the code again. If this works better, we start to fix the worst errors in the library.

Hi, I'm with the same. Could someone make the communication correctly? Best regards. :slight_smile:

Could someone make the communication correctly?

What if you volunteer and try it? My ModBus is an RTU type so I don't have the problem to connect to a ModBus TCP device. My interest to do your work is not that high as you might imagine.

Hello pylon,

I did the ".println" changes in the MgsModbus_test_Master and the MgsModbuss.cpp library. In the MgsModbus.h it is not neccessary.
I did this only by text strings and only by the println-commands. So i did not do this with the print-Command i.e. Serial.print("lalalalala"). And not with the line " Serial.println(Mb.remSlaveIP);" because it doesn´t work.

It also wastes a lot of memory by setting the send and receive buffers very big (260 bytes) and your sketch wastes the rest by using huge strings in RAM (together more than 1.8kB is used before the sketch starts, the UNO has only 2kB)

Where can I see how much RAM uses Arduino Uno?

I don´t upload the code to the arduino respectively the heating system. I only compiled.

Best greets

Where can I see how much RAM uses Arduino Uno?

Current IDE versions tell you how much RAM you use for constant strings. What version do you use?

So i did not do this with the print-Command i.e. Serial.print("lalalalala"). And not with the line " Serial.println(Mb.remSlaveIP);" because it doesn´t work.

"Serial.println(Mb.remSlaveIP);" is not a constant string but a constructed one, so leave it as it is. But

Serial.print("lalalalala");

can be changed to

Serial.print(F("lalalalala"));

without generating errors.

konradieee:
Hello together,

I´ve been trying for several days to establish a Modbus connection to get values from my wood heating system. ETA Stückholzkessel

My Hardware:

Arduino Uno R3
Arduino Ethernet Shield

My Software:

Arduino 1.0.5

My Library:

My Arduino Projects - Website dedicated to my arduino projects - A ModBus TCP library for the Arduino system /example.zip /MgsModbus_test_Master

I try to get information (temperature exhaust, temperatur outdoor, percentage heating puffer) with Function Code 0x03 (Read Holding Register) from Start Adress 1000, 6 Registers, so I need the value from Register 1000,1001,1002,1003,1004,1005,1006.
But it doesn´t work. I can´t get the data form holding registers :cry: :cry: :cry: :cry:

Ethernet/TCP Connection from Arduino 192.168.178.12 / 255.255.255.0 to Modbus slave wood heating system 192.168.178.54 / 255.255.255.0 works.

What´s my mistake?

Which software do you use for Modbus master simulator? I ask for software that I see in Modbus_Daten.png.

I am trying a comunication Modbus with my PLC arduino based on arduino mega, and I want to read a holding registers of Victron Energy inverter, and I am using a MgsModbus library. I would be very grateful if you can help me with your response about software that you are using.

If I found your code mistake, I will tell you :slight_smile:

Which software do you use for Modbus master simulator? I ask for software that I see in Modbus_Daten.png.

We are using QModBus, it supports ModBus TCP as well as ModBus RTU.

I am using a MgsModbus library.

Did you read the thread? You might have noticed that this library is unfinished and not usable the way it currently is. So be prepared to invest quite a bit of work if you want to get your project running using that library.

pylon:
We are using QModBus, it supports ModBus TCP as well as ModBus RTU.

Did you read the thread? You might have noticed that this library is unfinished and not usable the way it currently is. So be prepared to invest quite a bit of work if you want to get your project running using that library.

Thanks, I will use QModbus!

I read the thread but I think If I did little changes, I would get running.

Now, I am searching other libraries to implement my project.

pylon:
We are using QModBus, it supports ModBus TCP as well as ModBus RTU.

Did you read the thread? You might have noticed that this library is unfinished and not usable the way it currently is. So be prepared to invest quite a bit of work if you want to get your project running using that library.

I have found otre library, it's this.
Modbus library