Hi Myhong (Hope that's correct)

First of all, welcome to our cool project ... I hope you'll like it here and 
become a regular contributor ;-)

Regarding BOOL[2] getting the last two bits of two registers is definitely not 
the way it should be. It should be returning the last two bits of one register 
and only span to the next if reading more than 8. We should probably track this 
in an issue and fix it (if you've already got an idea ... PRs are always 
welcome :-))

However not 100% sure how we should generally do this. Perhaps [1] should 
return the first bit and add lesser significant bits as the array grows. I 
think I did it the way it's currently implemented, as when using registers to 
store Boolean values I usually store 0 and 1 in them. 

Other protocols (s7) have the concept of a bit-address. Perhaps artificially 
extending the modbus protocol with this concept would be an option.

Taking your example:

400006.1:BOOL[2]

Could then read two bits starting at the second-most significant bit.

0XX00000 00000000

Would that work for you? But in that case we probably should invert how we read 
"BOOL" from interpreting:

00000000 000000001 as true to 10000000 00000000

But not sure on how this would break other options.

Chris


-----Original Message-----
From: 洪锦琳 <[email protected]> 
Sent: Freitag, 22. April 2022 10:16
To: [email protected]
Subject: Reads of type bool have different results

Hello everyone!
First, thanks to Chris for his reply in my PR, so here I am!

Issue:
1 When I read 400006:BOOL[1], it will get the last bit of 400006(2bytes).
Here is the source code:
github.com/apache/plc4x/plc4go/internal/plc4go/modbus/readwrite/model/DataItem.go

case dataType == ModbusDataType_BOOL && numberOfValues == uint16(1): // BOOL
   // Reserved Field (Just skip the bytes)
   if _, _err := readBuffer.ReadUint16("reserved", 15); _err != nil {
      return nil, errors.Wrap(_err, "Error parsing reserved field")
   }

   // Simple Field (value)
   value, _valueErr := readBuffer.ReadBit("value")
   if _valueErr != nil {
      return nil, errors.Wrap(_valueErr, "Error parsing 'value' field")
   }
   readBuffer.CloseContext("DataItem")
   return values.NewPlcBOOL(value), nil


2 When I read 400006:BOOL[2], I get 400006 and 400007, the first two bits of a 
total of 4 bytes.
Source code:
github.com/apache/plc4x/plc4go/internal/plc4go/modbus/readwrite/model/DataItem.go

case dataType == ModbusDataType_BOOL: // List
   // Array Field (value)
   var value []api.PlcValue
   for i := 0; i < int(numberOfValues); i++ {
      _item, _itemErr := readBuffer.ReadBit("value")
      if _itemErr != nil {
         return nil, errors.Wrap(_itemErr, "Error parsing 'value' field")
      }
      value = append(value, values.NewPlcBOOL(_item))
   }
   readBuffer.CloseContext("DataItem")
   return values.NewPlcList(value), nil

I thought it was 400006:BOOL[1] to get the 2nd bit of 400006, but the "[1]"
match in the regular is "quantity". So, I'm not sure how to fix this problem 
correctly. Let's discuss it here.
github.com/apache/plc4x/plc4go/internal/plc4go/modbus/FieldHandler.go

generalFixedDigitAddressPattern :=
`(?P<address>\d{4,5})?(:(?P<datatype>[a-zA-Z_]+))?(\[(?P<quantity>\d+)])?$`

Reply via email to