Logix 5000 instruction or method to clear / 0 out an array of bits

A few things need to be clearfied
when you say an array of bits
is it a bit array
an INT tag and aDINT tag are both arrays of bits
and for that matter a string tag is stores as anarray od bits
but the easisest way is to use for next loop
in a ladder program use the lable function to form the loop
one line of code


I have to disagree ....

SINT, INT, and DINT tags are not arrays of bits, and neither is a STRING tag.

To address a single bit within an integer tag, you just use the "dot delimiter", and not the [nnnn] array element specification. And you are limited to the number of bits you can address within each data-type by the physical size of the tag data, i.e. 8 for SINT, 16 for INT, and 32 for a DINT. To increase the number of bits available, you could use Arrays of the integer tags, but will then have to calculate the "word" address (i.e. the array pointer), and the bit offset into the target array element.

A STRING tag is a structured tag consisting of two elements, a LENgth DINT, and a SINT[82] array, so its use as bit storage will become very messy indeed.

Take notice that I have used the words "bit" and "bits" above, so as not to confuse with the BOOL data-type. A BOOL is not a single bit of data, but is in fact a tag that is allocated a 32-bit memory space for its data, where only bit 0 is used. A BOOL[nn] array, due to background optimisation by the compiler, will use as many 32-bit memory spaces as needed to store the number of bits you request in the array, e.g. if you create a BOOL[100] array, you will be given a BOOL[128] array, which is 4 x 32-bit words of data. This in itself may lead to complications since you may inadvertantly indirectly address one of the "unused" bits, 100 to 127, so error checking and careful programming may be required.

In summary, if you want to use a BOOL array, then go ahead and use one, but to make it usable by many instructions, parcel it up in a UDT as described. Clearing all of the bits in the BOOL array tag is then a simple case of using a single FLL instruction. However, while FLL will work, you MUST NOT put any other members to the UDT other than the BOOL array. Read the Help on FLL for an explanation why. In fact the help suggests that to intialise a structured tag you should use COP (or CPS) instead, which means you need an identical UDT tag that has the required data stored in it.

For the reasons given in FLL Help, I always use a SINT constant tag as the FLL Source specification, with No External Access, and initialised to 0 on first scan. Then I know that I am keeping everything "in bounds" and tidy.

In the attached code, "MyData" is a UDT tag of data-type "MyData", which contains a single BOOL array of 2048 bits. ZeroByte is the constant SINT tag, and the Length of the FLL is set to 1 (1 x number of bytes of the destination data-type, which is 256 bytes). Execution time of the FLL is sub 180 uSecs (the second GSV is around 20 uSecs, so I suspect about 160 uSecs.

No looping, no FOR instruction calling another routine 2048 times, no lumping backwards, just 1 instruction.

2021-07-08_090458.jpg
 
I just had to come back to this one

I have to disagree with daba
All data in a computer or PLC are no more than bit arrays the data type will define the array size

In a Logix 5000 processor
The original question was “I want zero out all the bits in a Bool Array”

When I read that question as phrased I see it as a load question.
Without more information or context, the data type has not been defined
A Boolean data type is a single bit

To help clearly that you need to go back to the beginning.
All data in a computer is stored and used are bits and as I think we all can agree a single bit can only have a value of 0 or 1 read as True or False
The data type tells the processor and us humans how to interpret the bits
The first computer used 4 bit words and they soon progressed to the standard 8 bit words we use today.
The Data Type and the pattern of the bits the give us the value of each word.
Word can be joined together to form data strings.
The old RS232 communication strings were an array or 8 bit words sent and received. These strings can be very long. In theory the length of the string can be unlimited
Now the Logix processor are all using 32 bit words while most modern processors use 64 bit words and to add to confusion they actually have developed 128 bit processors and I sure they are working on 256 bit processors or larger.
But let’s get back to the logix 5000 data types
Again as a reminder all data is stored as an array of bits
While ASCII data type is not directly recognized as data type it is used in a String data type.
The Default String Data type is an array of 80 ASCII charters, each charter is an array of 8 bits
But the total array of the string is 80 * 8 or 640 bits. The firmware knows how to handle this data because we have defined it as a Sting Data Type. We could define the tag as string array of many strings the tag could contain several thousand strings but they all would be part of a single string tag.

Data type
INT is 16 Bits
DINT is 32 Bits
LONG is 64 Bits ( If Used )
REAL is stored as a 32 bit word in Scientific notation but the processor Reads it is as Real value.
STRING was described above

Storing Real Numbers
We begin with a review of scientific notation. When we have to write very large or very small numbers, it is easier to write them in scientific notation. For example,
351,000,000,000 = 3.51 x 1011
and
.000000000124 = 1.24 x 10-10
Notice that we place the decimal point just to the right of the leftmost nonzero digit in the value. We call the leftmost nonzero digit the most significant digit. In the text the decimal point is placed to the left of the most significant digit, but we shall always put the decimal point to its right.
The form of a number in scientific notation is
n = f x 10e
where f is a signed fractional part called a mantissa and e is a signed integer exponent.

On older PLC’s they used Float data type they were stored as 2 16 bit words the first word is the
number above the decimal point and the second word is the number below the decimal point

But it really doesn’t matter the data type they are all stored as bits and each bit can be accessed individually with in the program.

To address the original question it looks like a single BOOL array tag.
There is only 2 ways to clear all the bits in the tag within the PLC program
1 Address each individual element in the tag array Unlatch Array(0) . Unlatch Array (1) ,Ect
2 create a FOR loop and step through each element in the array
For Index= 0 to (Array end -1 )
Unlatch Array(index)
Next index
In the case of ladder program use the label and JMP to Label
Reset Array ----- Clear Index
Lable1 ------index < (array end – 1) -----unlatch array(Index) ----- Index = index +1 ----- JMP to Label 1

But a much simpler solution is use an INT or DINT data type in place of the BOOL array and for each in place of the BOOL array and when setting the Bit just address them at the tag bit level array.0 , Array.1 Ect.
Then to clear them use the clear function this will set all the bits in the INT or DINT to zero

I have used both of the methods many times over the years going back to early PLC2 and have never had any problems.
Just open any Logix 5000 program and look at the data table , expand the data types
INT and DINT will expand to the Bits
Strings will expand out to each charter will be an 8 Bit array and you can expand each charter array to the bit level.


Although I do find that new programmer are a little confused with it a first but once they use it and understand it most end up using it.
Every individual bit can be accessed and set or cleared from the plc code sometimes you just need to think about it first.
 
..........

To address the original question it looks like a single BOOL array tag.
There is only 2 ways to clear all the bits in the tag within the PLC program
1 Address each individual element in the tag array Unlatch Array(0) . Unlatch Array (1) ,Ect
2 create a FOR loop and step through each element in the array
For Index= 0 to (Array end -1 )
Unlatch Array(index)
Next index
In the case of ladder program use the label and JMP to Label
Reset Array ----- Clear Index
Lable1 ------index < (array end – 1) -----unlatch array(Index) ----- Index = index +1 ----- JMP to Label 1

But a much simpler solution is use an INT or DINT data type in place of the BOOL array and for each in place of the BOOL array and when setting the Bit just address them at the tag bit level array.0 , Array.1 Ect.
Then to clear them use the clear function this will set all the bits in the INT or DINT to zero

........

A very detailed explanation of Logix5000 data-types, although I felt it was unnecessary to include at this juncture, as the OP wanted to clear all the bits in a BOOL array. And it did contain a slight error - there are 82 character SINTs to a STRING data-type, not 80 as you stated.

Now let us analyse the methods you advocate for clearing BOOL arrays :---

1. Use the bits of a SINT, INT, or DINT as a BOOL array. (Note you cannot use LINT for 64 bits).

Fine if your array size fits into one SINT, INT, or DINT. Anything bigger than 32 bits and you come unstuck.

2. Unlatch all the bits individually.

That's going to be a right chore for a large array. Imagine the coding needed for a BOOL[2048] array, e.g. alarm bit storage. I'm not even going to attempt to code this to see how fast it executes, and there will also be a big hit on program memory.

3. Use a FOR instruction to index the bit address, which then needs to be unlatched in a separate routine.

It works, but is extremely slow, as picture "FOR_Loop" witnesses. You also need to ensure that the Index value is initialised at power-on to prevent the pre-scan picking up an "array index out-of-bounds" error...

4. Use a backwards-jumping "loop" to cycle through the bits.

This is only slightly faster than the FOR method, but still slow by any standards. Picture "JMP_LBL" witnesses this, and again you have to initialise the index value for the pre-scan. Incidentally your "pseudo-code" won't unlatch the last bit in the array....


Now for my method - fast, just one instruction, see picture "FLL_Method" for the speed results. No need to initialise anything, it just does what it says on the tin. The only "drawback", if you want to call it that is the BOOL array has to be contained in a UDT structure. I don't see it as a drawback if doing so opens up the possibility of doing real and useful things with the array ....

I have used an array size of 2048 bits for my comparative tests.

FOR_Loop.jpg JMP_LBL.jpg FLL_Method.jpg
 
Daba
Yes a string data type is 82 characters I apologize for that I was going from memory but if you really want to define a string data type it is a multi dimensional array of bits
I say this because I think it’s important to help the less experienced among us to understand the data structure. Understanding data structure is very important is any programming task.

Structure of String Data Type
DATA is an array of 82 SINT Data type, each SINT is an array of 8 BOOL
LEN is a DINT data type and as we have established is an array of 32 BOOL
The LEN is not the default 82 SINT array but the number of the SINT’s to used and displayed
It’s important to understand this when working with string data types within the program if you add to or subtract SINT arrays you use in the DATA then you need to adjust the LEN value accordingly. I have seen more than a few programs where that detail was missed and they were wondering why the program was not working correctly.

As for using the FLL function I really never thought of using it set or reset the values in a BOOL array. It’s main function to work with words (INT, and DINT), but I don’t see why it would not work for a BOOL array.
As for the Label and for loop I think you have way to many conditions in the rung and could be cleaned up a bit. But as I said before if it works and gives you what you need then it’s good.

As for the label loop ( Label – JMP to Label ) I started using them in the old PLC2’s where you didn’t have subroutines everything had to be done within the original ladder LABEL”s were part of the main program. For reference Labels we generally place after the last line of the ladder code (END statement ) you called a LABEL and each LABEL had a return at the end. The return set the execution pointer to the next rung after the LABEL call. And the ladder program continues from there. And in case you ask I have seen programs where a nested LABLE or FOR loop will get trapped is continuous loop and never reach the end statement when that happens the only way to stop the loop is set the processor in program mode or cycle power.
Rockwell has provided us programmers with a great list of functions and hat list is expanding all the time
We should a be grateful for that it makes our job easier ( so Thank You)
But all functions and AOI’s are subroutines and we just pass data to the receive data from them.
Subroutines need to be call as needed.
We all should take the time to really understand how they work within the program
 
Unfortunately, PLC manufacturers use different ways of running programs, many do not actually compile into machine code, it uses an interpreter just like basic, so for example a particular instruction might be a N/O contact in the IDE but is converted into a form of hex value like HE01F, this has two parts, one is the instruction & the other is the address, the interpreter knows this & runs the code, this way it makes it easier to do on-line changes so it does not need as much room, for example in the old S5, the program is split into blocks, when downloading a block, the MC5 instructions are downloaded into un-allocated memory & at some point in the non program scan portion the PLC replaces the "FAT" table header for that block of code so a block i.e. FB is downloaded, at the end of program scan (or before scan) the location of that block in memory is replaced with the location of the new one in the table, this is why in the early days there was a need to compress the memory at some point to remove the old blocks, now this is automatic.
Again, many of the instructions i.e. like PLS will actually require more than one machine code instruction, so rolling your own may probably not be any different from the PLS function. I worked with a guy who designed & built a PLC system for their own product, this was in the late 80's, it was far more advanced than most PLC's at the time, they did not really use ladder it was almost FBD based, so well in advance of most at the time, you dropped a block on the window & connected the pins. He did explain to me that he had reversed engineered a number of PLC's to see how they had done it.
The introduction of IEC blocks has forced some Mfrs. to create extra instructions that are actually compiled into existing STL type code, for example, in Mitsubishi an IEC timer does not use a timer as such, it uses a call to a block of code that increments a word using a internal time contact.
See pic although I cannot show the call pointer as I do not have a real PLC you can see it does jump to a subroutine & return.
I once worked on a PLC that used I think DOX5, this was awful, just changing a N/O to N/C meant stopping the PLC & downloading the whole compiled program.
S5 was great, you could download a complete program while in run mode (providing any new DB's were downloaded first) or the red light came on.
Going back to how memory is organised, this probably varies by manufacturer, some may use actual bits on 16 bit boundaries, some may use whole words, some will allow bit addresses in words some won't, who really cares as long as you can manipulate the bits/words with the built in functions or roll your own. I agree, it is imperative you understand as much as possible on how a system works, but PLC Mfrs. do not want you to know too much.

Compile.png
 
Thanks. I referenced that instruction, and it does not work with bool's. In fact it does not appear that any of the move, or clr, or .. . .instructions even work with word arrays.
 
I am Back
I see some of you are not following so created aline of code to the clear a BOOL Array
I created a BOOL array tag Alarm_Bool(32)

you cahange the tags and values for your needs
First line triggers it
Second line clears the Alarm_Bool Array
Clean Simple and it works

Reset Loop.JPG
 

Similar Topics

In studio 5000, is there a way to write a force mask into a rung? Long story short, I would like to create a test routine for a FAT test. In...
Replies
7
Views
1,238
Hey guys, thanks for taking the time to look into my question. I'm building a system to monitor several other systems for faults and one of the...
Replies
17
Views
4,606
I"m trying to average an array of DINT's called FIFO_ARRAY. It has 1000 elements in it. Here is what I have entered into the AVE instruction...
Replies
11
Views
4,641
I have a RS Logix 5000 program that i feel was poorly structured and I'm trying to make the best of it. There is a series of approx 40 tags with...
Replies
8
Views
1,775
Good morning everyone. I am apparently confused on the COP instruction. What I am trying to do is copy a DINT to a DINT in a User Defined Data...
Replies
16
Views
6,778
Back
Top Bottom