⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modbusrtutransport.java

📁 jamod is an object oriented implementation of the Modbus protocol, realized 100 in Java. It allows
💻 JAVA
字号:
//License/*** * Java Modbus Library (jamod) * Copyright (c) 2002-2004, jamod development team * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the author nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. ***/package net.wimpi.modbus.io;import net.wimpi.modbus.Modbus;import net.wimpi.modbus.ModbusIOException;import net.wimpi.modbus.msg.ModbusMessage;import net.wimpi.modbus.msg.ModbusRequest;import net.wimpi.modbus.msg.ModbusResponse;import net.wimpi.modbus.util.ModbusUtil;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;/** * Class that implements the ModbusRTU transport * flavor. * * @author John Charlton * @author Dieter Wimberger * * @version 1.2rc1 (09/11/2004) */public class ModbusRTUTransport    extends ModbusSerialTransport {  private InputStream m_InputStream;    //wrap into filter input  private OutputStream m_OutputStream;      //wrap into filter output  private byte[] m_InBuffer;  private BytesInputStream m_ByteIn;         //to read message from  private BytesOutputStream m_ByteInOut;     //to buffer message to  private BytesOutputStream m_ByteOut;      //write frames  private byte[] lastRequest = null;  public void writeMessage(ModbusMessage msg) throws ModbusIOException {    try {      int len;      synchronized (m_ByteOut) {        // first clear any input from the receive buffer to prepare        // for the reply since RTU doesn't have message delimiters        clearInput();        //write message to byte out        m_ByteOut.reset();        msg.setHeadless();        msg.writeTo(m_ByteOut);        len = m_ByteOut.size();        int[] crc = ModbusUtil.calculateCRC(m_ByteOut.getBuffer(), 0, len);        m_ByteOut.writeByte(crc[0]);        m_ByteOut.writeByte(crc[1]);        //write message        len = m_ByteOut.size();        byte buf[] = m_ByteOut.getBuffer();        m_OutputStream.write(buf, 0, len);     //PDU + CRC        m_OutputStream.flush();        if(Modbus.debug) System.out.println("Sent: " + ModbusUtil.toHex(buf, 0, len));        // clears out the echoed message        // for RS485        if (m_Echo) {          readEcho(len);        }        lastRequest = new byte[len];        System.arraycopy(buf, 0, lastRequest, 0, len);      }    } catch (Exception ex) {      throw new ModbusIOException("I/O failed to write");    }  }//writeMessage  //This is required for the slave that is not supported  public ModbusRequest readRequest() throws ModbusIOException {    throw new RuntimeException("Operation not supported.");  } //readRequest  /**   * Clear the input if characters are found in the input stream.   *   * @throws ModbusIOException   */  public void clearInput() throws IOException {    if (m_InputStream.available() > 0) {      int len = m_InputStream.available();      byte buf[] = new byte[len];      m_InputStream.read(buf, 0, len);      if(Modbus.debug) System.out.println("Clear input: " +                  ModbusUtil.toHex(buf, 0, len));    }  }//cleanInput  public ModbusResponse readResponse()      throws ModbusIOException {    boolean done = false;    ModbusResponse response = null;    int dlength = 0;    try {      do {        //1. read to function code, create request and read function specific bytes        synchronized (m_ByteIn) {          int uid = m_InputStream.read();          if (uid != -1) {            int fc = m_InputStream.read();            m_ByteInOut.reset();            m_ByteInOut.writeByte(uid);            m_ByteInOut.writeByte(fc);            //create response to acquire length of message            response = ModbusResponse.createModbusResponse(fc);            response.setHeadless();            // With Modbus RTU, there is no end frame.  Either we assume            // the message is complete as is or we must do function            // specific processing to know the correct length.  To avoid            // moving frame timing to the serial input functions, we set the            // timeout and to message specific parsing to read a response.            getResponse(fc, m_ByteInOut);            dlength = m_ByteInOut.size() - 2; // less the crc            if (Modbus.debug) System.out.println("Response: " +               ModbusUtil.toHex(m_ByteInOut.getBuffer(), 0, dlength + 2));            m_ByteIn.reset(m_InBuffer, dlength);            //check CRC            int[] crc = ModbusUtil.calculateCRC(m_InBuffer, 0, dlength); //does not include CRC            if (ModbusUtil.unsignedByteToInt(m_InBuffer[dlength]) != crc[0]                && ModbusUtil.unsignedByteToInt(m_InBuffer[dlength + 1]) != crc[1]) {              throw new IOException("CRC Error in received frame: " + dlength + " bytes: " + ModbusUtil.toHex(m_ByteIn.getBuffer(), 0, dlength));            }          } else {            throw new IOException("Error reading response");          }          //read response          m_ByteIn.reset(m_InBuffer, dlength);          if (response != null) {            response.readFrom(m_ByteIn);          }          done = true;        }//synchronized      } while (!done);      return response;    } catch (Exception ex) {      System.err.println("Last request: " + ModbusUtil.toHex(lastRequest));      System.err.println(ex.getMessage());      throw new ModbusIOException("I/O exception - failed to read");    }  }//readResponse  /**   * Prepares the input and output streams of this   * <tt>ModbusRTUTransport</tt> instance.   *   * @param in the input stream to be read from.   * @param out the output stream to write to.   * @throws IOException if an I\O error occurs.   */  public void prepareStreams(InputStream in, OutputStream out)      throws IOException {    m_InputStream = in;   //new RTUInputStream(in);    m_OutputStream = out;    m_ByteOut = new BytesOutputStream(Modbus.MAX_MESSAGE_LENGTH);    m_InBuffer = new byte[Modbus.MAX_MESSAGE_LENGTH];    m_ByteIn = new BytesInputStream(m_InBuffer);    m_ByteInOut = new BytesOutputStream(m_InBuffer);  } //prepareStreams  public void close() throws IOException {    m_InputStream.close();    m_OutputStream.close();  }//close  private void getResponse(int fn, BytesOutputStream out)    throws IOException {    int bc = -1, bc2 = -1, bcw = -1;    int inpBytes = 0;    byte inpBuf[] = new byte[256];    try {      switch (fn) {        case 0x01:        case 0x02:        case 0x03:        case 0x04:        case 0x0C:        case 0x11:  // report slave ID version and run/stop state        case 0x14:  // read log entry (60000 memory reference)        case 0x15:  // write log entry (60000 memory reference)        case 0x17:          // read the byte count;          bc = m_InputStream.read();          out.write(bc);          // now get the specified number of bytes and the 2 CRC bytes          setReceiveThreshold(bc+2);          inpBytes = m_InputStream.read(inpBuf, 0, bc+2);          out.write(inpBuf, 0, inpBytes);          m_CommPort.disableReceiveThreshold();          if (inpBytes != bc+2) {            System.out.println("Error: looking for " + (bc+2) +                               " bytes, received " + inpBytes);          }          break;        case 0x05:        case 0x06:        case 0x0B:        case 0x0F:        case 0x10:          // read status: only the CRC remains after address and function code          setReceiveThreshold(6);          inpBytes = m_InputStream.read(inpBuf, 0, 6);          out.write(inpBuf, 0, inpBytes);          m_CommPort.disableReceiveThreshold();          break;        case 0x07:        case 0x08:          // read status: only the CRC remains after address and function code          setReceiveThreshold(3);          inpBytes = m_InputStream.read(inpBuf, 0, 3);          out.write(inpBuf, 0, inpBytes);          m_CommPort.disableReceiveThreshold();          break;        case 0x16:          // eight bytes in addition to the address and function codes          setReceiveThreshold(8);          inpBytes = m_InputStream.read(inpBuf, 0, 8);          out.write(inpBuf, 0, inpBytes);          m_CommPort.disableReceiveThreshold();          break;        case 0x18:          // read the byte count word          bc = m_InputStream.read();          out.write(bc);          bc2 = m_InputStream.read();          out.write(bc2);          bcw = ModbusUtil.makeWord(bc, bc2);          // now get the specified number of bytes and the 2 CRC bytes          setReceiveThreshold(bcw+2);          inpBytes = m_InputStream.read(inpBuf, 0, bcw + 2);          out.write(inpBuf, 0, inpBytes);          m_CommPort.disableReceiveThreshold();          break;      }    } catch (IOException e) {      m_CommPort.disableReceiveThreshold();      throw new IOException("getResponse serial port exception");    }  }//getResponse  } //ModbusRTUTransport

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -