如何解决EasyModBus modbusClient.ReadHoldingRegisters() 返回意外的 0
背景:
一段时间以来,我们一直将 Schneider M251 PLC 与 TM3AI8、TM3DQ8R 和 TM3DI8 模块一起使用,我注意到我们收到了通过 Modbus tcp 发送的意外值。
大多数情况下,我们通过 Modbus 协议接收到的信号在我们预期信号的较低部分的 4mA 范围内。但是,我们看到间歇性的 0 很少使用简单的 modbus tcp 库通过 modbus tcp 发送到我们的 java 软件
图书馆:http://easymodbustcp.net/en/
具体来说,当我们调用:
val = modbusClient.ReadHoldingRegisters(3005,1)[0];
我们看到间歇性的不常见 val = 0 出现但只是偶尔出现。当我检查名为 soMachine 的 PLC 软件时,它似乎从未显示过零值。有没有人遇到过这种问题?我使用结构文本设置了一个 POU 来计算 IO 读数为 0 的次数,显然它从来都不是。所以我认为这与 modbus 库有关。
我在下面提供了一个 system.out.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 个单位,这对我们的系统构成了一个问题,因为它代表了我们测量中的巨大差异。我们正在使用 Schneider 卡上提供的诊断位以及检测传感器故障。但是,传感器似乎没有故障并且工作正常。
如您所见,IO 卡的信号也有点嘈杂。万用表在读取此传感器的电压时不会波动,在我们的万用表上它在 3.989mV 范围内非常稳定。
当我们看到打印到控制台的间歇性 0 时,我们在 soMachine 中看不到 0。此外,轮询值的方法每 250 毫秒调用一次。
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,serialdata,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,data,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,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,sendData,data.length-2);
for (SendDataChangedListener hl : sendDataChangedListener)
hl.SendDataChanged();
}
data = new byte[2100];
int numberOfBytes = inStream.read(data,data.length);
if (receiveDataChangedListener.size() > 0)
{
receiveData = new byte[numberOfBytes];
System.arraycopy(data,receiveData,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);
}
问候,
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。