plc4x-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ben Hutcheson <ben.hut...@gmail.com>
Subject Re: [MODBUS][DISCUSS] Improving handling of datatypes ...
Date Tue, 08 Sep 2020 12:44:11 GMT
Hi Chris,

The case where PLC data types are mapped to 16 bit registers isn't a
special case, as the Modbus protocol only supports 16 bit registers but it
doesn't specify what format the data should be in,any PLC data type can be
mapped to these and then passed over Modbus. It would definitely be handy
to be able to convert any of the PLC datatypes back from Modbus 16-bit
registers to whatever datatype they should be. I've done some work already
on the specific case of mapping a Java String to the PLCInteger/PLCShort
classes and can expand it basing it off the S7 functions that do the same.
We can then look at the differences and consolidate them if possible?

However it would be great to be able to add unambiguous classes to
plc4j/api/src/main/java/org/apache/plc4x/java/api/value for each of the IEC
datatypes instead of these being based off Java types.

Using the same format as the S7 protocol the address string would be
holding-register:1000:REAL[10] instead though, I don't think this will
cause issues if we make it optional and default to INT or BOOL as required.

Kind Regards

Ben







On Tue, Sep 8, 2020 at 8:10 AM Christofer Dutz <christofer.dutz@c-ware.de>
wrote:

> Hi Ben ...
>
> Sorry for my email... I should really finish reading before replying :-(
>
> About your suggestion to add it to the type to the ModbusField ... I
> agree. But I would simply extend the Address string the same way the TIA
> addresses were extended.
> Cause the problem I'm seeing is that for the 61131 datatypes we can
> provide an enum, but not for any custom types the driver might be
> supporting. With a String we can keep it simple ... check if the type is a
> 61131 type -> if yes: do the default handling. If it's not, use some driver
> specific encoding/decoding.
>
> In my particular case the Float values were also 4 byte values ... I
> manually solved it by requesting 2 element arrays for every float address
> (The map of reigsters only used only even register numbers, so that
> worked). Then I manually converted the 2 x 2bytes into a 4byte float with
> this code:
>
>             // Decode the first 10 shorts as 32bit floats ...
>             StringBuilder sb = new StringBuilder();
>             for(int i = 0; i < 10; i++) {
>                 int short1 = value.getIndex(i * 2).getInteger();
>                 int short2 = value.getIndex((i * 2) + 1).getInteger();
>                 WriteBuffer wb = new WriteBuffer(4);
>                 wb.writeInt(16, short1);
>                 wb.writeInt(16, short2);
>                 final byte[] data = wb.getData();
>                 int intVal = (data[3] & 0xFF) | ((data[2] & 0xFF) << 8)
|
> ((data[1] & 0xFF) << 16) | ((data[0] & 0xFF) << 24);
>                 final float v1 = Float.intBitsToFloat(intVal);
>                 sb.append(v1).append(", ");
>             }
>
> Ok in this case I read 10 floats by reading an array of 20 registers.
> Guess it should be even simpler with 32bit integers
>
> But I guess it does the job ... not pretty, but it works and I would
> definitely love to have something similar in the drivers to handle this if
> I said "holding-register:1000[10]:REAL"
>
> Chris
>
>
> Am 08.09.20, 13:59 schrieb "Christofer Dutz" <christofer.dutz@c-ware.de>:
>
>     Hi Ben,
>
>     if you have followed the latest discussions here ... currently the
> modbus protocol supports 16bit integer values for registers and Boolean
> values for coils.
>     The protocol doesn't directly support anything else. However I have
> seen that vendors use arrays of registers to support higher level types. In
> my special case the PLC vendor used two 16bit integers to provide 32bit
> float values.
>
>     We will probably start adding support for the basic IEC 61131
> datatypes (https://en.wikipedia.org/wiki/IEC_61131-3) but I think this
> will only apply for the Bool, Bit-String, Signed and Unsigned Integers as
> well as Real values. Durations, Times, Dates and especially Strings will be
> problematic as it seems every vendor uses a different encoding of these.
>
>     Chris
>
>
>     Am 08.09.20, 13:52 schrieb "Ben Hutcheson" <ben.hutche@gmail.com>:
>
>         Hi,
>
>         Looking at the example I had with the hello-world-write example
> trying to
>         write a String to the Modbus protocol.
>
>         ava -jar plc4j-hello-world-plc4x-write-0.8.0-SNAPSHOT-uber-jar.jar
>         --connection-string modbus://127.0.0.1:5467 --field-addresses
> 40010
>         -field-values 32000
>
>         The value 32000 then gets cast as a String and is passed to the
>         encodeString function in ModbusFieldHandler. (It doesn't have one
> it gets
>         passed to the DefaultFieldHandler). To get this to work properly
> we would
>         need to define a datatype to cast the String to, S7 does this
> already and
>         with the consensus that IEC 61131 data types be used where
> possible then I
>         see no reason we shouldn't add the datatype field to the
> ModbusField. If we
>         are doing this for these protocols, then why don't we add the
> datatype
>         field to the PLCField interface, this would allow us to use the
> same
>         default encodeString (We may have to map the protocol specific
> datatypes to
>         IEC 61131 here, the same internalEncodeString might be better)
> functions
>         for S7 and Modbus by casting the input to a PLCField instead of a
> S7Field
>         or ModbusField.
>
>         When encodeString is then called we can use the datatype that is
> passed to
>         it to encode it to a PLCInteger/PLCFloat/etc.., the same way the S7
>         protocol does it. S7 however only allows Strings to be passed as
> string
>         related variables (CHAR, WCHAR, STRING and WSTRING), I don't see
> any reason
>         we can't expand this to be able to pass any PLC datatype from a
> string.
>
>         The next problem I had was to then be able to parse the PLCInteger
> class to
>         a byte array within the fromPLCValue function. For the UINT
> datatype for
>         the Modbus protocol, this is a 2 byte array however the PLCInteger
> class
>         contains it as a 4 byte array. in the fromPLCValue function there
> doesn't
>         seem to be a way to test to see if it is an UINT or a 4 byte
> integer such
>         as a DINT. If we were to change the classes in
>         plc4j/api/src/main/java/org/apache/plc4x/java/api/value to match
> the IEC
>         61131 datatypes then we should be able to parse them correctly in
> Modbus
>         fromPLCValue function.
>
>         I have probably missed a few things out, like how the
> TransportSize class
>         for the S7 protocol works, and we may have to settle for mapping
> protocol
>         specific types to IEC61131 types in the encode functions in each
> protocol,
>         what are your thoughts?
>
>         Kind Regards
>
>         Ben
>
>
>
>
>         On Sun, Sep 6, 2020 at 11:25 AM Christofer Dutz <
> christofer.dutz@c-ware.de>
>         wrote:
>
>         > Hi all,
>         >
>         > well I doubt that we could really centrally handle this.
>         > If you have an idea how to unify this, I'd be happy for a
> suggestion.
>         > I guess most will have to be handled in the individual drivers
> themselves.
>         >
>         > But I really would like all drivers to support the same base-set
> of
>         > datatypes.
>         >
>         > Chris
>         >
>         >
>         >
>         > Am 06.09.20, 17:02 schrieb "Cesar Garcia" <
> cesar.garcia@ceos.com.ve>:
>         >
>         >     Hello,
>         >
>         >     I think it can be applied from several points of view, the
> one
>         > typified as
>         >     you indicate (HREGISTER: REAL) or (HREGISTER [2]), each one
> has its
>         >     advantage.
>         >
>         >     To be able to handle the types indifferently (specifically
> between
>         > Modbus
>         >     and S7), I modify the field of the Modbus driver so that it
> strictly
>         > adapts
>         >     to the PLC4X API. This prevents the user's App from having
> to implement
>         >     code to interpret the content of the records.
>         >
>         >     This is implemented in version 0.6.1 of  PLC4X, but the new
> version is
>         >     something else.
>         >
>         >     Best regards,
>         >
>         >     El dom., 6 sept. 2020 a las 10:03, Ben Hutcheson (<
>         > ben.hutche@gmail.com>)
>         >     escribió:
>         >
>         >     > Hi,
>         >     >
>         >     > I ran into this issue this morning when using the
> hello-world-write
>         > example
>         >     > and trying to write to a Modbus connection. It looks like
> it assumed
>         > the
>         >     > input value is a string whereas the Modbus protocol
> doesn't have
>         > support
>         >     > for it yet.
>         >     >
>         >     > I was thinking about expanding
>         >     >
>         >     >
>         >
> github/plc4x/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/connection/DefaultPlcFieldHandler.java
>         >     > to include default handlers for the various IEEE 61131
> data types,
>         > the
>         >     > specific protocols can then override them as necessary?
>         >     >
>         >     > Kind Regards
>         >     >
>         >     > Ben
>         >     >
>         >     > On Wed, Sep 2, 2020 at 9:36 AM Christofer Dutz <
>         > christofer.dutz@c-ware.de>
>         >     > wrote:
>         >     >
>         >     > > Hi Julian,
>         >     > >
>         >     > > I agree ... if one driver would define an "INT" as 32bit
> integer
>         > and the
>         >     > > others would treat it as 16bit ... that could be a
> problem.
>         >     > > Perhaps having a statement of the project that we use
> the IEC
>         > 61131 types
>         >     > > as a basis and if you want to use a given protocols
> different
>         > types, that
>         >     > > you can prefix them ..
>         >     > >
>         >     > > Assuming a driver for the famous "HURZ" protocol would
> use 32bit
>         > INTs,
>         >     > > then an "INT" could reference the 16bit version and a
> "HURZ_INT"
>         > could be
>         >     > > the 32bit version?
>         >     > >
>         >     > > Chris
>         >     > >
>         >     > >
>         >     > >
>         >     > >
>         >     > > Am 02.09.20, 15:26 schrieb "Julian Feinauer" <
>         >     > > j.feinauer@pragmaticminds.de>:
>         >     > >
>         >     > >     Hi,
>         >     > >
>         >     > >     agree with your suggestion!
>         >     > >     Although we have to be careful to not mix it up with
> specific
>         >     > > implementations of datatypes in some drivers.
>         >     > >
>         >     > >     Julian
>         >     > >
>         >     > >     Am 02.09.20, 15:21 schrieb "Christofer Dutz" <
>         >     > > christofer.dutz@c-ware.de>:
>         >     > >
>         >     > >         Hi all,
>         >     > >
>         >     > >         today I was at a customer’s site and used the
> Modbus
>         > driver to
>         >     > get
>         >     > > data. This generally worked fine.
>         >     > >         The thing however I found a little complicated,
> was that
>         > the PLC
>         >     > > seemed to offer all values as 32Bit Floating point
> values.
>         >     > >         So in order to correctly read them, I had to
> read an array
>         > of two
>         >     > > consecutive shorts and then manually convert them into a
> float.
>         >     > >
>         >     > >         I bet we can do this better.
>         >     > >
>         >     > >         So I thought … how about we use the same
>         >     > > https://en.wikipedia.org/wiki/IEC_61131-3 datatypes we
> are
>         > already using
>         >     > > in other drivers and for example if you write:
>         >     > >
>         >     > >         holding-register:1:REAL
>         >     > >
>         >     > >         it would automatically use modbus to read an
> array of two
>         > shorts
>         >     > > and to internally convert these to one REAL/float.
>         >     > >
>         >     > >         What do you think? I think we could probably do
> this in
>         > most
>         >     > > drivers.
>         >     > >
>         >     > >         Chris
>         >     > >
>         >     > >
>         >     > >
>         >     > >
>         >     > >
>         >     >
>         >
>         >
>         >     --
>         >     *CEOS Automatización, C.A.*
>         >     *GALPON SERVICIO INDUSTRIALES Y NAVALES FA, C.A.,*
>         >     *PISO 1, OFICINA 2, AV. RAUL LEONI, SECTOR GUAMACHITO,*
>         >
>         >     *FRENTE A LA ASOCIACION DE GANADEROS,BARCELONA,EDO.
> ANZOATEGUI*
>         >     *Ing. César García*
>         >
>         >     *Cel: +58 414-760.98.95*
>         >
>         >     *Hotline Técnica SIEMENS: 0800 1005080*
>         >
>         >     *Email: support.aan.automation@siemens.com
>         >     <support.aan.automation@siemens.com>*
>         >
>         >
>
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message