java EasyModBus Modbus客户端。ReadHoldingRegisters()返回意外的0
背景:
我们已经将施耐德M251 PLC与TM3AI8、TM3DQ8R和TM3DI8模块一起使用了一段时间,我注意到我们正在通过Modbus tcp发送意外值
大多数情况下,我们通过Modbus协议接收的信号在预期信号较低部分的4mA范围内。但是,我们看到使用easy modbus tcp库通过modbus tcp向java软件发送的间歇性0很少
库:http://easymodbustcp.net/en/
具体而言,当我们呼吁:
val=modbusClient。读保持寄存器(3005,1)[0]
我们看到间歇性的不频繁val=0出现,但只是偶尔出现。当我检查名为soMachine的PLC软件时,它似乎从未显示过零值。以前有人遇到过这种问题吗?我设置了一个POU,使用结构文本来计算IO读数为0的次数,显然从来都不是。所以我认为这与modbus库有关
我提供了一个系统。出来下面显示问题的println(val):
VAL IS THIS NOW: 3995
VAL IS THIS NOW: 3989
VAL IS THIS NOW: 3995
VAL IS THIS NOW: 3995
VAL IS THIS NOW: 3986
VAL IS THIS NOW: 3998
VAL IS THIS NOW: 3992
VAL IS THIS NOW: 3989
VAL IS THIS NOW: 3998
VAL IS THIS NOW: 3995
VAL IS THIS NOW: 0 <- Random intermittent 0
VAL IS THIS NOW: 3986
VAL IS THIS NOW: 3998
VAL IS THIS NOW: 3992
VAL IS THIS NOW: 3989
VAL IS THIS NOW: 3995
VAL IS THIS NOW: 3989
VAL IS THIS NOW: 3989
plc上的I/O配置为0-20mA扩展,传感器为4-20mA传感器。我们单位刻度上的零读数表示-2500个单位,这对我们的系统来说是一个问题,因为它表示我们的测量存在很大差异。我们正在使用施耐德卡上可用的诊断位以及检测传感器故障。但是,传感器似乎没有故障,工作正常
正如您所看到的,IO卡上的信号也有点嘈杂。万用表在读取此传感器的电压时不会波动,在我们的万用表上,它在3.989mV范围内非常稳定
当我们看到控制台上打印的间歇性0时,在soMachine中看不到0。此外,每250ms调用一次值轮询方法
我们采用了以下“过滤器”,但这并不是解决问题的理想办法
static int pt05ErrorCount = 0, pt05lastVal;
private static double readRegister3005() throws IOException{
try {
int val;
if(PLC.isConnected()) {
val = modbusClient.ReadHoldingRegisters(3005, 1)[0];
if(val > 0) {
pt05ErrorCount = 0;
pt05lastVal = val;
}
}else {
val = -1000;
}
System.out.println("VAL IS THIS NOW: "+val);
if(val > 0) {
return (double) (10000-0)/(20-4)*((double) val/1000-4)+0; //convert mA to psig
}else {
if(pt05ErrorCount > maxErrorCount) {
pt05ErrorCount++;
return (double) (10000-0)/(20-4)*((double) val/1000-4)+0;
}else {
return (double) (10000-0)/(20-4)*((double) pt05lastVal/1000-4)+0;
}
}
} catch(Exception e) {
System.out.println(e);
throw new IOException(Globals.getSystemCalendarDateandTime() + " PLC.java > readRegister3005(): ERROR reading PLC address 3005.");
}
}
如果您需要有关该问题的更多信息,请告诉我
ReadHoldingRegisters方法如下所示:
/**
* Read Holding Registers from Server
* @param startingAddress Fist Address to read; Shifted by -1
* @param quantity Number of Inputs to read
* @return Holding Registers from Server
* @throws de.re.easymodbus.exceptions.ModbusException
* @throws UnknownHostException
* @throws SocketException
* @throws SerialPortTimeoutException
* @throws SerialPortException
*/
public int[] ReadHoldingRegisters(int startingAddress, int quantity) throws de.re.easymodbus.exceptions.ModbusException,
UnknownHostException, SocketException, IOException, SerialPortException, SerialPortTimeoutException
{
if (tcpClientSocket == null)
throw new de.re.easymodbus.exceptions.ConnectionException("connection Error");
if (startingAddress > 65535 | quantity > 125)
throw new IllegalArgumentException("Starting adress must be 0 - 65535; quantity must be 0 - 125");
int[] response = new int[quantity];
this.transactionIdentifier = toByteArray(0x0001);
this.protocolIdentifier = toByteArray(0x0000);
this.length = toByteArray(0x0006);
//serialdata = this.unitIdentifier;
this.functionCode = 0x03;
this.startingAddress = toByteArray(startingAddress);
this.quantity = toByteArray(quantity);
byte[] data = new byte[]
{
this.transactionIdentifier[1],
this.transactionIdentifier[0],
this.protocolIdentifier[1],
this.protocolIdentifier[0],
this.length[1],
this.length[0],
this.unitIdentifier,
this.functionCode,
this.startingAddress[1],
this.startingAddress[0],
this.quantity[1],
this.quantity[0],
this.crc[0],
this.crc[1]
};
if (this.serialflag)
{
crc = calculateCRC(data, 6, 6);
data[data.length -2] = crc[0];
data[data.length -1] = crc[1];
}
byte[] serialdata = null;
if (serialflag)
{
serialdata = new byte[8];
java.lang.System.arraycopy(data, 6,serialdata,0,8);
serialPort.purgePort(SerialPort.PURGE_RXCLEAR);
serialPort.writeBytes(serialdata);
if (debug) StoreLogData.getInstance().Store("Send Serial-Data: "+ Arrays.toString(serialdata));
long dateTimeSend = DateTime.getDateTimeTicks();
byte receivedUnitIdentifier = (byte)0xFF;
serialdata = new byte[256];
int expectedlength = 5+2*quantity;
while (receivedUnitIdentifier != this.unitIdentifier & !((DateTime.getDateTimeTicks() - dateTimeSend) > 10000 * this.connectTimeout))
{
serialdata = serialPort.readBytes(expectedlength, this.connectTimeout);
receivedUnitIdentifier = serialdata[0];
}
if (receivedUnitIdentifier != this.unitIdentifier)
{
data = new byte[256];
}
if (serialdata != null)
{
data = new byte[262];
System.arraycopy(serialdata, 0, data, 6, serialdata.length);
if (debug) StoreLogData.getInstance().Store("Receive ModbusRTU-Data: " + Arrays.toString(data));
}
for (int i = 0; i < quantity; i++)
{
byte[] bytes = new byte[2];
bytes[0] = data[3+i*2];
bytes[1] = data[3+i*2+1];
ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
response[i] = byteBuffer.getShort();
}
}
if (tcpClientSocket.isConnected() | udpFlag)
{
if (udpFlag)
{
InetAddress ipAddress = InetAddress.getByName(this.ipAddress);
DatagramPacket sendPacket = new DatagramPacket(data, data.length, ipAddress, this.port);
DatagramSocket clientSocket = new DatagramSocket();
clientSocket.setSoTimeout(500);
clientSocket.send(sendPacket);
data = new byte[2100];
DatagramPacket receivePacket = new DatagramPacket(data, data.length);
clientSocket.receive(receivePacket);
clientSocket.close();
data = receivePacket.getData();
}
else
{
outStream.write(data, 0, data.length-2);
if (debug) StoreLogData.getInstance().Store("Send ModbusTCP-Data: "+Arrays.toString(data));
if (sendDataChangedListener.size() > 0)
{
sendData = new byte[data.length-2];
System.arraycopy(data, 0, sendData, 0, data.length-2);
for (SendDataChangedListener hl : sendDataChangedListener)
hl.SendDataChanged();
}
data = new byte[2100];
int numberOfBytes = inStream.read(data, 0, data.length);
if (receiveDataChangedListener.size() > 0)
{
receiveData = new byte[numberOfBytes];
System.arraycopy(data, 0, receiveData, 0, numberOfBytes);
for (ReceiveDataChangedListener hl : receiveDataChangedListener)
hl.ReceiveDataChanged();
if (debug) StoreLogData.getInstance().Store("Receive ModbusTCP-Data: " + Arrays.toString(data));
}
}
}
if (((int) data[7]) == 0x83 & ((int) data[8]) == 0x01)
{
if (debug) StoreLogData.getInstance().Store("FunctionCodeNotSupportedException Throwed");
throw new de.re.easymodbus.exceptions.FunctionCodeNotSupportedException("Function code not supported by master");
}
if (((int) data[7]) == 0x83 & ((int) data[8]) == 0x02)
{
if (debug) StoreLogData.getInstance().Store("Starting adress invalid or starting adress + quantity invalid");
throw new de.re.easymodbus.exceptions.StartingAddressInvalidException("Starting adress invalid or starting adress + quantity invalid");
}
if (((int) data[7]) == 0x83 & ((int) data[8]) == 0x03)
{
if (debug) StoreLogData.getInstance().Store("Quantity invalid");
throw new de.re.easymodbus.exceptions.QuantityInvalidException("Quantity invalid");
}
if (((int) data[7]) == 0x83 & ((int) data[8]) == 0x04)
{
if (debug) StoreLogData.getInstance().Store("Error reading");
throw new de.re.easymodbus.exceptions.ModbusException("Error reading");
}
for (int i = 0; i < quantity; i++)
{
byte[] bytes = new byte[2];
bytes[0] = data[9+i*2];
bytes[1] = data[9+i*2+1];
ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
response[i] = byteBuffer.getShort();
}
return (response);
}
问候,
共 (0) 个答案