Features, discussions, tips, tricks, questions, problems and feedback

Ulong(4word) combine in one tag


I have register in energy meter which is Ulon(4 word),
MAPS doses not have to read this type of value.
How could I combine 2 dint in expression agents.


I don’t think this would be possible as it’s 32 bit application. You would need 64 bit version to achieve that or make your own bit-wise logic using scripts

Hi Colban, this is an interesting question and not a simple answer.

Adroit 10.x , Map 4.x does support greater than 32 bit value types but not exactly 64bit integer types.

Integer/Marshal/Arec agents can hold a LONG 32bit and ULONG 32bit.

Which is a maximum of 4 bytes

Real/Analog agents and many others can hold double precision float data (FLOAT64)

Which is maximum of 8 bytes consisting of 1 bit for sign, 11 bits for exponent and 52 bits for mantissa.

Single precision floats (Float32) can be accurately held in a double precision float.

Double precision floats can accurately hold an integer up to 0x0020 0000 0000 0000 hex. (Notice the most significant 12 bits are excluded. An ever-increasing Precision error will be noted as the INT value increments to greater 2^52 is stored in a FLOAT64)

Now most drivers can read 16bit and 32bit registers containing either integers or single precision float data.

The expression output slot v99 is a double precision real slot.

Using either a script or an expression agent, we can combine the registers to form a compound value INT52.

Please note : Make sure the 4 registers are reported in the same driver Transaction/Job/Group, and more importantly it is recommended to trigger the expression or script on some external trigger source (say a timer) to prevent an error where evaluation takes place and 1 or more of the 4 registers did not get refreshed yet in the evaluation cycle which could cause a mismatched value error.

Another reason for an external trigger is some registers may not change and thus not cause a trigger. (For example, the most significant word (v01) may change, and the other (v02-v04) words do not change and say you were triggering on the least significant register(v04) this would result in a missed evaluation).

Another reason is if you trigger on any change of V01 through V04 , The driver even though the Registers would be best in the same transaction, deep down in the core of the server, the 4 updates to v01 through v04 would still occur individually at some point and thus could cause up to 4 triggers as each V01 through v04 input gets refreshed by the poll cycle.

So, for your supplied info above “Consumed Active Energy L1” Scanned at 00C8 and assuming 400001 is 0000 then 00C8 is 400201 (1 added for the offset)

A.value -> 00C8(400201) = 0x0001 Most significant WORD16

B.value -> 00C9(400202) = 0x0002

C.value -> 00CA(400203) = 0x0003

D.value -> 00CB(400204) = 0x0004 least significant WORD16

We can create an expression E to form a following ~INT64 (~ close enough to …) it is an INT52 (12 most significant bits removed)

E.rawvalue -> 0x0001 0002 0003 0004 hex (281483566841860 dec)

So, we need left shift each word to its new correct bit position in the new 64bit variable v99 we can achieve this multiplying out by value (as there is no 64bit left shifting available in the expression agent which only allows for a maximum of 32bit shifting)

So, add an expression called E

Browse in v01 -> A.value , v02 -> B.value , c03 -> C.value , v04 -> D.value

So the expression is :

  1. (V01 * 65536 * 65536 * 65536) + (V02 * 65536 * 65536) + (V03 * 65536) + V04

Where (left is more significant)

v01 << 48 (or the size of 3 words to the left (multiplication).

  • V02 << 32 ( 2 words left )

  • V03 << 16 (1 Word left )

  • V04 stays in position


Dear David,

Thank you so much, it is help us, it solved our problem.

Best Regards.