Develop Eclipse modbus/TCP software

T

Thread Starter

Tommy

I am a new user to use java eclipse to develop a programe which is using to communicate a device (CT Mentor MP) through modbus/TCP port 502. I have plugged in jamod for communicate to the device. But I don't know how can I read and write the device's register. I didn't find out the related script on Internet. Have anyone can give me some hints or examples please?

Thanks
 
Thank you for your reply. Now, I want to write a simple program to test the communication with Mentor MP. I want to change the value from 0 to 1 at register address 23384.

There is my script:

package Co;

import java.net.*;
import java.io.*;
import net.wimpi.modbus.*;
import net.wimpi.modbus.msg.*;
import net.wimpi.modbus.io.*;
import net.wimpi.modbus.net.*;
import net.wimpi.modbus.procimg.InputRegister;
import net.wimpi.modbus.procimg.Register;
import net.wimpi.modbus.procimg.SimpleInputRegister;
import net.wimpi.modbus.procimg.SimpleRegister;
import net.wimpi.modbus.util.*;
import net.wimpi.modbus.facade.*;
import net.wimpi.modbus.msg.ModbusRequest;

public class modbusConnection {

@SuppressWarnings("null")
public static void main (String args[]){

int port = Modbus.DEFAULT_PORT;
int ref = 1;

SimpleRegister sr =null;
sr = new SimpleRegister(23384);

try {
String astr = "192.168.0.100";
InetAddress addr = InetAddress.getByName(astr);
TCPMasterConnection con = new TCPMasterConnection(addr); //the connection
ModbusTCPTransaction trans = null; //the transaction

Wreq = new WriteSingleRegisterRequest(ref,sr);
Wres = new WriteSingleRegisterResponse();

//2. Open the connection
con.setPort(port);
con.connect();
System.out.println("Connected... " + port + " " + ref);

trans = new ModbusTCPTransaction(con);
trans.setRequest(Wreq);

trans.execute();
Wres = (WriteSingleRegisterResponse) trans.getResponse();
System.out.println("The value is: " + Wres.getHexMessage());


con.close();

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

System.out.println("Finished");
}



}

But it failed. Can you tell me what I have to correct? And can you tell me What is the different between writesimpleregisterrequest and writecoilrequest, please?

Thanks a lot!!
 
Well, to start with you said you are trying to write the value 1 in register 23384, but it looks like your code is trying to write the value 23384 to register 1. That's the most obvious mistake to me. There may be more mistakes, but I suggest that you start with that.

As for your questions, "writesimpleregisterrequest" writes to a register, while "writecoilrequest" writes to a coil. A "register" is a 16 bit word memory location. There are two types of registers. Input registers are read only, while holding registers are read/write.

A coil is a boolean (bit) address. Coils are read/write. Discrete inputs are read only boolean addresses.

So, the difference between a coil and a register is that they are different data types with different memory locations. There are 4 different types of memory locations. You might want to read up a bit on Modbus so that you will understand this.

I have my own project on Sourceforge which has a couple of packages which might help you. Go to "http://sourceforge.net/projects/mblogic/" and download the "MBTools" package. The package requires the Python run time, so you will need to install that ("http://www.python.org").

MBTools contains three packages. MBAsyncServer is a Modbus/TCP server (slave). You can use this to test your program's communications. You may find it more convenient while testing than using the Mentor MP. MBPoll is a command line client (master). You should be able to use this to test communications with the Mentor MP. MBPoll is also a good example if you would rather write your program in Python than in Java.

If you use MBAsyncServer for testing, keep in mind that the register mapping may be different than it is for the Mentor MP. MBAsyncServer maps the holding registers over the input registers (so that they're actually the same registers), and the discrete inputs over the coils (again, so they are actually the same addresses). This is because as a simple server, there would be no other way to write to read only addresses. Also, the coils (and discrete inputs) are mapped into the first 4096 registers (i.e. coils 0 to 15 are in register 0, coils 16 to 31 in register 1, etc.).

 
Hi there,

Thank you for your help and I got the connection from my program to yours. But I got the other problem. How can I get the real number of the register address's value? I tried to use read input registers response, but it only showed me some hex message something like that.

Thanks!!

 
You said: "I got the connection from my program to yours". There are actually several programs in the package that I suggested downloading. I will assume that you mean MBAsyncServer, which is a server (slave). So, I assume you are trying to say that you have your Java program talking to MBAsyncServer using Modbus/TCP so that you can test your program before trying to connect it to the Mentor drive.

You said: "How can I get the real number of the register address's value?". Your question is not very clear. However, what you could try doing is to write a number to a register and then try to read it back. If you can read back the same number that you wrote, then you know your program is reading and writing OK.

You said: "I tried to use read input registers response, but it only showed me some hex message something like that". The program that you posted had the following line near the end:

System.out.println("The value is: " + Wres.getHexMessage());

In other words, you told the program to print out the message in hex ("getHexMessage"). If you ask the program to print out a message in hex, then I am not really very surprised that it printed out "some hex message". What did you expect it to do? If you don't want "some hex message", then go over the Jamod API documentation (it's on their web site) and use some different function calls to print out the message in a different form.

So, where you seem to be at this time is you think your program is talking to the server, but you don't know what the response is. You can either take the "some hex message" and compare it to the Modbus specification, or you can change your program to output the data in a different format (Jamod has a different set of functions for that).
 
Thank you for your reply. I am sorry about my questions made you confused. I rewrited my previous code and communicated with the mblogic. I successed to write the value to address 32200.

Then, I hope to write a function to receive the value back from address 32200 ( assume I dont know the value at address 32200). I was read the jamod API document, I don't know "ReadInputRegisterResquest" is the one function can receive the value from the address.

Now, I got the problem is I have to enter 2 different values to run "ReadInputRegisterResquest" functions. The first one is (reference - the reference number of the register to read from) and the other one is (count - the number of words to be read.). I understood the refernece value is the register address (32200). But I don't know what value I need to type in.

And the second question is if I used Read Input Registers Response to get the value back. I only find one "get Hex message" is the closest one can be used. If it is the only one function I can use, how can I convert back to real numbers?

I hope this time you get my problems and give me some help!!! I am happy to hear your advices soon :)

Thanks a lot!!!
 
Did you read the example on the Jamod website for "TCP Master HOW-TO"? They have a complete example. Look in step 5 of their example. You should be able to use this as a guide to read input registers using the input register request and response classes instead of the discrete input classes.

 
Hi,

I tried again and got the value I wanted finally after I posted my question. I will test it on Mentor MP soon and see it works or not.

Thanks!!!!
 
Hello,

I got the other problem. I want to send a value( 450000) to the register 23404. But read input register function convert the value to 16 bit. And the 16 bit data range up to 63500 something only). And I did not find any function to convert it back to 32 bit from api doc.

Then, how can I solve this problem?

Thanks!!
 
K

Ken Emmons Jr.

I could be wrong, but I believe Modbus only supports 16 bit words. To transfer a 32 bit word you will have to break it into two words (manually) and re-assemble at the other end (manually).

KEJR
 
A Modbus register is 16 bits, so 450000 isn't going to fit in one register. A common method of dealing with this is to write the upper and lower halves of a 32 bit number it into two different registers. You'll need to read the drive's documentation however to see how the manufacturer decided to handle this.

At this point it's not a Modbus question, it's a Mentor drive question. I can't answer questions about the drive itself as I don't have a manual.
 
Hey all,

Don't know if anyone is still working on this. I have written a great deal of code using jamod and Modbus TCP/IP. My applications include remote monitoring, alarm responses, and remote control. I would NOT bother going with a commercial Java Modbus library as jamod has worked for me in multiple large projects already. If anyone has any specific implementation questions please let me know. I have ALSO written some about it in my company blog. Feel free to check it out as it goes through a broad overview of the process.

http://www.dmcinfo.com/Blog/article...-to-a-Modbus-Network-with-Java-and-Jamod.aspx
 
In reply to JonC:

I read your blog post, and it sounded interesting. How did you do the remote monitoring user interface? I've done this with a web interface with XHTML/SVG/Javascript to do things like push buttons, pilot lights, strip charts, alarms and events, etc. Did you do anything similar? I've got some graphics samples and screen hots at:

http://mblogic.sourceforge.net/mbhmi/mbhmiintro.html

that show you what I mean.
 
Top