How to Map 32 bit data in Deltav

Dear All,

I want to check the bit value of all bit for the 32 bit data in DeltaV which is coming through serial connection. 

as in case in 16 bit register we get the values at the OUT_D of BFI block. 

17 Replies

  • You must subtract or remove the first 16 bits. The result will then be sent to a bfo. You can remove the first 16 by subtracting 65536 from the value, take the absolute value, then send the value to the in_d of the bfo. Don't use the Out# of the calc block to wire the value, as this will convert the value to a float and risk precision loss.

    You can also use the Rol/Ror/Shr/Shl functions to roll or shift the bits, but I've never used them.

     

    Youssef El-Bahtimy | Systems Integration Technologist
    PROCONEX | 103 Enterprise Drive | Royersford, PA 19468 USA
    Proconex Office: 610 495 2970 | Cell: 267 275 7513
    Youssef.El-Bahtimy@ProconexDirect.com
     
  • In reply to IntuitiveNeil:

    Sorry I may have misunderstood the requirement, you're not trying to convert to float, just extract the individual bits from the top 16 bits of a 32 bit word. The code at that link shows the SHR function in use.

    If we imagine the 32 bit integer parameter is called 32BITIN, and the input parameter connected to input of the first BFO called LOW16BITS and the input parameter connected to the second BFO called HIGH16BITS.

    You'll need to perform a bitwise and mask of  0000FFFF hex against the 32 bit input number and store that in a register for input to the first 16 bit BFO. Then shift the top 16 bits into the bottom 16 bits position.

    Your code would be

    LOW16BITS := 32BITIN & 65535;

    HIGH16BITS := SHR (32BITIN, 16)

    Parameters LOW16BITS and HIGH16BIT should be unsigned integers type.

  • In reply to IntuitiveNeil:

    I recently had to implement this and one gotchya I came up against was that the IN1 of your calc block won't handle your 32-bit integer, so make sure your 32BITIN (per IntuitiveNeil's solution) is directly referencing the 32-bit parameter or you will lose precison and get incorrect results. Unless you tested every bit, it would be possible to think you have it working when in fact some of the 32 outputs will not be correct.

    To make your FBD look nicer, you could even still connect the 32-bit input parameter to IN1 of your calc block, but in the calc block explain with a comment why IN1 is not used so as to not create confusion.

  • I forgot to mention the calc in# as well. We recently had to track down floating point conversion and loss of large integer sensitivity. As an additional statement, I believe we saw that performing any arithmetic function with a calc in which the other operands are floats causes the result to also be cast as a float, regardless of whether you address the assignment outside of the calc. 

  • In reply to Youssef.El-Bahtimy:

    The CALC block IN and OUT parameters are Float type.  DeltaV automatically converts wired connections to Floats, and as mentioned above, 32 bit integers lose precision.  A Float uses a 22 Bit mantissa (resolution of the floating point number), so it can handle 16 Bit integers.  However, if you looked at the IN parameter for bit wise operation, it would not be the same as the original 16 BIT integer.  

    The code presented by IntuitiveNeil would not work if you used internal parameters, so the code should look like:

    '^/LOW16BITS' := '^/32BITIN' & 65535;

    '^/HIGH16BITS' := SHR ('^/32BITIN', 16)

    Internal parameters in a CALC block will be floating points, so you need to store your intermediate integer values in declared parameters outside the CALC block, defined as the desired variable data type.

    I don't think you can declare CALC variables to be a particular data type, and they are all Floating Point.  If that's not the case, would be happy to see a post that explains how to declare a variable as 32 Bit integer.  Otherwise, parameters need to be used of the desired data type.

    Andre Dicaire

  • In reply to Andre Dicaire:

    I agree with Andre on this.  Minimize the transactions with the 32 bit integer in the calc block.  I dug up my code from when I had to do this and turns out I did use SHR afterall.

    '^/BFO2/IN_INT.CV' := SHR('^/INT32_SELECT.CV',16);

    Where INT32_SELECT is a 32bit integer.

  • In reply to Youssef.El-Bahtimy:

    This would also apply to the 32 bit control word?
  • hello, could you give me a hand for a matter? I tried to use could the same setup on my sartorius interface for Profibus. www.geass.com/.../Manuale-trasmettitore-peso-PR5211-en.pdf
    i have a similar problem where the device called pr-5210/11 sends its data packed on a 32 word bit (pages 58 and 59 from the document).
    Could you please help me on this?
  • You have 32 bit (Boolean) and you need to writing on BFI blocks? or it's 32 bit unsigned integer and you need to writing on BFO blocks?

    1- Map 32 bit (Boolean) on BFI blocks:

    The result of the OUT_D of BFI block is calculated as follows:

    OUT_INT = IN1 x (2)^0 + IN2 x (2)^1 + IN3 x (2)^2 + IN4 x (2)^3 + IN5 x (2)^4 + IN6 x (2)^5 + ........  + IN16 x (2)^15

    For example:

    if IN1 = 1 and  IN2 to IN16 = 0, OUT_INT = 1 x (2)^0 = 1

    if IN1 and IN2 = 1 and IN3 to IN16 = 0, OUT_INT = 1 x (2)^0 + 1 x (2)^01 = 1 + 2 = 3

    You can do an equation for the 32 bits in a CALC block .

    1- Map 32 bit (unsigned integer) on BFO blocks:

    The link below for Application Exchange is for different conversion:

    https://deltav.com/Appsnew/application.asp?subid=243

  • In reply to Nabil BOU:

    As a suggestion to anyone who might use the code above, execution order is important to the efficient running of a module. Right now the blocks are executing backwards, so it would take 3 scans of the module to get the updated data out the BFO blocks. Just something to keep in mind whenever designing a new control strategy. Generally blocks should execute left to write and all your interconnecting lines on the forward path should be solid indicating that they are all executing in a sequenctial order.

    Thanks,
    Matt
  • In reply to Nabil BOU:

    I appreciate the contributions of people like yourself, Nabil. One correction I will offer for others' clarity is that the BFI output parameter you are referring to for the calculation would be OUT_INT, not OUT_D. Any parameter that ends in "..._D" is generally a Boolean or discrete value. In this case, if any of the INx bits are TRUE, OUT_D would be TRUE. If they're all FALSE, then OUT_D will be FALSE.
  • In reply to Brent Hamilton:

    actually I mis-understood the requirements, i have to split the 32Dint to 4 8-byte integers.
    Could someone tell me how?
  • In reply to stamate_mircea:

    The solution above still applies. You need a CALC Expression, and four destination parameters that you create as either Discrete with Status or 8 bit Integer unsigned. You can also add an external reference parameter to point to your source 32 bit word.

    INTE32_REF - external reference parameter in the module used to retrieve source 32 bit word
    INT8_A - 8 bit integer for least significant 8 bits (1 to 8)
    INT8_B - 8 bit integer for next 8 bits (9 to 16)
    INT8_C - 8 bit integer for penultimate significant 8 bits (17 to 24)
    INT8_D - 8 bit integer for most significant 8 bits (25 to 32)



    '^/INT8_A.CV' := '^/INT32_REF.CV' & 255 ; rem Bitwise and to that masks all but 8 least significant bits.
    '^/INT8_B.CV' := SHR('^/INT32_REF.CV',8)& 255 ; rem Shift word to get next 8 bit word in least significant location.
    '^/INT8_C.CV' := SHR('^/INT32_REF.CV',16)& 255 ; rem Shift word to get next 8 bit word in least significant location.
    '^/INT8_D.CV' := SHR('^/INT32_REF.CV',24)& 255 ; rem Shift word to get next 8 bit word in least significant location.

    Note that for the last shift, the bitwise AND is not needed as the 24 bits will be padded with zero's.

    Do not wire the source 32bit parameter via the Calc BLOCK "IN" parameters as this will convert the 32 bit word to a Floating point, and applying the Bitwise operators will result in unexpected values. By using defined module level parameters in the expression, the values remain as integers and there is no parameter conversion.

    Andre Dicaire

  • In reply to Andre Dicaire:

    Thank you mr Andre Dicaire. Could you tell me how to do it also the reverse of it (meaning to cumulate the 4 8 bit integers in one 32 dint?