Welcome to our new forum
All users of the legacy CODESYS Forums, please create a new account at account.codesys.com. But make sure to use the same E-Mail address as in the old Forum. Then your posts will be matched. Close

7 inputs and 8 outputs. only 3 outputs can be TRUE at once

espenbo
2018-11-15
2018-11-15
  • espenbo - 2018-11-15

    Hello. I need some help with a control function.

    I have 7 switches connected to digital inputs on the PLS and 7 Digital outputs.

    Digital input 1 controls Digital Out 1
    Digital input 2 controls Digital Out 2
    Digital input 3 controls Digital Out 3
    Digital input 4 controls Digital Out 4
    Digital input 5 controls Digital Out 5
    Digital input 6 controls Digital Out 6
    Digital input 7 controls Digital Out 7

    When 3 digital outputs are TRUE, no more outputs are allowed to be set to TRUE.
    Then you must turn off an output before the next can be turned on.

    If I set
    Digital input 1 = TRUE
    Digital input 2 = TRUE
    Digital input 3 = TRUE
    Digital input 4 = FALSE
    Digital input 5 = FALSE
    Digital input 6 = FALSE
    Digital input 7 = FALSE
    Then
    Digital out 1 = TRUE
    Digital out 2 = TRUE
    Digital out 3 = TRUE
    Digital out 4 = FALSE
    Digital out 5 = FALSE
    Digital out 6 = FALSE
    Digital out 7 = FALSE


    Then I set Digital 4 TRUE

    Digital input 1 = TRUE
    Digital input 2 = TRUE
    Digital input 3 = TRUE
    Digital input 4 = TRUE
    Digital input 5 = FALSE
    Digital input 6 = FALSE
    Digital input 7 = FALSE
    Then
    Digital out 1 = TRUE
    Digital out 2 = TRUE
    Digital out 3 = TRUE
    Digital out 4 = FALSE
    Digital out 5 = FALSE
    Digital out 6 = FALSE
    Digital out 7 = FALSE


    And nothing should happen to the output

    If I then turn of digital input 1 to FALSE I get

    Digital input 1 = FALSE
    Digital input 2 = TRUE
    Digital input 3 = TRUE
    Digital input 4 = TRUE
    Digital input 5 = FALSE
    Digital input 6 = FALSE
    Digital input 7 = FALSE
    Then
    Digital out 1 = FALSE
    Digital out 2 = TRUE
    Digital out 3 = TRUE
    Digital out 4 = TRUE
    Digital out 5 = FALSE
    Digital out 6 = FALSE
    Digital out 7 = FALSE


    I Then turn Digital input 5 to TRUE and digital input 2 to FALSE.
    Digital output 2 don't go to FALSE


    Digital input 1 = FALSE
    Digital input 2 = FALSE
    Digital input 3 = TRUE
    Digital input 4 = TRUE
    Digital input 5 = TRUE
    Digital input 6 = FALSE
    Digital input 7 = FALSE
    Then
    Digital out 1 = FALSE
    Digital out 2 = TRUE
    Digital out 3 = TRUE
    Digital out 4 = TRUE
    Digital out 5 = FALSE
    Digital out 6 = FALSE
    Digital out 7 = FALSE

    How can I get thise to work?

    VAR_GLOBAL CONSTANT
       IOMAXSIZE: INT := 7;
    END_VAR
    PROGRAM test2
    VAR
        aInput         : ARRAY[1..IOMAXSIZE] OF BOOL;
        aOutput         : ARRAY[1..IOMAXSIZE] OF BOOL;
        aINT_Input      : ARRAY[1..IOMAXSIZE] OF INT;
        aINT_Output      : ARRAY[1..IOMAXSIZE] OF INT;
        iCount         : INT;
       iTotalInput      : INT;
       iTotalOutput   : INT;
    END_VAR
    (*Max 3 til TRUE samtidig. Alle de andre skal da være stengt.
    Ikke mulig å åpne den 4 når 3 allerede er TRUE.
    Bør kunne gå fra 4 innganger i TRUE til 3 UTGANGER i TRUE direkte. Ikke måtte innom kun 2 i TRUE*)
    PROG
       (*Legger sammen alle utgangene som er TRUE en total variabel*)
       iTotalInput := aINT_Input[1] + aINT_Input[2] + aINT_Input[3] + aINT_Input[4] + aINT_Input[5] + aINT_Input[6] + aINT_Input[7];
       iTotalOutput := aINT_Output[1] + aINT_Output[2] + aINT_Output[3] + aINT_Output[4] + aINT_Output[5] + aINT_Output[6] + aINT_Output[7];
    (*Gjør om fra BOOL verdier til INT*)
    FOR iCount := 1 TO IOMAXSIZE BY 1 DO
       aINT_Input[iCount] := BOOL_TO_INT (aInput[iCount]);
       aINT_Output[iCount] := BOOL_TO_INT (aOutput[iCount]);
    END_FOR
    (*Hvis det er mindre en 3 innganer som er på kjøres denne*)
    IF (iTotalInput < 3) THEN
       (*Overfører utganger til ingangs arrayene*)
       FOR iCount := 1 TO IOMAXSIZE BY 1 DO
          aOutput[iCount] := aInput[iCount];
       END_FOR
    END_IF
    (*Her er tanket at Hvis det er 3 Innganger som er TRUE, men disse ikke sammsvarer med utgangene som er TRUE.
    Så kjør denne for å oppdatere innganger å utganger*)
    IF (iTotalInput = 3) AND NOT aOutput[iCount] = aInput[iCount] THEN
       FOR iCount := 1 TO IOMAXSIZE BY 1 DO
          aOutput[iCount] := aInput[iCount];
       END_FOR
    END_IF
    

    Link to video
    https://www.dropbox.com/s/opu2b96l5lvhl ... 5.MOV?dl=0

    Link to program
    https://www.dropbox.com/s/qz1jtw7bse6cfaq/test.zip?dl=0 m

     

    Related

    Talk.ru: 1
    Talk.ru: 2
    Talk.ru: 3
    Talk.ru: 5
    Talk.ru: 7

  • Lo5tNet - 2018-11-15

    There are two problems I see that once fixed will get your function to work properly.

    Try using this code instead and you can compare to what you have to see what has changed.

    (*Gjør om fra BOOL verdier til INT*)
    FOR iCount := 1 TO IOMAXSIZE BY 1 DO
       aINT_Input[iCount] := BOOL_TO_INT (aInput[iCount]);
       aINT_Output[iCount] := BOOL_TO_INT (aOutput[iCount]);
    END_FOR
    (*Legger sammen alle utgangene som er TRUE en total variabel*)
       iTotalInput := aINT_Input[1] + aINT_Input[2] + aINT_Input[3] + aINT_Input[4] + aINT_Input[5] + aINT_Input[6] + aINT_Input[7];
       iTotalOutput := aINT_Output[1] + aINT_Output[2] + aINT_Output[3] + aINT_Output[4] + aINT_Output[5] + aINT_Output[6] + aINT_Output[7];
    (*Hvis det er mindre en 3 innganer som er på kjøres denne*)
    IF (iTotalInput < 3) THEN
       (*Overfører utganger til ingangs arrayene*)
       FOR iCount := 1 TO IOMAXSIZE BY 1 DO
          aOutput[iCount] := aInput[iCount];
       END_FOR
    END_IF
    (*Her er tanket at Hvis det er 3 Innganger som er TRUE, men disse ikke sammsvarer med utgangene som er TRUE.
    Så kjør denne for å oppdatere innganger å utganger*)
    FOR iCount := 1 TO IOMAXSIZE BY 1 DO
       IF (iTotalInput = 3) AND aOutput[iCount] <> aInput[iCount] THEN
          aOutput[iCount] := aInput[iCount];
       END_IF
    END_FOR
    

    The first problem was was you were counting inputs of aINT_Input then later assigning the values you were changing so the iTotalInput value was wrong.
    The second problem was the last if/for statements that were made needed to be done in a different order. The IF statement was only checking to see if aInput[iCount] of array position 8 did not equal aOutput[iCount] of array position 8. The IF statement needed to be moved into the FOR loop in order to iterate through the array using the iCount variable.

     

    Related

    Talk.ru: 1
    Talk.ru: 2
    Talk.ru: 3
    Talk.ru: 5
    Talk.ru: 7

  • espenbo - 2018-11-15

    Thank you for youre feedback Comingback4u

    I been working with it and found another solution.

    PROGRAM test2
    VAR
        aInput         : ARRAY[1..IOMAXSIZE] OF BOOL;
        aOutput         : ARRAY[1..IOMAXSIZE] OF BOOL;
        aINT_Input      : ARRAY[1..IOMAXSIZE] OF INT;
        aINT_Output      : ARRAY[1..IOMAXSIZE] OF INT;
        iCount         : INT;
       iTotalInput      : INT;
       iTotalOutput   : INT;
       iTotalActiveInputs: INT;
       iInputCount: INT;
       bad: BOOL;
    END_VAR
    (*Teller opp antall inputer som er TRUE*)
    iTotalActiveInputs := 0;
    FOR iInputCount := 1 TO IOMAXSIZE BY 1 DO
       IF (aInput[iInputCount] = TRUE) THEN
          iTotalActiveInputs := iTotalActiveInputs + 1;
       END_IF
    END_FOR
    (*Hvis det er mindre en 4 inputer som er TRUE, overfør inputer mot outputene*)
    FOR iCount := 1 TO IOMAXSIZE BY 1 DO
       IF (iTotalActiveInputs < 4) THEN
          aOutput[iCount] := aInput[iCount];
    (*Hvis det er 0 inputs som er TRUE set outputene til FALSE*)
       ELSIF (iTotalActiveInputs = 0) THEN
          aOutput[iCount] := FALSE;
       END_IF
       aINT_Input[iCount] := BOOL_TO_INT (aInput[iCount]);
       aINT_Output[iCount] := BOOL_TO_INT (aOutput[iCount]);
    END_FOR
    (* DEN ULTIMATE TEST *)
    IF (iTotalActiveInputs < 4) THEN
       FOR iCount := 1 TO IOMAXSIZE BY 1 DO
          IF (aOutput[iCount] <> aInput[iCount]) THEN
             bad := TRUE;
          END_IF
       END_FOR
    END_IF
    

    Link to project
    https://www.dropbox.com/s/h6kgatk13g2x0 ... n.zip?dl=0

    I will test the code to try to learn more about how this can be solved.

     

Log in to post a comment.