BinEnc Expression Function Not Working as Documented

Hi,

I wanted to convert an array of booleans to Integer or Long using the binEnc functions to handle alarms in one value using the bit state.

binEnc fails to handle more than 31 bits when the value is higher than 2147483647 (Int8).

It does not work for Integer nor with Long datatype on the tag.


Here is the UDT example

{
  "name": "BooleanArrayAlarm",
  "parameters": {
    "Tag": {
      "dataType": "String"
    }
  },
  "tagType": "UdtType",
  "tags": [
    {
      "opcItemPath": {
        "bindType": "parameter",
        "binding": "{Tag}"
      },
      "valueSource": "memory",
      "dataType": "BooleanArray",
      "name": "BooleanArray",
      "value": [
        false,
        false,
        false,
        false,
        false,
        false,
        false,
        false,
        false,
        false,
        false,
        false,
        false,
        false,
        false,
        false,
        false,
        false,
        false,
        false,
        false,
        false,
        false,
        false,
        false,
        false,
        false,
        false,
        false,
        false,
        false,
        false
      ],
      "tagType": "AtomicTag",
      "opcServer": "Ignition OPC UA Server"
    },
    {
      "valueSource": "expr",
      "expression": "binEnc(\r\n\t{[.]BooleanArray}[0],\r\n\t{[.]BooleanArray}[1],\r\n\t{[.]BooleanArray}[2],\r\n\t{[.]BooleanArray}[3],\r\n\t{[.]BooleanArray}[4],\r\n\t{[.]BooleanArray}[5],\r\n\t{[.]BooleanArray}[6],\r\n\t{[.]BooleanArray}[7],\r\n\t{[.]BooleanArray}[8],\r\n\t{[.]BooleanArray}[9],\r\n\t{[.]BooleanArray}[10],\r\n\t{[.]BooleanArray}[11],\r\n\t{[.]BooleanArray}[12],\r\n\t{[.]BooleanArray}[13],\r\n\t{[.]BooleanArray}[14],\r\n\t{[.]BooleanArray}[15],\r\n\t{[.]BooleanArray}[16],\r\n\t{[.]BooleanArray}[17],\r\n\t{[.]BooleanArray}[18],\r\n\t{[.]BooleanArray}[19],\r\n\t{[.]BooleanArray}[20],\r\n\t{[.]BooleanArray}[21],\r\n\t{[.]BooleanArray}[22],\r\n\t{[.]BooleanArray}[23],\r\n\t{[.]BooleanArray}[24],\r\n\t{[.]BooleanArray}[25],\r\n\t{[.]BooleanArray}[26],\r\n\t{[.]BooleanArray}[27],\r\n\t{[.]BooleanArray}[28],\r\n\t{[.]BooleanArray}[29],\r\n\t{[.]BooleanArray}[30],\r\n\t{[.]BooleanArray}[31]\r\n)\r\n",
      "dataType": "Int4",
      "name": "Integer",
      "tagType": "AtomicTag"
    }
  ]
}

Looks like it's working to me. all bits on = -1 when using a signed integer which is what you have.

2 Likes

After testing the alarm on bit 32 it does work as expected. Thanks for clarifying.

Also, remember that binEnc() also swaps the order so that the Most Significant bit is the last argument, as opposed to the first.

So binEnc(0,0,1,0) results in 4, and not 2 as you might expect.

2 Likes

Personally, it works as I would expect, as I wouldn't think nor want the first argument to be bit 31.

1 Like

I don't disagree, but I've had to answer many questions about why something wasn't the number expected when it was because they were reading the values as a traditionally printed binary number, instead of reversed.

Just a note because it can really trip some people up.

2 Likes

Hey Michael,

I've tried to use the bit state mode on an alarm on an encoded Long value but it does not seem to work after the 32 bits. So far, Bit State Mode only works for 32 bits due to the signed value I guess.

Any thoughts?

The manual states that binEnc() will accept up to 64 arguments.

What does "does not seem to work" actually mean?

What result did you expect and what result did you actually get?

In the documentation it says bit state works with integers. While I didn't see it explicitly call out a 32 bit integer, the integer datatype is only 32 bits.

1 Like

Yeah, I think this is the key info here. While binEnc() can take up to 64 arguments. For alarm handling one can only evaluate 32 bits hence limiting the great functionality of encoding 64bits.

@lrose if you try to evaluate above 32 bits on an alarm using bit state mode it won't trigger the alarm.

Thanks both

I've never needed 64-bits for my alarms, plus I do all of my alarm bit packing in the PLC when I do use it, and even though the PLC supports 64-bit, I only use 32-bit integers because that's all I've ever needed. In your case I would just split out the bits to 2 separate 32-bit integers (or why not just put the alarms directly on the tags you're bit packing and skip the bit packing all together).

Edit: Although if your data is an actual array, I don't know that you'll be able to alarm on the individual elements, but didn't know if that was just an example you were using for this post.

I love Ignition's flexibility.

2 separate 32-bit integers work but given the current state of the PLC code with many arrays of different lengths, I decided to go for a UDT with individual reference tags, each with one alarm. It allows me to script any array from an alarm list quickly. I am working with someone else's code.