BGLOGIC code that I have found useful

  • FYI, prior to HandlingTool v8.3, BGLogic could be used for state-machine logic control, but it was more cumbersome, since without JMP-LBL, you could not create code-blocks that would only run if certain conditions were met. Every line would be executed every scan.


    Now, IF-THEN-ENDIF can be used in BGLogic, so that you can create cleaner-looking state-machines, for example, in BGLogic, since only the instructions within a specific IF-THEN-ENDIF code-block might be the only thing executed until a condition is met.


    An IF-THEN-ENDIF block of code could be the only code executing in a BGLogic program when a state-number register is set to a specific state number. Then when the state-transition condition occurs, an IF statement that monitors the transition condition within the IF (R[nnn:MyState]=<State1Num>) THEN-ENDIF block would assign <State2Num> to R[nnn:MyState], and then the IF (R[nnn:MyState]=<State2Num>) THEN-ENDIF code-block would start executing.


    example 'code':


    <always-run code here for start-of-scan processing or some conditional reset code, etc. For example, a watchdog time counter:>
    R[10:ScanTimeCounter]=R[10:ScanTimeCounter]+1;


    ! State 10, initialize ;
    IF (R[10:ConveyorState]=10) THEN ;
    <initialize registers or outputs> ;
    ! wait for the start/enable signal ;
    IF (F[1:IndexConv]) THEN ;
    <do cycle inits or wait for an index signal, or possibly kick off index from here>
    R[10:ConveyorState]=1000 ;
    ENDIF ;
    ENDIF ;


    ! State 1000, begin index ;
    IF (R[10:ConveyorState]=1000) THEN ;
    GO[1:ConvSpeed]=1000 ;
    DO[1:RunConvFwd]=ON ;
    R[12:WatchdogCount]=R[10:ScanTimeCounter] ;
    ! Just one-shot & goto State 2000 ;
    R[10:ConveyorState]=2000 ;
    ! (It would be nice to have a JMP-LBL to end of program right here to do some check-code every scan prior to a subsequent state after a transition, but there are other ways to do that too.) ;
    ! (in this case it executes the subsequent state immediately, which could be preferred.) ;
    ENDIF ;


    !State 2000, wait for slow zone ;
    IF (R[10:ConveyorState]=2000) THEN ;
    ! Wait til slow-down sensor ;
    ! Transition condition... ;
    IF (DI[2:SlowSensor]),
    ! set slow speed... ;
    GO[1:ConvSpeed]=50 ;
    ! Reset watchdog... ;
    R[12:WatchdogCount]=R[10:ScanTimeCounter] ;
    ! and go to State 3000 ;
    R[10:ConveyorState]=3000 ;
    ENDIF ;
    ! Check for Watchdog ;
    IF ((R[12:WatchdogCount]+42)<R[10:ScanTimeCounter]) THEN ;
    ! Something bad may have happened, better handle it immediately ;
    <stop conveyor, set alarm, set error register value, go back to State 10, etc.>
    ENDIF ;
    ENDIF ;


    !State 3000, wait for stop signal ;
    IF (R[10:ConveyorState]=3000) THEN ;
    ! Wait til stop sensor ;
    ! Transition condition... ;
    IF (DI[3:StopSensor]),
    ! stop conveyor... ;
    DO[1:RunConvFwd]=OFF ;
    ! set speed back to default... ;
    GO[1:ConvSpeed]=1000 ;
    ! Reset watchdog... ;
    R[12:WatchdogCount]=R[10:ScanTimeCounter] ;
    ! and go to State 4000 ;
    R[10:ConveyorState]=4000 ;
    ENDIF ;
    ! Check for Watchdog ;
    IF ((R[12:WatchdogCount]+22)<R[10:ScanTimeCounter]) THEN ;
    ! Something bad may have happened, better handle it immediately ;
    <stop conveyor, set alarm, set error register value, go back to State 10, etc.>
    ENDIF ;
    ENDIF ;


    <State 4000, etc...>


    <end-of-scan always-run code>


    END ;



    (Can someone confirm that JMP-LBL can still not be used in v8.30? I don't have access at the moment. It would still be useful in an IF-THEN-ENDIF state-machine program in BGLogic. I know for a fact I can put a JMP in a BGLogic program without a fault in v8.30, but I didn't realize it might not work, and the program in question would actually work fine without the JMP being functional. It's only purpose was to force only one code-block to run per scan, so at transition, it JMPs to the end, but if the JMP wasn't executing, it would only execute the subsequent state code-block 1 scan early.)


    For older versions, you could use a lot of IF (<mixed logic>), <assignment> statements with the State register check in every IF statement:


    ! State 1000, begin index ;
    IF (R[10:ConveyorState]=1000), GO[1:ConvSpeed]=1000 ;
    IF (R[10:ConveyorState]=1000), DO[1:RunConvFwd]=ON ;
    IF (R[10:ConveyorState]=1000), R[12:WatchdogCount]=R[10:ScanTimeCounter] ;
    ! Just one-shot & goto State 2000 ;
    IF (R[10:ConveyorState]=1000), R[10:ConveyorState]=2000 ;



    !State 2000, wait for slow zone ;
    ! Wait til slow-down sensor ;
    IF ((R[10:ConveyorState]=2000) AND DI[2:SlowSensor]),R[10:ConveyorState]=2100 ;
    ! Check for Watchdog ;
    ! If Watchdog, go to an unique error state to handle the condition... ;
    IF ((R[10:ConveyorState]=2000) AND ((R[12:WatchdogCount]+42)<R[10:ScanTimeCounter])),R[10:ConveyorState]=9200 ;



    !State 2100, respond to reaching slow sensor ;
    ! 1st set slow speed... ;
    IF (R[10:ConveyorState]=2100),GO[1:ConvSpeed]=50 ; ;
    ! Reset watchdog... ;
    IF (R[10:ConveyorState]=2100),R[12:WatchdogCount]=R[10:ScanTimeCounter] ;
    ! and go to State 3000 ;
    IF (R[10:ConveyorState]=2100),R[10:ConveyorState]=3000 ;



    !State 3000, wait for stop signal ;
    ! Wait til stop sensor ;
    IF ((R[10:ConveyorState]=3000) AND DI[3:StopSensor]),R[10:ConveyorState]=3100 ;
    ! Check for Watchdog ;
    ! If Watchdog, go to an unique error state to handle the condition... ;
    IF ((R[10:ConveyorState]=3000) AND ((R[12:WatchdogCount]+22)<R[10:ScanTimeCounter])),R[10:ConveyorState]=9300 ;



    !State 3100, respond to stop signal ;
    ! stop conveyor... ;
    IF (R[10:ConveyorState]=3100),DO[1:RunConvFwd]=OFF ;
    ! set speed back to default... ;
    IF (R[10:ConveyorState]=3100),GO[1:ConvSpeed]=1000 ;
    ! Reset watchdog... ;
    IF (R[10:ConveyorState]=3100),R[12:WatchdogCount]=R[10:ScanTimeCounter] ;
    ! and go to State 4000 ;
    IF (R[10:ConveyorState]=3100),R[10:ConveyorState]=4000 ;

    - Jay


  • Can someone confirm that JMP-LBL can still not be used in v8.30? I don't have access at the moment. It would still be useful in an IF-THEN-ENDIF state-machine program in BGLogic. I know for a fact I can put a JMP in a BGLogic program without a fault in v8.30, but I didn't realize it might not work, and the program in question would actually work fine without the JMP being functional. It's only purpose was to force only one code-block to run per scan, so at transition, it JMPs to the end, but if the JMP wasn't executing, it would only execute the subsequent state code-block 1 scan early.)


    Just confirmed in RoboGuide, conditional and non-conditional jump label work at least as far back as V7.70.

    Check out the Fanuc position converter I wrote here! Now open source!

    Check out my example Fanuc Ethernet/IP Explicit Messaging program here!

  • Hello,
    I have FANUC R-30iB Plus Controller and I want to clean welding torch after startup. I use code similar this (I don't use it in BGlogic, but in standard welding program):


    Code
    IF (!F[1:CLEANED]), DO[100] = PULSE [2s]
     F[1:CLEANED]=(ON)


    It works, but I have problem. Flag F[1] does not set to OFF after startup. It still ON.
    We switch off controller directly by the main switch.


    Is there any other configuration?
    Thank you.

    Edited once, last by Petan ().

  • just use the BG logic to set the flag, then reset it in the torch cleaning program, somewhere at the end.


    EDIT:


    Or even better - instead of BG-logic, use an initialisation program which would start at Hot- and Cold-Start (make sure it has no motion group and"ignore pause" set to TRUE), which would set the flag (or even the DO directly). Then use it to call the cleaning program and reset the flag/DO at the end of the program.

    Edited once, last by bidzej ().

  • Thank you,
    If I understand I use HOT START when Switch OFF and ON just with main switch on the front panel of the cabinet. Tha's why Flags is not going to FALSE after reboot.


    How I can start program after start (after init)? I use Remote control.


    There is not any variable "first scan" like PLC?

  • Hot-Start is used only if the robot is configured to perform it. Normally, after cycling power, the controller performs a Cold-Start. I've mentioned both just to be sure, that the program is always executed after powering up, regardless of the starup method being used.


    There is no such thing as a dedicated "first scan" signal. You can evaluate UOP signals in the PLC to determine that the robot has just powered up and started the system, but the robot itself doesn't have it.


    And as for starting the program - depends on what you actually want to do. You can write that "init" program to set a given flag or DO, like that:


    Code
    F[1: pre-check cleaning] = ON


    then use the flag in the robot's main program (if you use one):


    Code
    ...
    IF F[1: pre-check cleaning]=OFF, JMP LBL[1]
    CALL Cleaning
    LBL[1 : skip cleaning]
    ...


    and as I've written before, reset the flag to OFF in the program Cleaning as soon as the process is complete.


    If there is no single main program in the robot which selects tasks based on orders from PLC, but rather a bunch of programs that are directly started by the PLC (like multiple PNSs, RSRs etc.), use a DO instead of the flag and write logic in the PLC to first call the cleaning program if the DO is set to on. Then reset the DO back to OFF at the end of the program and that's it.

  • Probably I will solve it with DI, or I will set Flag to OFF when IMSTP is FALSE (in BG logic). I use PNS in my application. It doesn't matter if the torch will clean after press emergency stop.


    But I still don't know, why restart of controller do not turn flags to false.
    There is this text in manual:



    That's why I think I use HOT start after cycle power. I would like to set flags to FALSE after start the controller. Either way, COLD start is standard start procedure (I hope). But unfortunately I don't know how to set COLD start to default start.

  • Hello,
    One thing I found very useful is the shifted override.
    Instead of going from 5 to 5%, when you activate $SHFTOV_END=1 then it goes 100-50-5-1 and the same way back.
    Great for integrators but it's better to disable it for real production :icon_wink:

  • well, this has nothing to do with BG-Logic.
    The variable you mentioned is usually set to 1 in smaller robots (like ArcMates), so the override can be set in steps 1-25-50-100[%].
    But you're right, better to leave it at 0 in bigger ones.

  • 6: --eg:Initialize Strobe ;
    7: !-------------------------------- ;
    8: IF (F[42:OFF:Flasher .2sec]=OFF),F[43:OFF:Flasher .5sec]=PULSE,1.0sec ;
    9: IF (F[43:OFF:Flasher .5sec]=OFF),F[42:OFF:Flasher .2sec]=PULSE,1.0sec ;
    10: IF ($PWRUP_DELAY.$SY_READY=0),F[42:OFF:Flasher .2sec]=(ON) ;


    This always helped me. These two flags pulse back and forth. Also, you don't have to worry about initializing it because it triggers when the sysvar PWRUP_DELAY is complete.


    I always use these flashers, and maybe more than just two, to indicate to operators what's happening if I only have a stack light with the standard 3 colors (Green=Running, Red=Faulted, Amber=Hold). Then I can flash the yellow or other colors for other action items.


    Example below. When the inbound stack of parts is running out, i would indicate to the fork truck operator to prepare a new skid of parts.


    1: !-------------------------------- ;
    2: !Background Logic ;
    3: !-------------------------------- ;
    4: ;
    5: ;
    6: --eg:Initialize Strobe ;
    7: !-------------------------------- ;
    8: IF (F[42:OFF:Flasher .2sec]=OFF),F[43:OFF:Flasher .5sec]=PULSE,1.0sec ;
    9: IF (F[43:OFF:Flasher .5sec]=OFF),F[42:OFF:Flasher .2sec]=PULSE,1.0sec ;
    10: IF ($PWRUP_DELAY.$SY_READY=0),F[42:OFF:Flasher .2sec]=(ON) ;
    11: ;
    12: --eg:Flash Lights to Indicate to Operator Inspect Part is ready ;
    13: !-------------------------------- ;
    14: IF (F[15:OFF:Low Stack SrchVis]=ON),UO[3:OFF:Prg running]=(F[42:OFF:Flasher .2sec]) ;
    15: IF (F[15:OFF:Low Stack SrchVis]=ON),UO[5:OFF:Motion held]=(F[42:OFF:Flasher .2sec]) ;
    16: IF (F[15:OFF:Low Stack SrchVis]=ON),UO[6:ON :Fault]=(F[42:OFF:Flasher .2sec]) ;
    17: ;
    18: --eg:If UO is on or if Flasher is on Turn light On ;
    19: !-------------------------------- ;
    20: IF ((F[15:OFF:Low Stack SrchVis]=ON AND F[42:OFF:Flasher .2sec]=ON) OR UO[3:OFF:Prg running]=ON),DO[1017:OFF:Intrcnct EXGOP]=(ON) ;
    21: IF (F[15:OFF:Low Stack SrchVis]=OFF AND UO[3:OFF:Prg running]=OFF),DO[1017:OFF:Intrcnct EXGOP]=(OFF) ;
    22: ;
    23: IF ((F[15:OFF:Low Stack SrchVis]=ON AND F[42:OFF:Flasher .2sec]=ON) OR UO[5:OFF:Motion held]=ON),DO[1018:OFF:Intrcnct EMGTP]=(ON) ;
    24: IF (F[15:OFF:Low Stack SrchVis]=OFF AND UO[5:OFF:Motion held]=OFF),DO[1018:OFF:Intrcnct EMGTP]=(OFF) ;
    25: ;
    26: IF ((F[15:OFF:Low Stack SrchVis]=ON AND F[42:OFF:Flasher .2sec]=ON) OR UO[6:ON :Fault]=ON),DO[1019:OFF:Intrcnct EMGEX]=(ON) ;
    27: IF (F[15:OFF:Low Stack SrchVis]=OFF AND UO[3:OFF:Prg running]=OFF),DO[1019:OFF:Intrcnct EMGEX]=(OFF) ;




    Also, mapping your UOPs to virtual bits is slick too. (Rack 0, Slot 0, Start 1-1000) Then, you can have ALL THE POWER!

  • We often want to send a negative value to the robot for either an offset modifier, or to modify other registers.


    We use mostly 16-bit words to communicate a negative number actually subtracts from the high end 65535, so when the PLC sends a -1 it actually sends to the robot 65535, we modify that using a BG Logic program similar to this:


    1: IF (GI[X]<=32768), R[X]=(GI[X])
    2: IF (GI[X]>32768), R[X]=(GI[X]-65536)


    which sets the GI's to a register and gives them the appropriate sign, this does obviously limit your total value options to -32,768 thru 32,768; but we rarely need a value higher than 10,000.

  • Hi,
    I want to start the robot with an external button (no PLC). I also want to give operator an external reset button.
    Always the same program (Program Select = OTHER, $shell_wrk.$cust_name : MAIN)


    I'm thinking that I need to monitor the state of the buttons through BGLOGIC.


    Can anyone help with BGLOGIC and I/O config setup please?


    Thanks,
    Tom

  • So configure UI[5: FAULT RESET] and UI[6: START] to the same points as my digital inputs DI[5] & DI[6] and wire my switches to the DIs locations.


    Then for example my start button on DI[6] will activate UI[6:START] to move the robot, right?

  • You will actually want UI[18] production start, in order to start your Main program. UI[6] will start the currently selected program, not necessarily Main, or it can be set to continue only in the system config. I suggest making start for continue only = true.


    The UI signals don't have to be mapped to any specific DI'S, just make sure they are set to the correct rack, slot , start point for your push buttons.


    Sent from my SM-G930V using Tapatalk

  • Here is a code that I found useful....


Advertising from our partners