I'm using the library Jamod and I have trouble reading the record, what I want is to read only the record number 300 PLC I'm connected, but I get read error (enters the catch). Thanks for your help
package com.JR.scada;
import java.net.InetAddress;
import net.wimpi.modbus.Modbus;
import net.wimpi.modbus.io.ModbusTCPTransaction;
import net.wimpi.modbus.msg.ReadInputDiscretesRequest;
import net.wimpi.modbus.msg.ReadInputDiscretesResponse;
import net.wimpi.modbus.msg.ReadMultipleRegistersResponse;
import net.wimpi.modbus.net.TCPMasterConnection;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class Main extends Activity{
TextView text, depurar;
EditText IP;
Button boton;
int i=0;
TCPMasterConnection con = null; //the TCP connection
ModbusTCPTransaction trans = null; //the Modbus transaction
InetAddress addr = null; //direccion del esclavo
int port = Modbus.DEFAULT_PORT;//puerto por defecto 502
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.lblRegistro);
IP = (EditText) findViewById(R.id.txtIp);
depurar = (TextView) findViewById(R.id.txtdepurar);
boton = (Button)findViewById(R.id.btnVerRegistro);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
protected void onStop() {
super.onStop();
//Close the TCP connection
con.close();
}
public class conectar extends AsyncTask<String,String,Integer>{
ReadInputDiscretesRequest req = null; //the request
ReadInputDiscretesResponse res = null; //the response
int startReg;
protected void onPreExecute() {
try {
//IP address;
addr = InetAddress.getByName("212.170.50.238");
} catch (Exception e) {
Log.d("MODBUS","IP error", e);
}
}
protected Integer doInBackground(String... urls) {
try {
// Open the connection
con = new TCPMasterConnection(addr);
con.setPort(port);
con.connect ();
try {
startReg = 300;
// Prepare the request
req = new ReadInputDiscretesRequest (startReg, 1);
// Prepare the transaction
trans = new ModbusTCPTransaction(con);
trans.setRequest(req);
// execute the transaction
trans.execute();
// get the response
res = (ReadInputDiscretesResponse) trans.getResponse ();
} catch (Exception e) {
Log.d("MODBUS", "Error in reading/writing");
return 1;
}
} catch (Exception e) {
Log.d("MODBUS","connection error", e);
return 1;
}
return 0;
}
protected void onPostExecute(Integer bytes) {
if(con.isConnected()){
depurar.setText("conecta");
}
text.setText("Digital Inputs Status=" + res.getDiscretes ().toString () );
}
}
public void onClick(View v) {
// int startReg;
conectar conectamos = new conectar();
conectamos.execute("hola");
}
error:
08-21 10:01:57.554: D/MODBUS(3322): Error in reading/writing
Without knowing more about the modbus configuration on your slave PLC, my first suggestion is to try a different value for startReg, and see if the error persists. This will rule out problems with your Java.
Some test numbers that should work: 0,1,7,8
They may not all work, but at least one of them should return successfully.
If none of them return successfully, there may be a problem on the PLC configuration, or a problem with your request code.
If one of the test numbers is successful, you should post your results. If so, this means that you are attempting to access a memory location that does not exist on the PLC. If you access undefined PLC memory locations, often the PLC will abort the request (it does not just send back '0').
If you find that your code works when using different values for startReg
, but not for 300, the reason has to do with memory mapping on the PLC, and this can be different for each brand/model of PLC (post your PLC brand/model if available).
You say in your question 'record 300'. When working with PLC, you usually don't refer to memory as a record. Are you trying to access Bit 300, Byte 300, Word 300, DoubleWord 300?
The real question you need to be asking, is 300
the actual modbus address you want to read, or is 300
how the PLC address is mapped (such as the 300th I/O slot, not necessarily the 300th WORD). It may be required to convert between octal, decimal, and hexidecimal addresses. Or, you may need to re-index an address (some PLCs like to start counting at 1
, but generally modbus starts counting at 0
).
Perhaps you meant to read BIT 300 (not record 300), which would then be 12th
BIT in the 18th
WORD, so it would look like this:
//
startReg = 17;
// Prepare the request
// Your 300th bit should be the last value returned.
req = new ReadInputDiscretesRequest (startReg, 12);
The different values I suggested for startReg
are meant to help you discover how your PLC Inputs are mapped into modbus addresses by your Java library. This might help with number conversions.