Welcome to the forum!
You're on the right track, I think, just a few minor hurdles to get you over the line.
First things first:
Created Tag Array-
Name: PartRejectArray[5]
Data Type: PartData
Small nitpick - your tag should be called PartRejectArray and it should be of data type PartData[5], not what you've stated above. I'm assuming this is actually what you've done, and you just made a small typo in your post (putting the [5] on the end of the tag name, not the data type) - but just making sure! Ultimately, what you should have is an array of five of your UDT's, named PartData[0] through PartData[4]. Within each of those UDT's there are two elements, Barcode and Weight, so if you open your tag browser you should be able to drill down e.g. PartData > PartData[3] > PartData[3].Weight
As long as that's the case, moving on!
FSC (to find next empty position)
Control: Not sure what to use here; tried using both my PartRejectArray as well as individual tags and other arrays, nothing was accepted
This is a Control tag that the FSC uses to perform its magic. You need to create a
new tag, of data type Control, and put it here. Think of this tag as the FSC itself - whenever you refer to the FSC instruction, you refer to this tag, not your array data. So, I would call the tag something like RejectArraySearch or PartRejectFSC - that makes it easy for you (and other programmers) to distinguish between the data you're searching (your array and the data within it) and the method you're using to search for it (the Control tag and the FSC that uses it).
Length: Should this populate automatically? I tried entering 5, didn't work, said not supported or something
This will not populate automatically. You have to tell the FSC how far through the array to search. Sometimes you may not want to search the whole array, only the first, say, 100 elements. You should be able to put a 5 in there directly; it's likely just not being accepted right now because it doesn't have a valid Control tag assigned, and the Length parameter is actually part of that Control tag. So the FSC has nowhere to "store" your value of 5.
Unsolicited tip: if you were to put "6" in your length field, you would likely crash the PLC, as it will go looking for an array element that doesn't exist. For this reason, I always use a SIZE instruction immediately before the FSC instruction. The SIZE instruction gets the size of my array, which I then put into the Length of my FSC instruction. As well as ensuring I don't fault the PLC, if in the future I realise I need 10 array elements, not 5, I just have to increase the size of my array and the FSC instruction will automatically be updated. How do you get the result of the SIZE instruction into the FSC Position? Easy. Remember, the Length is part of the Control tag we discussed before. So, if your FSC Control tag is called PartRejectFSC, you would just make the Destination of your SIZE instruction PartRejectFSC.LEN
This will be automatically generated/updated. You should for the most part never need to write to the Position manually; only read it. If you need the FSC to go back to the start, use the RES instruction (again, directed the Control tag) which will set the Position back to zero, and reset all sorts of other flags that need resetting.
This should be fine - you can have the instruction search one array element per scan, or all of them - but with such a small array there's no need to do anything other than ALL
Expression: PartRejectArray[PartRejectArray.POS].Barcode = 0 (or should it be ''?)
After all my waffling above, hopefully you've gotten your head around the difference between the Control tag and your Array. This is where your array comes into play. You want to search each element of the array for a specific value. Effectively, you want to do:
Code:
PartRejectArray[0 through 4].Barcode = BarcodeYouWant
To get the "0 through 4" you are as you expected going to look at the Position of your FSC instruction - which is, as you can probably guess, part of the Control tag. So if you called your Control tag PartRejectFSC, then you need to use PartRejectFSC.LEN - giving you:
Code:
PartRejectArray[PartRejectFSC.LEN].Barcode = BarcodeYouWant
Now, your second issue is that you need to determine what constitutes an "empty" slot in your array.
It seems you're looking for a blank string in the Barcode UDT member, which is one way of doing it. How to achieve that? The latest versions of Logix will allow you to use a literal string, but earlier ones will not. You could create a new string tag, call it BlankString and use the DELETE instruction to ensure that it always stays empty. Then you can compare to that tag.
Alternatively, you could check the length of the Barcode string - if the length is zero, the barcode is obviously "blank":
Code:
PartRejectArray[PartRejectFSC.LEN].Barcode.LEN = 0
One other way might be to add a BOOL member to your UDT called, say, InUse. When you load your rejected part into the array, you'll presumably be copying a string and a number into the Barcode and Weight UDT members; at the same time use an OTL to turn on the InUse member. When you remove an item from the array, DELETE the Barcode string, CLR the Weight, and OTU the InUse.
Hopefully with that information you can also work through how to find the "matching" barcode.
Lastly, once I can actually get the FSC instruction to return a position for the empty/match how do I use that info to move/copy a barcode in/out of the array
Easy. Your position is once again part of your Control tag. So, assuming your control tag is called PartRejectFSC, you should first look for PartRejectFSC.FD (found) to be true. That means it's found a match. If PartRejectFSC.DN (done) is true but PartRejectFSC.FD is not, then the FSC reached the end of the array before finding a match.
Assuming you found a match, the FSC will halt with its position equal to the array element with the match. If you were looking for a blank space to copy your data into, simply use a COP for the Barcode and a MOV for the weight, with PartRejectFSC.POS as the pointer for the array element. e.g.:
Code:
COP
Source: FaultyBarcode
Destination: PartRejectArray[PartRejectFSC.POS].Barcode
Length: 1
MOV
Source: FaultyWeight
Destination: PartRejectArray[PartRejectFSC.POS].Weight
Then - IMPORTANT! -
reset the FSC instruction. You want to make absolutely sure the next time you use the instruction, you're starting from the start!
Moving them out of the array will look exactly the same as moving them in, just with the source and destination reversed. However, remember that this doesn't remove the source data! i.e. you'll copy your Barcode and Weight data out of the array into some other tags, but
they will still exist unchanged in the array. You will again need to use the PartRejectFSC.POS to delete that data from your array, using a DELETE instruction for the Barcode, and a CLR instruction for the Weight. Then, reset your FSC. Or, if you go down the track of using my "InUse" boolean idea from above, you could in theory just leave the values in there and solely use the InUse to determine whether that array element is in use or not. A word of caution - leaving old data in the array may be confusing for yourself or others looking at the array. Even more so if you can see the array contents on a HMI anywhere. Even if you don't
need to delete the data from the array, you should consider whether it would be good practice to do so anyway.
Good luck!