在 net.wimpi.modbus.facade 中,ModbusSerialMaster.class 包含:
public void setUnitIdentifier(int unitid) {
}
public int getUnitIdentifier() {
}
遗憾的是,ModbusTCPMaster.class 中缺少此代码,因此它始终默认读取单元标识符或 (1)。任何人都可以建议解决方法或提议将代码从串行复制到 TCP。
在 net.wimpi.modbus.facade 中,ModbusSerialMaster.class 包含:
public void setUnitIdentifier(int unitid) {
}
public int getUnitIdentifier() {
}
遗憾的是,ModbusTCPMaster.class 中缺少此代码,因此它始终默认读取单元标识符或 (1)。任何人都可以建议解决方法或提议将代码从串行复制到 TCP。
好吧,如果有人实际使用 ModbusTCPMaster,并且像我一样,想通过 ID 与任意数量的从属单元通信,我已经更改了 ModbusTCPMaster.java 以反映这种能力,如 ModbusSerial Master.class 中所示
package net.wimpi.modbus.facade;
import net.wimpi.modbus.ModbusCoupler;
import net.wimpi.modbus.ModbusException;
import net.wimpi.modbus.io.ModbusTCPTransaction;
import net.wimpi.modbus.msg.*;
import net.wimpi.modbus.net.TCPMasterConnection;
import net.wimpi.modbus.procimg.InputRegister;
import net.wimpi.modbus.procimg.Register;
import net.wimpi.modbus.util.BitVector;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* Modbus/TCP Master facade.
*
* @author Dieter Wimberger
* @version @version@ (@date@)
*/
public class ModbusTCPMaster {
private TCPMasterConnection m_Connection;
private InetAddress m_SlaveAddress;
private ModbusTCPTransaction m_Transaction;
private ReadCoilsRequest m_ReadCoilsRequest;
private ReadInputDiscretesRequest m_ReadInputDiscretesRequest;
private WriteCoilRequest m_WriteCoilRequest;
private WriteMultipleCoilsRequest m_WriteMultipleCoilsRequest;
private ReadInputRegistersRequest m_ReadInputRegistersRequest;
private ReadMultipleRegistersRequest m_ReadMultipleRegistersRequest;
private WriteSingleRegisterRequest m_WriteSingleRegisterRequest;
private WriteMultipleRegistersRequest m_WriteMultipleRegistersRequest;
private boolean m_Reconnecting = false;
/**
* Constructs a new master facade instance for communication
* with a given slave.
*
* @param addr an internet address as resolvable IP name or IP number,
* specifying the slave to communicate with.
*/
public ModbusTCPMaster(String addr) {
try {
m_SlaveAddress = InetAddress.getByName(addr);
m_Connection = new TCPMasterConnection(m_SlaveAddress);
m_ReadCoilsRequest = new ReadCoilsRequest();
m_ReadInputDiscretesRequest = new ReadInputDiscretesRequest();
m_WriteCoilRequest = new WriteCoilRequest();
m_WriteMultipleCoilsRequest = new WriteMultipleCoilsRequest();
m_ReadInputRegistersRequest = new ReadInputRegistersRequest();
m_ReadMultipleRegistersRequest = new ReadMultipleRegistersRequest();
m_WriteSingleRegisterRequest = new WriteSingleRegisterRequest();
m_WriteMultipleRegistersRequest = new WriteMultipleRegistersRequest();
} catch (UnknownHostException e) {
throw new RuntimeException(e.getMessage());
}
}//constructor
/**
* Constructs a new master facade instance for communication
* with a given slave.
*
* @param addr an internet address as resolvable IP name or IP number,
* specifying the slave to communicate with.
* @param port the port the slave is listening to.
*/
public ModbusTCPMaster(String addr, int port) {
this(addr);
m_Connection.setPort(port);
}//constructor
/**
* Connects this <tt>ModbusTCPMaster</tt> with the slave.
*
* @throws Exception if the connection cannot be established.
*/
public void connect()
throws Exception {
if (m_Connection != null && !m_Connection.isConnected()) {
m_Connection.connect();
m_Transaction = new ModbusTCPTransaction(m_Connection);
m_Transaction.setReconnecting(m_Reconnecting);
}
}//connect
/**
* Disconnects this <tt>ModbusTCPMaster</tt> from the slave.
*/
public void disconnect() {
if (m_Connection != null && m_Connection.isConnected()) {
m_Connection.close();
m_Transaction = null;
}
}//disconnect
/**
* Sets the flag that specifies whether to maintain a
* constant connection or reconnect for every transaction.
*
* @param b true if a new connection should be established for each
* transaction, false otherwise.
*/
public void setReconnecting(boolean b) {
m_Reconnecting = b;
if (m_Transaction != null) {
m_Transaction.setReconnecting(b);
}
}//setReconnecting
/**
* Tests if a constant connection is maintained or if a new
* connection is established for every transaction.
*
* @return true if a new connection should be established for each
* transaction, false otherwise.
*/
public boolean isReconnecting() {
return m_Reconnecting;
}//isReconnecting
/**
* Reads a given number of coil states from the slave.
* <p/>
* Note that the number of bits in the bit vector will be
* forced to the number originally requested.
*
* @param unitid
* @param ref the offset of the coil to start reading from.
* @param count the number of coil states to be read.
* @return a <tt>BitVector</tt> instance holding the
* received coil states.
* @throws ModbusException if an I/O error, a slave exception or
* a transaction error occurs.
*/
public synchronized BitVector readCoils(int unitid, int ref, int count)
throws ModbusException {
m_ReadCoilsRequest.setUnitID(unitid);
m_ReadCoilsRequest.setReference(ref);
m_ReadCoilsRequest.setBitCount(count);
m_Transaction.setRequest(m_ReadCoilsRequest);
m_Transaction.execute();
BitVector bv = ((ReadCoilsResponse) m_Transaction.getResponse()).getCoils();
bv.forceSize(count);
return bv;
}//readCoils
/**
* Writes a coil state to the slave.
*
* @param unitid the slave unit id.
* @param ref the offset of the coil to be written.
* @param state the coil state to be written.
* @return the state of the coil as returned from the slave.
* @throws ModbusException if an I/O error, a slave exception or
* a transaction error occurs.
*/
public synchronized boolean writeCoil(int unitid, int ref, boolean state)
throws ModbusException {
m_WriteCoilRequest.setUnitID(unitid);
m_WriteCoilRequest.setReference(ref);
m_WriteCoilRequest.setCoil(state);
m_Transaction.setRequest(m_WriteCoilRequest);
m_Transaction.execute();
return ((WriteCoilResponse) m_Transaction.getResponse()).getCoil();
}//writeCoil
/**
* Writes a given number of coil states to the slave.
* <p/>
* Note that the number of coils to be written is given
* implicitly, through {@link BitVector#size()}.
*
* @param ref the offset of the coil to start writing to.
* @param coils a <tt>BitVector</tt> which holds the coil states to be written.
* @throws ModbusException if an I/O error, a slave exception or
* a transaction error occurs.
*/
public synchronized void writeMultipleCoils(int unitid, int ref, BitVector coils)
throws ModbusException {
m_WriteMultipleCoilsRequest.setUnitID(unitid);
m_WriteMultipleCoilsRequest.setReference(ref);
m_WriteMultipleCoilsRequest.setCoils(coils);
m_Transaction.setRequest(m_WriteMultipleCoilsRequest);
m_Transaction.execute();
}//writeMultipleCoils
/**
* Reads a given number of input discrete states from the slave.
* <p/>
* Note that the number of bits in the bit vector will be
* forced to the number originally requested.
*
* @param ref the offset of the input discrete to start reading from.
* @param count the number of input discrete states to be read.
* @return a <tt>BitVector</tt> instance holding the received input discrete
* states.
* @throws ModbusException if an I/O error, a slave exception or
* a transaction error occurs.
*/
public synchronized BitVector readInputDiscretes(int unitid, int ref, int count)
throws ModbusException {
m_ReadInputDiscretesRequest.setUnitID(unitid);
m_ReadInputDiscretesRequest.setReference(ref);
m_ReadInputDiscretesRequest.setBitCount(count);
m_Transaction.setRequest(m_ReadInputDiscretesRequest);
m_Transaction.execute();
BitVector bv = ((ReadInputDiscretesResponse) m_Transaction.getResponse()).getDiscretes();
bv.forceSize(count);
return bv;
}//readInputDiscretes
/**
* Reads a given number of input registers from the slave.
* <p/>
* Note that the number of input registers returned (i.e. array length)
* will be according to the number received in the slave response.
*
* @param ref the offset of the input register to start reading from.
* @param count the number of input registers to be read.
* @return a <tt>InputRegister[]</tt> with the received input registers.
* @throws ModbusException if an I/O error, a slave exception or
* a transaction error occurs.
*/
public synchronized InputRegister[] readInputRegisters(int unitid, int ref, int count)
throws ModbusException {
m_ReadInputRegistersRequest.setUnitID(unitid);
m_ReadInputRegistersRequest.setReference(ref);
m_ReadInputRegistersRequest.setWordCount(count);
m_Transaction.setRequest(m_ReadInputRegistersRequest);
m_Transaction.execute();
return ((ReadInputRegistersResponse) m_Transaction.getResponse()).getRegisters();
}//readInputRegisters
/**
* Reads a given number of registers from the slave.
* <p/>
* Note that the number of registers returned (i.e. array length)
* will be according to the number received in the slave response.
*
* @param ref the offset of the register to start reading from.
* @param count the number of registers to be read.
* @return a <tt>Register[]</tt> holding the received registers.
* @throws ModbusException if an I/O error, a slave exception or
* a transaction error occurs.
*/
public synchronized Register[] readMultipleRegisters(int unitid, int ref, int count)
throws ModbusException {
m_ReadMultipleRegistersRequest.setUnitID(unitid);
m_ReadMultipleRegistersRequest.setReference(ref);
m_ReadMultipleRegistersRequest.setWordCount(count);
m_Transaction.setRequest(m_ReadMultipleRegistersRequest);
m_Transaction.execute();
return ((ReadMultipleRegistersResponse) m_Transaction.getResponse()).getRegisters();
}//readMultipleRegisters
/**
* Writes a single register to the slave.
*
* @param ref the offset of the register to be written.
* @param register a <tt>Register</tt> holding the value of the register
* to be written.
* @throws ModbusException if an I/O error, a slave exception or
* a transaction error occurs.
*/
public synchronized void writeSingleRegister(int unitid, int ref, Register register)
throws ModbusException {
m_WriteSingleRegisterRequest.setUnitID(unitid);
m_WriteSingleRegisterRequest.setReference(ref);
m_WriteSingleRegisterRequest.setRegister(register);
m_Transaction.setRequest(m_WriteSingleRegisterRequest);
m_Transaction.execute();
}//writeSingleRegister
/**
* Writes a number of registers to the slave.
*
* @param ref the offset of the register to start writing to.
* @param registers a <tt>Register[]</tt> holding the values of
* the registers to be written.
* @throws ModbusException if an I/O error, a slave exception or
* a transaction error occurs.
*/
public synchronized void writeMultipleRegisters(int unitid, int ref, Register[] registers)
throws ModbusException {
m_WriteMultipleRegistersRequest.setUnitID(unitid);
m_WriteMultipleRegistersRequest.setReference(ref);
m_WriteMultipleRegistersRequest.setRegisters(registers);
m_Transaction.setRequest(m_WriteMultipleRegistersRequest);
m_Transaction.execute();
}//writeMultipleRegisters
}//class ModbusTCPMaster