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

How to convert Function block diagram to Structured text

espenbo
2015-04-27
2015-05-04
  • espenbo - 2015-04-27

    Hello

    I need some help converting function block diagram to sturctured text.

    My function program.

    PROGRAM MP_Linje_4
    VAR
       MP_Linje_4: FbMpBusMaster;
       MPBus: typMpBus;
       ErrorMasterLinje4: BYTE;
       MP_Adr_Linje_4: FbMpBusAddressing;
       L4_Address: BYTE;
       L4_Set: BOOL;
       L4_SetSerialNo: typSerialNo;
       L4_Adr_Ready: BOOL;
       L4_Adr_Error: BYTE;
       L4_Learn: BOOL;
       TILLUFT_MAX_POS_L4: REAL;
       AVTREKK_MAX_POS_L4: REAL;
       MP_Node_1_READY: BOOL;
       X360_005_SQ52093A: FbMpBusVav;
       X360_005_SQ52093A_ERROR: BYTE;
       X360_005_SQ52093A_POS: REAL;
       X360_005_SQ52093A_VOL_PERC: REAL;
       X360_005_SQ52093A_VOL_M3H: REAL;
       X360_005_SQ52093A_CRI: BOOL;
       X360_005_SQ52093A_MOL: BOOL;
       X360_005_SQ52093A_AH: BOOL;
    END_VAR
    

    Please helpe me with some examples on how I can do thise.

    Espen

    IMG: Funk.PNG

     
  • shooter - 2015-04-27

    make a new function block with name mp_linje_ST for example (type obvious ST)
    now copy all vars into the new FB

    get to line 1 in program:
    press F2 and find the FB MP_Linje_4 (I just saw that you have a program and a FB with same name (dont do it, it is confusing the compiler, every name should be unique, i use prgprogramname fbfunctionblockname etc. There is a naming convention in the helpfile.
    change the name of the block to same as you gave it in the FBprogram.
    go to the first := and fill in the variable also with F2
    the := are inputs and the >= are outputs.

    rung 3 is complicated to make in ST but possible.
    use tabs to get all aligned.
    the functions work by using a var:=FuBACNETPV_TO_BOOL(bacnet.BY....);
    btw i would use some smaller var names who is calling a function block X360_005_SQ52093A.
    (above you see the convention Fu)

     
  • espenbo - 2015-04-28

    Hello.

    I have tride to convert the program.

    (*MP_Linje_1*)
    FbMpBusMaster(
       bModule_750_643:=1 ,
       typMpBus:=MPBus ,
       bError=>ErrorMasterLinje1 );
    (*MP_Adr_Linje_1*)
    FbMpBusAddressing(
       bAddress:= L1_Address,
       xSet:=L1_Set ,
       xGetSerialNo:= ,
       typINSerialNo:=L1_SetSerialNo ,
       tMaxLearnTime:=t#60s ,
       xLearn:=L1_Learn ,
       typMpBus:=MPBus ,
       xReady=>L1_Adr_Ready ,
       bError=> ,
       typOUTSerialNo=> );
    (*Program before xEnable*)
    MOpen:=FuBACnetBinaryPV_to_BOOL(BACnet.BY2200_360_005_SQ52070_MOpen.Present_Value)
       EnableMP1:=var1 AND SFC_MP_L1.EnableMP_L1
    MClose:=FuBACnetBinaryPV_to_BOOL(BACnet.BY2200_360_005_SQ52070_MClose.Present_Value)
       EnableMP2:=var2 AND SFC_MP_L1.EnableMP_L1
          xEnable:=SFC_MP_L1.Node1 OR var4 OR var5
    (*Program before rAirVolum*)
    MPmax:=FuBACnetBinaryPV_to_BOOL(BACnet.BY2200_360_005_MPMAX.Present_Value)
       AirVolum:=SEL(MPmax,BACnet.BY2200_570_205_RY62070_VENT_OP.Present_Value,100);
    (*Program before rAirVolum*)
    Reset:=FuBACnetBinaryPV_to_BOOL(BACnet.BY2200_360_005_SQ52070_Reset.Present_Value)
    (*X360_005_SQ52070*)
    FbMpBusVav(
       xEnable:=xEnable ,
       tCycleTime:=t#3s ,
       bAddress:=1 ,
       rAirVolume:=MPmax ,
       rMinAirVolume:= ,
       rMaxAirVolume:= ,
       xSet:= ,
       xRead:= ,
       bSensorType:=0 ,
       xManualOpen:=MOpen ,
       xManualClose:=MClose ,
       xReset:=Reset ,
       typMpBus:=MPBus ,
       xReady=>MP_Node_1_READY ,
       bError=>X360_005_SQ52070_ERROR ,
       rOutPosition=>X360_005_SQ52070_POS ,
       rOutAirVolume_perc=>X360_005_SQ52070_VOL_PERC ,
       rOutAirVolume_m3_h=>X360_005_SQ52070_VOL_M3H ,
       wSensorValue=> ,
       rVmin=> ,
       rVmax=> ,
       xControlRangeIncreased=>X360_005_SQ52070_CRI ,
       xMecanicalOverload=>X360_005_SQ52070_MOL ,
       xActuatorHunting=>X360_005_SQ52070_AH ,
       xSensorError=> );
    

    Is there a better way to do it? Maby with less new varibels?

    I get an error
    'FBMPBUSMASTER' is no function
    Is it somthing wrong in the libary?

    Thanks for all comments, first priority is and convert the Function block program to Structure text. Then I will look at youre advise on naming the varibel.

     
  • shooter - 2015-04-28

    did you copy all variables and FB calls in the VAR block?
    and i see not enough ; in your program at a quick look.
    all FB need to be declared in the VAR list, see the original.

    and yes you can use lesser variables, however the program gets very complicated, FBD is very good in this as you have noticed, CFC is even better for this type of things, but is not easy for old LD programmers.

     
  • espenbo - 2015-04-28

    My var block:

    PROGRAM PLC_PRG_test
    VAR
       MP_Linje_1: FbMpBusMaster;
       MPBus: typMpBus;
       ErrorMasterLinje1: BYTE;
       MP_Adr_Linje_1: FbMpBusAddressing;
       L1_Address: BYTE;
       L1_Set: BOOL;
       L1_SetSerialNo: typSerialNo;
       L1_Adr_Ready: BOOL;
       L1_Adr_Error: BYTE;
       L1_Learn: BOOL;
            MP_Node_1_READY: BOOL;
    (*Node 1*)
       X360_005_SQ52070: FbMpBusVav;
       X360_005_SQ52070_ERROR: BYTE;
       X360_005_SQ52070_POS: REAL;
       X360_005_SQ52070_VOL_PERC: REAL;
       X360_005_SQ52070_VOL_M3H: REAL;
       X360_005_SQ52070_CRI: BOOL;
       X360_005_SQ52070_MOL: BOOL;
       X360_005_SQ52070_AH: BOOL;
    (*Convert signals*)
       MOpen: BOOL;
       EnableMP1: BOOL;
       MClose: BOOL;
       EnableMP2: BOOL;
       xEnable: BOOL;
       MPmax: BOOL;
       AirVolum: BOOL;
       Reset: BOOL;
    END_VAR
    

    Program

    (*MP_Linje_1*)
    (* Is it rigth to use the variabel name to get the funksjon? *)
    MP_Linje_1(
       bModule_750_643:=1 ,
       typMpBus:=MPBus ,
       bError=>ErrorMasterLinje1 );
    (*MP_Adr_Linje_1*)
    (* Is it rigth to use the variabel name to get the funksjon? *)
    MP_Adr_Linje_1(
       bAddress:= L1_Address,
       xSet:=L1_Set ,
       xGetSerialNo:= ,
       typINSerialNo:=L1_SetSerialNo ,
       tMaxLearnTime:=t#60s ,
       xLearn:=L1_Learn ,
       typMpBus:=MPBus ,
       xReady=>L1_Adr_Ready ,
       bError=> ,
       typOUTSerialNo=> );
    (*Program before xEnable*)
    MOpen:=FuBACnetBinaryPV_to_BOOL(BACnet.BY2200_360_005_SQ52070_MOpen.Present_Value); (* ; after every line? *)
       EnableMP1:=MOpen AND SFC_MP_L1.EnableMP_L1;  (* ; after every line? *)
    MClose:=FuBACnetBinaryPV_to_BOOL(BACnet.BY2200_360_005_SQ52070_MClose.Present_Value);  (* ; after every line? *)
       EnableMP2:=MClose AND SFC_MP_L1.EnableMP_L1;  (* ; after every line? *)
          xEnable:=SFC_MP_L1.Node1 OR EnableMP1 OR EnableMP1;  (* ; after every line? *)
    (*Program before rAirVolum*)
    MPmax:=FuBACnetBinaryPV_to_BOOL(BACnet.BY2200_360_005_MPMAX.Present_Value);
       AirVolum:=SEL(MPmax,BACnet.BY2200_570_205_RY62070_VENT_OP.Present_Value,100);
    (*Program before rAirVolum*)
    Reset:=FuBACnetBinaryPV_to_BOOL(BACnet.BY2200_360_005_SQ52070_Reset.Present_Value);
    (*X360_005_SQ52070*)
    (* Is it rigth to use the variabel name to get the funksjon? *)
    X360_005_SQ52070(
       xEnable:=xEnable ,
       tCycleTime:=t#3s ,
       bAddress:=1 ,
       rAirVolume:=MPmax ,
       rMinAirVolume:= ,
       rMaxAirVolume:= ,
       xSet:= ,
       xRead:= ,
       bSensorType:=0 ,
       xManualOpen:=MOpen ,
       xManualClose:=MClose ,
       xReset:=Reset ,
       typMpBus:=MPBus ,
       xReady=>MP_Node_1_READY ,
       bError=>X360_005_SQ52070_ERROR ,
       rOutPosition=>X360_005_SQ52070_POS ,
       rOutAirVolume_perc=>X360_005_SQ52070_VOL_PERC ,
       rOutAirVolume_m3_h=>X360_005_SQ52070_VOL_M3H ,
       wSensorValue=> ,
       rVmin=> ,
       rVmax=> ,
       xControlRangeIncreased=>X360_005_SQ52070_CRI ,
       xMecanicalOverload=>X360_005_SQ52070_MOL ,
       xActuatorHunting=>X360_005_SQ52070_AH ,
       xSensorError=> );
    

    Is it rigth to use the variabel name to get the funksjon?
    ; after every line?

    Yes FBD is very good and easy to understand. But I'm trying to find a faster way to do it, when I'm going to controll many hundres og VAV/CAV. Today we are copy and pasting names in FB. Hoping to find a faster way of doing it.

     
  • shooter - 2015-04-28

    How does it compile now?
    what errors do you get
    and yes the name above the FB should be in front of the Function Block in ST.
    The functions dont need it, as you can see in MOpen
    i dont see the AND and OR back in the program
    Make for every function or Block a ST Line then you can follow what happens.
    esspecially in the beginning to find errors.

     
  • espenbo - 2015-05-04

    Had a look at thise today.
    Looks like everything is working.

    Thanks for the help shooter.

    I have used digital inputs insted of bacnet variabels.

    MP_Linje_1(PRG-ST)
    PROGRAM MP_Linje_1
    VAR
       MP_Linje_1: FbMpBusMaster;
       MPBus: typMpBus;
       ErrorMasterLinje1: BYTE;
       MP_Adr_Linje_1: FbMpBusAddressing;
       L1_Address: BYTE;
       L1_Set: BOOL;
       L1_SetSerialNo: typSerialNo;
       L1_Adr_Ready: BOOL;
       L1_Adr_Error: BYTE;
       L1_Learn: BOOL;
       TILLUFT_MAX_POS_L1: REAL;
       AVTREKK_MAX_POS_L1: REAL;
       MP_Node_1_READY: BOOL;
    (* Global variable DI1-DI8 and DO1-DO8 *)
    (*         MClose:=DI1;
             MPmax:=DI2;
             Reset:=DI3;      *)
    (*   Virtuel out REAL *)
       REAL1:REAL;
    (*Node 1*)
       X360_005_SQ52070: FbMpBusVav;
       X360_005_SQ52070_ERROR: BYTE;
       X360_005_SQ52070_POS: REAL;
       X360_005_SQ52070_VOL_PERC: REAL;
       X360_005_SQ52070_VOL_M3H: REAL;
       X360_005_SQ52070_CRI: BOOL;
       X360_005_SQ52070_MOL: BOOL;
       X360_005_SQ52070_AH: BOOL;
       MOpen: BOOL;
       EnableMP1: BOOL;
       MClose: BOOL;
       EnableMP2: BOOL;
       xEnable: BOOL;
       MPmax: BOOL;
       AirVolum: REAL;
       Reset: BOOL;
    END_VAR
    
    (*MP_Linje_1*)
    MP_Linje_1(
       bModule_750_643:=1 ,
       typMpBus:=MPBus ,
       bError=>ErrorMasterLinje1 );
    (*MP_Adr_Linje_1*)
    MP_Adr_Linje_1(
       bAddress:= L1_Address,
       xSet:=L1_Set ,
       xGetSerialNo:= ,
       typINSerialNo:=L1_SetSerialNo ,
       tMaxLearnTime:=t#60s ,
       xLearn:=L1_Learn ,
       typMpBus:=MPBus ,
       xReady=>L1_Adr_Ready ,
       bError=> ,
       typOUTSerialNo=> );
    (*Program before xEnable*)
       MOpen:=DI4;
          EnableMP1:=MOpen AND SFC_MP_L1.EnableMP_L1;
       MClose:=DI1;
          EnableMP2:=MClose AND SFC_MP_L1.EnableMP_L1;
             xEnable:=SFC_MP_L1.Node1 OR EnableMP1 OR EnableMP1;
    (*Program before rAirVolum*)
       MPmax:=DI2;
       AirVolum:=SEL(MPmax,REAL1,100);
    (*Program before rAirVolum *)
    Reset:=DI3;
    (*X360_005_SQ52070*)
    X360_005_SQ52070(
       xEnable:=xEnable ,
       tCycleTime:=t#3s ,
       bAddress:=1 ,
       rAirVolume:=AirVolum ,
       rMinAirVolume:= ,
       rMaxAirVolume:= ,
       xSet:= ,
       xRead:= ,
       bSensorType:=0 ,
       xManualOpen:=MOpen ,
       xManualClose:=MClose ,
       xReset:=Reset ,
       typMpBus:=MPBus ,
       xReady=>MP_Node_1_READY ,
       bError=>X360_005_SQ52070_ERROR ,
       rOutPosition=>X360_005_SQ52070_POS ,
       rOutAirVolume_perc=>X360_005_SQ52070_VOL_PERC ,
       rOutAirVolume_m3_h=>X360_005_SQ52070_VOL_M3H ,
       wSensorValue=> ,
       rVmin=> ,
       rVmax=> ,
       xControlRangeIncreased=>X360_005_SQ52070_CRI ,
       xMecanicalOverload=>X360_005_SQ52070_MOL ,
       xActuatorHunting=>X360_005_SQ52070_AH ,
       xSensorError=> );
    
     

Log in to post a comment.