You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2020/09/26 15:52:42 UTC

[plc4x] 04/10: Modbus Write Extended Register Support

This is an automated email from the ASF dual-hosted git repository.

cdutz pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 4c7521693d3b5efbcc8801595fc205743aadac04
Author: hutcheb <be...@gmail.com>
AuthorDate: Tue Sep 22 06:47:55 2020 -0400

    Modbus Write Extended Register Support
---
 .../java/modbus/protocol/ModbusProtocolLogic.java  | 30 +++++++++++++++++++++-
 .../main/resources/protocols/modbus/modbus.mspec   |  8 +++---
 2 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/protocol/ModbusProtocolLogic.java b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/protocol/ModbusProtocolLogic.java
index d28a86a..75078af 100644
--- a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/protocol/ModbusProtocolLogic.java
+++ b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/protocol/ModbusProtocolLogic.java
@@ -240,7 +240,7 @@ public class ModbusProtocolLogic extends Plc4xProtocolBase<ModbusTcpADU> impleme
             short group2_file_number;
             ModbusPDUReadFileRecordRequestItem[] itemArray;
 
-            if ((group1_address + extendedRegister.getLengthWords()) < FC_EXTENDED_REGISTERS_FILE_RECORD_LENGTH) {
+            if ((group1_address + extendedRegister.getLengthWords()) <= FC_EXTENDED_REGISTERS_FILE_RECORD_LENGTH) {
               //If request doesn't span file records, use a single group
               group1_quantity = extendedRegister.getLengthWords();
               ModbusPDUReadFileRecordRequestItem group1 = new ModbusPDUReadFileRecordRequestItem((short) 6, group1_file_number, group1_address, group1_quantity);
@@ -268,6 +268,34 @@ public class ModbusProtocolLogic extends Plc4xProtocolBase<ModbusTcpADU> impleme
             ModbusFieldHoldingRegister holdingRegister = (ModbusFieldHoldingRegister) field;
             return new ModbusPDUWriteMultipleHoldingRegistersRequest(holdingRegister.getAddress(),
                 holdingRegister.getLengthWords(), fromPlcValue(plcValue));
+        } else if(field instanceof ModbusExtendedRegister) {
+            ModbusExtendedRegister extendedRegister = (ModbusExtendedRegister) field;
+            int group1_address = extendedRegister.getAddress() % FC_EXTENDED_REGISTERS_FILE_RECORD_LENGTH;
+            int group2_address = 0;
+            int group1_quantity, group2_quantity;
+            byte[] plcValue1, plcValue2;
+            short group1_file_number = (short) (Math.floor(extendedRegister.getAddress() / FC_EXTENDED_REGISTERS_FILE_RECORD_LENGTH) + 1);
+            short group2_file_number;
+            ModbusPDUWriteFileRecordRequestItem[] itemArray;
+
+            if ((group1_address + extendedRegister.getLengthWords()) <= FC_EXTENDED_REGISTERS_FILE_RECORD_LENGTH) {
+              //If request doesn't span file records, use a single group
+              group1_quantity = extendedRegister.getLengthWords();
+              ModbusPDUWriteFileRecordRequestItem group1 = new ModbusPDUWriteFileRecordRequestItem((short) 6, group1_file_number, group1_address, fromPlcValue(plcValue));
+              itemArray = new ModbusPDUWriteFileRecordRequestItem[] {group1};
+            } else {
+              //If it doesn span a file record. e.g. 609998[10] request 2 words in first group and 8 in second.
+              group1_quantity = FC_EXTENDED_REGISTERS_FILE_RECORD_LENGTH - group1_address;
+              group2_quantity = extendedRegister.getLengthWords() - group1_quantity;
+              group2_file_number = (short) (group1_file_number + 1);
+
+              plcValue1 = ArrayUtils.subarray(fromPlcValue(plcValue), 0, group1_quantity);
+              plcValue2 = ArrayUtils.subarray(fromPlcValue(plcValue), group1_quantity, fromPlcValue(plcValue).length);
+              ModbusPDUWriteFileRecordRequestItem group1 = new ModbusPDUWriteFileRecordRequestItem((short) 6, group1_file_number, group1_address, plcValue1);
+              ModbusPDUWriteFileRecordRequestItem group2 = new ModbusPDUWriteFileRecordRequestItem((short) 6, group2_file_number, group2_address, plcValue2);
+              itemArray = new ModbusPDUWriteFileRecordRequestItem[] {group1, group2};
+            }
+            return new ModbusPDUWriteFileRecordRequest(itemArray);
         }
         throw new PlcRuntimeException("Unsupported write field type " + field.getClass().getName());
     }
diff --git a/protocols/modbus/src/main/resources/protocols/modbus/modbus.mspec b/protocols/modbus/src/main/resources/protocols/modbus/modbus.mspec
index 99c019a..339069b 100644
--- a/protocols/modbus/src/main/resources/protocols/modbus/modbus.mspec
+++ b/protocols/modbus/src/main/resources/protocols/modbus/modbus.mspec
@@ -256,16 +256,16 @@
     [simple     uint 8     'referenceType']
     [simple     uint 16    'fileNumber']
     [simple     uint 16    'recordNumber']
-    [implicit   uint 16    'recordLength'   '(COUNT(recordData) * 2) / 2']
-    [array      uint 16    'recordData'     length  'recordLength * 2']
+    [implicit   uint 16    'recordLength'   'COUNT(recordData) / 2']
+    [array      int 8      'recordData'     length  'recordLength']
 ]
 
 [type 'ModbusPDUWriteFileRecordResponseItem'
     [simple     uint 8     'referenceType']
     [simple     uint 16    'fileNumber']
     [simple     uint 16    'recordNumber']
-    [implicit   uint 16    'recordLength'   '(COUNT(recordData) * 2) / 2']
-    [array      uint 16    'recordData'     length  'recordLength * 2']
+    [implicit   uint 16    'recordLength'   'COUNT(recordData) / 2']
+    [array      int 8      'recordData'     length  'recordLength']
 ]
 
 [dataIo 'DataItem' [uint 8 'dataType', uint 8 'numberOfValues']