文章實現 Modbus slave app , 用 serial rtu 傳輸, 代碼只實現監聽功能(本人測試可行), 要實現寫功能,可研究一下代碼中 updateProcessImage 方法。完整代碼(先閱讀 README.md ) :http://git.oschina.net/jlpostbox/demo-modbusjava
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轉換git
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; }