The code that determines the number of A boards and B boards is fairly straight forward. I tested this code last night on a simulator I have, and if you force the number of boards in the beam into MD20, then it returns the correct boards of each type (You can copy and paste this code into an FC to test it as long as you create the local variables):
NumberOFBoards = DINT
ABoards = DINT
BBoards = DINT
L MD 20
T #NumberOfBoards
L #NumberOfBoards
DTR
L 3.000000e+000
/R
RND+
T #ABoards
L L#2
MOD
A ==0
JC m001
L #ABoards
+ L#1
T #ABoards
m001: NOP 0
L #NumberOfBoards
L #ABoards
-D
T #BBoards
Once you find the ABoards and BBoards, then you have to create your own recipe in the PLC. If I was doing this, then I would start at the beginning of a data block and then start filling it in, board by board. You used two bytes per board; was there a reason for that? Were you going to identify a board with an integer, such as ABoards = 1, BBoards = 2? Anyway, since the number of ABoards is always an even number, you would divide by two to determine how many are inserted initially. There are a few ways to do it, but I think it would be easiest to create a LOOP, with the NumberOfBoards determining the number of cycles in the loop. Then, as you filled the DB, you would increment a pointer by two bytes. Also, inside the loop you would have to keep track of how many of each type have been transferred. It sounds tricky at first, but it would be a neat little piece of code by the time you are done (plus, you would really understand Loops by the time you were finished.
)
You would have to do this for each beam in your production run. When you are finished, you would have a list of boards in sequential order, starting at DBW 0 through, say, DBW 30. And, this is where I must be missing something in the mechanics of this system, because since it is LIFO, I don't understand why you couldn't just produce the boards in reverse order, starting at DBW 30. If so, the cages would look like this, assuming five boards per cage:
Cage 1: DBW 30 (Board 16)
DBW 28 (Board 15)
DBW 26 (Board 14)
DBW 24 (Board 13)
DBW 22 (Board 12)
Cage 2: DBW 20 (Board 11)
DBW 18 (Board 10)
DBW 16 (Board 9)
DBW 14 (Board 8)
DBW 12 (Board 7)
Cage 3: DBW 10 (Board 6)
DBW 8 (Board 5)
DBW 6 (Board 4)
DBW 4 (Board 3)
DBW 2 (Board 2)
Cage 4: DBW 0 (Board 1)
So, when you start producing the beams, they would have to be unloaded in reverse order, right? First, you would unload Board 1, then jump to Cage 3 and unload Board 2 (since it was the last one loaded in that cage) and so forth. This way, all of the data is only in one place, and you won't need to move it to another DB. I would suggest that you add additional properties to your boards (whether you use arrays or not) and mark certain boards as the "Start Of Beam", "End Of Beam", etc. I'm sure these bits would be useful as you develop the code.
It sounds like a fun project. Keep us posted.