ModbusRTU Master Over TCP/IP Interface in Java

M

Thread Starter

Michael Venegas

I'm developing a ModbusRTU Master Over TCP/IP Interface to read a ModbusRTU electricity meters data. the meters are working over RS485 network, and I implemented a RS485/RS232 and RS232/Ethernet(TCP/IP) Adapter via a java application. The application implement a ModbusRTU Master (client) over the TCP/IP protocol via TCP/Socket.

The application pretends to be a jmodbus library extension.

But when the application send a modbus request to the electricity meter, don't receive a response.

the meter is a Contrel EMD-D3B-485 (technical info here-> http://www.contrel.it/data/products/tech/1325595876_EMC-D3bIM450-Ev2.1.pdf)

the RS232 / Ethernet(tcp/ip) converter is a Wiznete WIZ110SR (link here-> http://www.olimex.cl/product_info.php?cPath=76_83&products_id=455&product__name=Conversor_Serial_RS232_a_Ethernet_WIZ110SR)

the source code is the following (only to debug and test):<pre>
package testModelo;
import Utils.CCITTcrc;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import jmodbus.ByteUtils;

/**
*
* @author Michael Venegas, DreamIT Software -> mvenegas(in)dreamit(dot)cl
*/
public class testSocket {

public static void main(String args[]){

/*

the Utils.CCITTcrc calculate a Modbus (hight and low CRC Modbus -> posted by nancy here: http://www.control.com/thread/1026215359)
the jmodbus.ByteUtils convert the bytes to hex.

The electricity Meter containt the following data points:
ID meter -> 01
Data Address -> 4096
Data Length -> 16

*/

int idDevice = 1;
int modbusFunction = 3;
int dataAddress = 4096;
int dataAddressLength = 16;

//the byte traza is a new byte containt the modbusRTU message
byte traza[] = new byte[6];
traza[0] = (byte)(idDevice & 0xFF);
traza[1] = (byte)(modbusFunction & 0xFF);
traza[2] = (byte)((dataAddress >> 8) & 0xFF);
traza[3] = (byte)((dataAddress >> 0) & 0xFF);
traza[4] = (byte)((dataAddressLength >> 8) & 0xFF);
traza[5] = (byte)((dataAddressLength >> 0) & 0xFF);

//show the modbusRTU message
for(int i=0; i<traza.length; i++){
System.out.println(jmodbus.ByteUtils.toHex(traza));
}

//calculate the CRC Modbus message
CCITTcrc crc = new CCITTcrc();
byte ceerreces[] = crc.calc(traza, traza.length);

//show the CRC Modbus message
System.out.println(jmodbus.ByteUtils.toHex(ceerreces[0]));
System.out.println(jmodbus.ByteUtils.toHex(ceerreces[1]));

//create the full packet and concatenate the modbus message and modbus crc
byte[] Packet = {traza[0],traza[1],traza[2],traza[3],traza[4],traza[5],ceerreces[0],ceerreces[1]};

//the IP address and port of the RS232/Ethernet TCP/IP converter
String host="192.168.0.190";
int port = 5000;

//the java socket
Socket cliente;

try {

//create the socket
cliente = new Socket(host,port);

//instanciate the input and output stream to communicate with the converter
DataOutputStream salida_ = new DataOutputStream(cliente.getOutputStream());
BufferedReader receivedPacket= new BufferedReader(new InputStreamReader(cliente.getInputStream()));

//show the data packet
System.out.println("enviando packete..");
System.out.println("Lo que se envia: "+ByteUtils.toHex(Packet, Packet.length));

//sending the data packet
salida_.flush();
salida_.write(Packet);
salida_.flush();

System.out.println("Esperando recibir algo..");
//waiting receive some data
byte elem;
byte[] bytes = new byte[1];
for(int i=0; i< 1; i++){
elem = (byte) receivedPacket.read();
bytes = elem;
System.out.println(ByteUtils.toHex(elem));
}


} catch (IOException ex) {
ex.printStackTrace();
}


}

}</pre>
thanks for any help.
I apologize from my English, but i'm a Chilean guy and i do not speak so well.

Best regards
 
To expand on what Andrzej says, you have a complex chain of possible failures facing you, so start working your way down the chain.

1) confirm with wireshark that you send a single TCP packet and the Modbus/RTU is valid.

2) I personally would try using any Modbus master to poll the same request and confirm it looks 100% the same (aka: CRC byte order matches, no unexpected NULLs embedded, etc).

3) the wireshark will also confirm your TCP/serial box saw the request & sent the TCP ack.

4) if the TCP/serial box has stats, confirm it sent 8 bytes (or whatever size it should be).

5) then you get into the whole "Is my cable correct" between the TCP/serial box and meter. You need some somehow confirm this is correct - ideally with a volt meter - or if you are lucky, the Wiznete box's RS-232 port is 100% PC-like, then you can test the same cable directly.

- Lynn
 
M

Michael Venegas

The ip address of the converter is 192.168.0.190.

If i test from the modbus poll (trial) over a virtual "com" (the software and driver of the ethernet-rs232 converter, only for windows OS), the meter send a response, but when I send a request, no.

I'm reviewing the packets using wireshark but the packets are practically identical =S..

the packet screenshot of the software over a virtual "com" viewed from wireshark:

the packet screenshot of my application:

any suggestion?

now i'll test my app using a virtual modbusRTU slave

maybe my app is not allowed for receive a response or those code block contain a programation error.

thanks
best regards
 
L

Lynn August Linse

> the packet screenshot of the software over a virtual "com" viewed from wireshark:
>
> the packet screenshot of my application:
>
Note that the 'virtual comm' Data Len is 17 bytes, while your own is 273 bytes?

Should not your own packet be exactly 4 bytes if you are sending a Report Slave ID request as RTU in a raw binary TCP socket?

- Lynn
 
Top