文章实现 Modbus slave app , 用 serial rtu 传输, 代码只实现监听功能(本人测试可行), 要实现写功能,可研究一下代码中 updateProcessImage 方法。完整代码(先阅读 README.md ) :http://git.oschina.net/jlpostbox/demo-modbus
public static void main(String[] args) throws Exception { String commPortId = "COM2"; int baudRate = 9600; int flowControlIn = 0; int flowControlOut = 0; int dataBits = 8; int stopBits = 1; int parity = 0; SerialPortWrapperImpl wrapper = new SerialPortWrapperImpl(commPortId, baudRate, flowControlIn, flowControlOut, dataBits, stopBits, parity); ModbusFactory modbusFactory = new ModbusFactory(); final ModbusSlaveSet listener = modbusFactory.createRtuSlave(wrapper); // Add a few slave process images to the listener. listener.addProcessImage(getModscanProcessImage(1)); new Thread(new Runnable() { @Override public void run() { try { listener.start(); } catch (ModbusInitException e) { e.printStackTrace(); } } }).start(); }static class BasicProcessImageListener implements ProcessImageListener { @Override public void holdingRegisterWrite(int offset, short oldValue, short newValue) { System.out.println("HR at " + offset + " was set from " + oldValue + " to " + newValue); } } static BasicProcessImage getModscanProcessImage(int slaveId) { //创建10个可读写的数字类型,与主机对应 BasicProcessImage processImage = new BasicProcessImage(slaveId); processImage.setInvalidAddressValue(Short.MIN_VALUE); processImage.setHoldingRegister(0,(short) 8); processImage.setHoldingRegister(1,(short) 8); processImage.setHoldingRegister(2,(short) 8); processImage.setHoldingRegister(3,(short) 8); processImage.setHoldingRegister(4,(short) 8); processImage.setHoldingRegister(5,(short) 8); processImage.setHoldingRegister(6,(short) 8); processImage.setHoldingRegister(7,(short) 8); processImage.setHoldingRegister(8,(short) 8); processImage.setHoldingRegister(9,(short) 8); // Add an image listener. processImage.addListener(new BasicProcessImageListener()); return processImage; }
开发中遇到一个问题,short的取值是 -32768~32767 , 而对方发过来的是 0~65535 , 这样当发过来是32757~65535,java这边收到的是 -32768~ -1 , 我们就得利用Java位运算符,完成Unsigned转换
public int getUnsignedByte (byte data){ //将data字节型数据转换为0~255 (0xFF 即BYTE)。 return data&0x0FF;} public int getUnsignedByte (short data){ //将data字节型数据转换为0~65535 (0xFFFF 即 WORD)。 return data&0x0FFFF;} public long getUnsignedIntt (int data){ //将int数据转换为0~4294967295 (0xFFFFFFFF即DWORD)。 return data&0x0FFFFFFFFl;}