Studio5000 - swap array value and index into new array

@chelton: what if array1 is [3,2,1]?

So

  • array2[1] should be 3, because array1[3] is 1
  • array2[2] should be 2, because array1[2] is 2
  • array2[3] should be 1, because array1[1] is 3
  • i.e. the general case is
    • MOV index array2[array1[index]]
      • which is semantically correct, but does not work syntactically because of the nested brackets
 
@Chelton, the OP's title does say "swap" but, he wants to move Array1's position into an Array2 position that is equal to Array1's value.

If Array1[1] = 1 then Array2[1] should = 1
If Array1[1] = 2 then Array2[2] should = 1
If Array1[1] = 3 then Array2[3] should = 1

The OP has not given the Length of the arrays. He only stated that Array 1 and Array 2 are of equal lengths. The example was of 3 values. But for all we know the real array length could be in the 10's,100's, or 1000's.

The OP also stated he wants to do this in 1 scan cycle which also complicates the solution.

So, my only conclusion is:
1. Use EQU and MOV for a small array length. The number of rungs needed would be the Array length squared.

2. Create a 3rd array with values equal to the array element # and use a FSC to find Array 1's value in Array3 and move FSC.POS value into Array2[element]. But this would require 1 FSC per element in the array. So, the number of rungs would be equal to the Array length.

3. Use a FOR/BREAK instruction and put a FAL in INC mode and a MOV instruction in the call routine and loop for Array length. This would only increase program scan cycle by the loop time. Which again depends on the actual length of the Arrays and the PLC.

Option 1 is an example I gave in post #12
Option 2 is also an example I gave in post #12
Option 3 is an expanded idea to post #3. I added a FOR/BREAK loop and would change the FAL mode from ALL to INC.

I had fun last night playing around with your formula in excel and trying to make it work with larger arrays. But only had success using =lookup() and =ifs(). The MOD returning 0 always seemed to get in my way. I may play around with it tomorrow at work if I have time with my desktop PLC but I expect I'll be too busy. Anyway, if you come up with a solution, please share I know you down under boys can be very innovated.
 
@Chelton, the OP's title does say "swap" but, he wants to move Array1's position into an Array2 position that is equal to Array1's value.

If Array1[1] = 1 then Array2[1] should = 1
If Array1[1] = 2 then Array2[2] should = 1
If Array1[1] = 3 then Array2[3] should = 1

@cwal61 - I can see how you have interpreted the OP. What then happens if Array1 was an array or Real's? or if Array1 data has duplicated contained the same value? Do you just overwrite the same address in Array2?
 
The OP stated both arrays are DINT's. As far as duplicates, that's to OP's responsibility to control the values in Array 1. But to answer your question the brute force method would overwrite the value.
 
Both tested on RSLogix 5000 Emulator, both work.

The double-FAL approach takes N scans to complete and will need some additional logic to restart; for now manually assigning 0 to ctl1.POS initiates a new pass.

The looping approach completes on every scan and runs automatically.

falfal.PNG

...

loop.PNG
 
The OP stated both arrays are DINT's.

Yep missed that. Looks to me like a definite major fault contender.

Anyway, this is the best i could come up with as a distraction.

jmp.png

@Drbitiboy & @cwal61 not much different to your approach, just misunderstood the criteria.
 
Anyway, this is the best i could come up with as a distraction.


Nice. Haha, my second FAL could be replaced by a MOV or perhaps and ADD or SUB.

if the Mode is changed to 1:

  • Does moving the [XIO swap_2.DN] to the main rung just after the LBL, i.e. before the branch, mean we can drop the [XIC swap_2.EN]?
  • I think the [ADD swap_2.POS 1 array_4[temp_int]] could be [MOV swap_2.POS array_4[temp_int]], because the FAL will increment swap_2.POS before it exits.
 
Last edited:
New Approach, create a 2-dimensional Array for Array 1 (UDT) and also add a 3rd 2-dimensional Sort Array.

1st dimension contains Values. 2nd dimensions contains Positions.

Copy Array 1 into Array3, sort Array3 by 2nd dimension and Copy Array3 1st dimension into Array 2.

have not tested but it works in excel.
 
Last edited:
I think the [ADD swap_2.POS 1 array_4[temp_int]] could be [MOV swap_2.POS array_4[temp_int]], because the FAL will increment swap_2.POS before it exits.

Only reason for the ADD is because the OP's array addresses started at [1]
the ADD 1 is just an offset.
 
New Approach, create a 2-dimensional Array for Array 1 (UDT) and also add a 3rd 2-dimensional Sort Array.

1st dimension contains Values. 2nd dimensions contains Positions.

Copy Array 1 into Array3, sort Array3 by 2nd dimension and Copy Array3 1st dimension into Array 2.

have not tested but it works in excel.

Looking forward to the results..
 
Is it somehow guaranteed that in every index of array 1 is a unique number?

How does the OP want to handle, for instance every index in array1 to have the number 1 in it?
 
If the numbers are all unique in the array1[index]. An the numbers in array1[index] are not greater than the [index]

Then this works. I've based it on a 1..10 section array, but can be expanded or made dynamic quite easily.

Tested in siemens SCL so the syntax would need changing, also, no error checking done.

Trigger_Bool is only so loop runs 1 time.


Code:
IF #trigger_bool = true THEN
    
    FOR #i := 1 TO 10 DO
        #j := #ARRAY1[#i];
        #ARRAY2[#j] := #i;
    END_FOR;
END_IF;

#trigger_bool := false;

Edit:- Miss read the OP wanting in LAD. Also based the function off drbitboy's post #16.
 
Last edited:
Looking forward to the results..

They stunk. No luck with SORT. Will only sort 1 dimension and invalid subscript on a UDT.

I also did not have success doing it in one scan. The best I came up with was FAL and COP. Maybe a loop would work but did not test.

So, I made a 2-dimensional UDT tag both DINT's. One for Array1[x].Value and one Array1[x].Element and I created an Index DINT.

Then, I used the FAL to Copy Array1[FAL.POS].Value into the Index DINT. Then COP Array1[FAL.POS].Element into Array2[INDEX] for a length of 1.

I set the FAL to INC and placed the COP in series on the same rung and used a XIO FAL.EN to trigger. It worked but it will take the same number of scan cycles equal to the Array's length.

Did this during 1 hr. Zoom meeting. I spent the rest of day on the floor. We're working on a new production line install. So not much time at the desk.
 

Similar Topics

I have a C-More HMI that changes my PLC String from "Machine Status" to "aMhcni etStasu" . There is an option with other objects that have string...
Replies
15
Views
3,477
I have an array of 55 REAL values. Is there a way to multiply based on the array location ? I have 55 transfer belts that are equally spaced...
Replies
3
Views
154
Hi Hope you all are doing well. Iam working on a project with some AOI. I also hate no online edits... lol. My problem occurs when I use a UDT...
Replies
2
Views
161
I am not sure if this is possible but if there is a way, you guys would be the ones to know. I am currently working on a project where we are...
Replies
7
Views
222
Hi all. I'm having issues adding an ethernet module to my project in Studio500 v34. The device is a Fredericks Televac EthernetIP MX gateway which...
Replies
8
Views
365
Back
Top Bottom