Sign in to follow this  
Followers 0
Junto026

Copy consecutive bits in Int array to Consecutive bits in array of UDDTs

13 posts in this topic

************** The Problem: ************** - I have a big array of Ints, where each 14 consecutive bits correspond to different status bits for a bunch of hardware on the field. - I made a UDT for the hardware, which is comprised of 14 named Bools (Offline, Online, Fault, etc.) - I want to copy the first 14 bits of the Int array into the first UDT, the second 14 bits of the Int array into the second UDT, etc. ************** Stipulation: ************** I'll be doing this for data for thousands of different hardware, some having 14 status bits, some more, some less, etc. I'm hoping to make this more efficient than a brute force type XIC/OTE, etc. It also helps in case something changes during commissioning, i.e. I find out there are really 13 status bits, etc. ************** I Tried: ************** For example, I tried making an array of my UDDT, and using a COP. I hoped it would copy the first bits in the INT array into the first UDDT, and if I made the length long enough the subsequent bits would be copied into the next UDDT in the array. But no dice, it copies into the first UDDT and puts nonsense in the subsequent ones. Any suggestions? Edited by Junto026

Share this post


Link to post
Share on other sites
Uploaded an extra screenshot, can't figure out how to delete.... ignore the second image in my post above.

Share this post


Link to post
Share on other sites
You need to use multiple copy instructions. One for each array element of your UDT. Make the length of 14 bits, then keep changing the start point of your INT array for each sequential copy instruction (incrementing the UDT array element each time). Edited by MrAutomation

Share this post


Link to post
Share on other sites
Can you give an example of what you'd use for Source and Destination? RSLogix won't take a bool for either. More context: There are about 10 different types of hardware, each with it's own UDT. I currently have one subroutine for each UDT. Each subroutine takes some pointers as inputs (to tell it where in the INT array all relevant data starts at), and will extract all data from the array and build out the UDTs. So my main routine is just a ton of JSRs, giving some pointers as inputs to each. This is nice because it's easy to make certain changes. I'd love to be able to throw one copy command into my re-used JSRs, but it's proven impossible to index through them since the 14 booleans don't always start at the first bit in the word. I was thinking about putting one COP in each subroutine, and having two input parameters to make the COP work. The source would be SOURCE_ARRAY[Parameter1].Parameter2, with length 14. But this won't work since I can't put a bit in a COP command. Edited by Junto026

Share this post


Link to post
Share on other sites
Few things to be aware of: 1. the COP instruction operates byte by byte with no consideration of data types - i.e. there is no conversion like with a MOV 2. the length is referencing the destination data type. 3. a udt has to align with a 32-bit boundary - i.e. minimum size = 4 bytes / 32 bits Each UDT in your destination array is 32 bits long, regardless of you only defining 4. So, your COP instruction will copy 6x32=192 bits starting at Source_array[0]. The first 2 INT's from the source will go into the first destination UDT, but you will only be able to access the 4 bits you have defined. If the source array is long enough, the following 10 INT's will go into the next 5 UDT's. If the source array isn't long enough, whatever follows it in memory will be copied until the requested length (192 bits) is satisfied. Edited by Gerry
1 person likes this

Share this post


Link to post
Share on other sites
Gotcha, thanks Gerry - fully explained the results in my screenshots. Are you aware of any clean way to parse these 14 bits apart from each other?

Share this post


Link to post
Share on other sites
Before I offer any suggestions, can you first explain how the 14 bits are loaded into the source array? I'm speculating that you may not need the data in two separate arrays. Edited by Gerry

Share this post


Link to post
Share on other sites
The simple, but inelegant way to "fix" the above is to make the source array DINT's instead of INT's. Without more information, I can't (won't) offer anything better.

Share this post


Link to post
Share on other sites
Sure, I can explain the source array. I'm gathering data using a Prosoft MVI56E-MNETC, over a Modbus TCP/IP network. Many boolean status bits are already aggregated on an RTAC unit in consecutive registers. The way this works is, I send commands from the Prosoft card out to the RTAC. The RTAC sends the data back, which is stored in an array of 10,000 INTs on the Presoft card. Those 10,000 INTs are then continuously copied to an array of 10,000 INTs in the processor's memory. I have two options: - A: Read each 14 bits separately, put them into a separate words in the MNETC array. This would be nice. - B: Read them from the RTAC all at once, but they'll be put into consecutive bits in the 10,000 INT array, which makes it a pain to separate into UDDTs consisting of 14 named BOOL tags. Option A isn't really an option, because the Prosoft card has a 480 command limit. Not even close to the amount I'd need to read all these status bits separately. So, I really don't have much control over the source array, or the fact that these status bits are all going to be in consecutive bits in an array of INTs. If there were 16 status bits for each device, that would be very nice. Even if there were 8, at least I could consistently copy the first eight bits of the word into one UDDT, and the second 8 bits of the word into a second UDDT. But because there are 14, they don't line up well with a 16 bit word, and the word needs to be parsed in a different place for each word... It's also important that these status bits are placed into logically named and organized UDDTs. These tags are then being logged in Pi, and naming them correctly and naming the UDDTs correctly is important for them. I have since thought of creating a UDDT with 14 bits. I then create an array of those UDDTs. I can then create a loop in the ladder logic, and take advantage of a "mod" calculation to reset the bit designator every 16 count... Edited by Junto026

Share this post


Link to post
Share on other sites
I suspected there was a field bus involved. Using a technique known as 'bit-aliasing' in your UDT you can access the bits individually or collectively as SINT, INT, or DINT. To set it up, you need to export your program to .L5K and edit the UDT definition with a text editor. This is described in one of the manuals for CLX (system planning, I think). The UDT definitions are near the beginning of the file. After editing, the modified UDT can't be edited in RSLogix (probably a good thing). If your UDT is called RTAC, it could include an INT called Status with its bits aliased as offline, fault, etc. You could then use a FAL to copy from the input array to your array of UDT's. Maybe you can eliminate the intermediate step. source_int[index] => RTAC[index].Status access the bits as RTAC[index].Status.fault Edited by Gerry

Share this post


Link to post
Share on other sites
Hmm, I need to do some playing / reading to fully understand this, but it's sounding a lot like genius. Going to look into this!

Share this post


Link to post
Share on other sites
...been trying to find that manual. Closest I found is this: Rockwell Automation Publication 1756-RM084R-EN-P October 2014 see pages 64, 65 their example: DATATYPE MyBits (FamilyType := NoFamily) SINT ZZZZZZZZZZMyBits0 (Hidden := 1); BIT MyBit0 ZZZZZZZZZZMyBits0 : 0 (Radix := Binary); BIT MyBit1 ZZZZZZZZZZMyBits0 : 1 (Radix := Binary); END_DATATYPE Change name MyBits to whatever e.g. RTAC Change SINT ZZZZZZZZZZMyBits0 (Hidden := 1); to INT Status; (I don't think Hidden := 0 is necessary) Alias your bits: BIT Fault Status : 0 (Descrption := "fault decription"); (I don't think radix is necessary -- description more useful). note that spaces and semi-colons are vital. Correction to my previous post: access the bits as RTAC[index].Fault You could create alias tags for the RTAC array members in the interest of user-friendliness. Edited by Gerry

Share this post


Link to post
Share on other sites
See this from 2002: http://www.plctalk.net/qanda/showthread.php?t=12292

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0