微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

EasyModBus modbusClient.ReadHoldingRegisters() 返回意外的 0

如何解决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 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?