Go Down

Topic: Modbus TCP Master Communication Reading Register from Modbus slave (Read 13943 times) previous topic - next topic

konradieee

Hello together,

I´ve been trying for several days to establish a Modbus connection to get values from my wood heating system. https://www.eta.co.at/produkte/produktuebersicht/stueckholz/eta-sh-20-bis-60-kw/

My Hardware:

Arduino Uno R3
Arduino Ethernet Shield

My Software:

Arduino 1.0.5

My Library:

http://myarduinoprojects.com/modbus.html     /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  :'(  :'(  :'(  :'(

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?

pylon

Quote
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.

mikb55


konradieee

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?


pylon

Quote
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.

konradieee

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 https://forum.arduino.cc/index.php?topic=275752.0
@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 :-)



pylon

Quote
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:

Code: [Select]
#define DEBUG 1

so you get all the output.

Quote
Other Persons got the same problem, see https://forum.arduino.cc/index.php?topic=275752.0
@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
Code: [Select]
Mb.remSlaveIP = (192,168,178,54);

should be corrected to

Code: [Select]
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:

Code: [Select]
Serial.println("0 - print the first 12 words of the MbData space");

gets

Code: [Select]
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.

konradieee

Hello pylon,

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

Quote
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.


pylon

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.

Quote
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.

konradieee

Hello pylon,

Quote
The bigger problem is that the library is so bad
.
That´s true  :'( I think the modbus serial is finished, but modbus TCP isn´t.

Quote
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.

Quote
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.

Quote
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 :-(.


Quote
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
Quote
(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 ;-)

konradieee

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

pylon

Quote
That´s true  :'( 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.

Quote
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.

Quote
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:

Code: [Select]
Serial.println("This is just a string");

gets

Code: [Select]
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.

venado_bike

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

pylon

Quote
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.

konradieee

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.

Quote
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

Go Up