0
FOR #index := 0 TO 9 DO
    // Increase working time count if the pump is active
    IF #PumpActiveSignal[#index] = true THEN
        IF #M_Clockbit1s = true THEN // memory clock that switches on every second
            IF #LoopOnce[#index] = false THEN // execute this on a positive edge of the memoryclockbit
                #WorkingTimes[#index]."Time" := #WorkingTimes[#index]."Time" + 1; // increase the working time
                #LoopOnce[#index] := true;
            END_IF;
        ELSE
            #LoopOnce[#index] := false;
        END_IF;
    END_IF;
END_FOR;

// move working times to list that needs to be ordered
FOR #k := 0 TO 9 DO
    #OrdenedList[#k] := #WorkingTimes[#k]."Time";
END_FOR;
// Order working times, lowest to highest
FOR #i := 0 TO 9 DO
    FOR #j := #i + 1 TO 9 DO
        IF #OrdenedList[#i] > #OrdenedList[#j] THEN
            #temp1 := #OrdenedList[#i];
            #OrdenedList[#i] := #OrdenedList[#j];
            #OrdenedList[#j] := #temp1;
        END_IF;
    END_FOR;
END_FOR;

IF #CHNGOVER = 1 THEN
    // assign priority number according to working times
    FOR #l := 0 TO 9 DO
        #WorkingTimes[#l].PriorityNo := -1;
    END_FOR;
    FOR #m := 0 TO 9 DO
        FOR #l := 0 TO 9 DO
            IF #OrdenedList[#m] = #WorkingTimes[#l]."Time" AND #WorkingTimes[#l].PriorityNo = -1 THEN
                #WorkingTimes[#l].PriorityNo := #m;
                EXIT;
            END_IF;
        END_FOR;
    END_FOR;
END_IF;

///with this logic I tried to make the logic in tia portal for a project. Following are the requirement in the logic: ** Change over based on the less running hours. ** after a time cycle of 2 hrs. there will be a change over which will make the less run hour motor to start first. ** and also i want to add the trip status in the logic , so that due to above logic trip motor should not come into running logic.

1 Answers1

1

From the attached code I cannot really understand what you're trying to do with the #WorkingTimes[#l].PriorityNo and I don't know how it's being evaluated in the rest of the logic.

But... here some general points:

  • you should use a more structured approach. I would make for example an array of structures (with members "Active", "Tripped", "WorkingTimes"...) for the pumps.
  • it's not necessary to evaluate everything every PLC cycle. This costs time! For a pump application a 1 sec. period is just fine in most of the cases.
  • In my opinion - it's better to structure the task in such a manner, that we could reuse some of the data in the future.

Here my version of your code :) :

IF #M_Clockbit1s AND NOT #M_EdgeDetect THEN // execute this on a positive edge of     the memoryclockbit
// Increase working time count if the pump is active
FOR #index := 0 TO 9 DO
    IF #Pumps[#index].Active THEN 
        #Pumps[#index].WorkingTimes +=1; // increase the working time 
    END_IF;
END_FOR;
// next - it would be good to know how many alailable pumps we have (not tripped) and write them to the start order array
//
#AvailPump := 0;
//
FOR #k := 0 TO 9 DO
IF NOT #Pumps[#k].Tripped THEN
    #PumpOrder[#AvailPump] := #k;
    #AvailPump +=1;
END_IF;
END_FOR;
// I like to have the things so. -1 means no pump available for this array element. Not used right now, but might be needed someday :)
//
IF #AvailPump < 9 THEN
FOR #m := #AvailPump + 1 TO 9 DO
    #PumpOrder[#m] := -1;
END_FOR;
END_IF;
// now we can sort our array to determine which pump has to be started next time.
//
IF #AvailPump > 0 THEN
FOR #i := 0 TO #AvailPump DO
    FOR #j := #i + 1 TO #AvailPump DO
        IF  #Pumps[#PumpOrder[#i]].WorkingTimes >  #Pumps[#PumpOrder[#j]].WorkingTimes THEN
            #temp1 := #PumpOrder[#i];
            #PumpOrder[#i] := #PumpOrder[#j];
            #PumpOrder[#j] := #temp1;
        END_IF;
    END_FOR;
END_FOR;
END_IF;
// now in PumpOrder[0] you have the pump number with the least running time, in PumpOrder[1] the pump number with the second least and so on...
//
// here the closing end_if - so we evaluate the data every second and not every cycle
END_IF;
#M_EdgeDetect := #M_Clockbit1s;
Yadi
  • 36
  • 3
  • Temporary CPU error: Area length error in FB 2 affecting OB 1 execution read access Type-safe LD area Incorrect address, operand replaced Processing will continue (no OB processing) PLC_1 / PLC_1 Internal address details: Caddr=16#0000018D, area: Type-safe LD area, addr: 4286578752 – Lalit Pandey Aug 19 '22 at 16:37
  • Hi Yadi, I am facing this error and my cpu is in error state. – Lalit Pandey Aug 19 '22 at 16:37
  • HI Yadi, Could you please tell me that data type i need to consider for them. – Lalit Pandey Aug 19 '22 at 16:51
  • HI , ca you tell the data type and type of parameter. – Lalit Pandey Aug 19 '22 at 17:24
  • The value addressed by the access address is outside or not completely within the permitted operand range (CPU-specific variable or size of the data block). Resolution: Select the access address so as to ensure the addressed value lies completely within the permitted operand range. Check the type of addressing and the addressed operand type. Open the block to display the error in the context of the block program code. – Lalit Pandey Aug 19 '22 at 17:44
  • * whenever there is a pump active is there, the priority is not changing accordingly. * Could you please reach via Whatapp message +97431395288. * I can show you the problem i am facing to rectify. – Lalit Pandey Aug 20 '22 at 11:43