Checking vacuum while moving through multiple subroutines (PC TASK?)

  • Goodmorning guys! :help:
    I'm pretty new to Kawasaki and starting to learn a lot!
    So...now I have this challenge:
    I'm using a kawasaki FS06L with D71 Controller europe spec, to unload a pallet of coolers, and place these into multiple stations for coining, measuring and then placing it onto a leaktester line.
    The unload of the pallet (including trays) is working with vision!
    Now the goal I want to reach is that the robot checks on loosing the vacuum after it got vacuum, so after it picks up a cooler (vacuum sensor kicks in)
    Now if it looses the vacuum before I shut down the gripper (it moves through multiples subroutines), I want it to hold, and initialize it's home program, so the operator can put it home position manually and remove the cooler, then continue.
    Somehow it just doesn't accept an interrupt in my 4th PC program... how should I solve this? :hmmm:
    Also I am a beginner and could use some help with debugging my programs, because it's a little unstable with multiple variables counting up and down for requesting different vision models etc.
    And I'm a little worried with my 32 inputs and 32 outputs being used already, and on top of that I need so include multiple "Handshakes" with a PLC.
    Sorry for my bad english, still learning everyday!
    Thanks a lot in advance guys! The forum helped me out multiple times already! :dance2:

  • There are several elements to your question......
    But to address your initial question.


    If you are using the ON/ONI instruction, this is classed as a motion command and cannot be used in a PC Program.

    Quote

    Somehow it just doesn't accept an interrupt in my 4th PC program... how should I solve this? :hmmm:


    - Is this the way you are intending to monitor for the vacuum?
    - I ask, as it is more common to use the ON/ONI command specifically for this, in which case you have to place it in your main routine.
    - ON/ONI starts monitoring and IGNORE stops monitoring.
    - Take care using the CALL instruction with this, unless managed, the robot WILL return to the next instruction after the CALL.....and may result in unexpected motion.
    - I usually use this with a GOTO instead to prevent that.


    From the sounds of it though, you want to just hold the process.....until the operator interacts and carry on.
    But it depends on just when in the process it can lose the vacuum.....you would be carrying on with no part.
    - Or are you intending the operator to check the gripper is working, place the cooler back in the gripper and then carry on?


    If the operator is a necessity for a stoppage....then simplest way is to just hold the process and let the operator decide the best course of action.
    - Get them to check/reload the gripper and just carry on.
    - I would be tempted to just use a ONI and CALL vac_fail routine, set an immediate flag and have it 'conditionally paused' inside an IF/END or DO/UNTIL in that subroutine until a. gripper outputs on, b.part detected, c. vac sensor ok d. confirmation by the operator has been received and reset the flag and RETURN and carry on.
    - That way if someone just kept pressing cycle start, it would sit in the stoppage routine conditionally until all conditions met


    Many different ways to manage it, my opinion is always keep it simple as possible.......

  • Dear Kwakisaki! THANK YOU SO MUCH!
    I just thought a pc program would be easy for monitoring in the background so I didn't have to make a mess with interrupts through my entire program but I guess it can't be any other way.
    I'm currently busy with putting the ONI instructions into the subprograms where it picks up an object, and putting the ignores after my gripper is disabled (Thus: a ignore function at every drop point).
    I want the operator to manually move robot (with check-go) into home-pos doing the following: The interrupt will call "lost_object" wherein it will "BRAKE" Then a message will be prompted to my first IFdisplay to inform the operator it lost the object, then set a variable to 1, call go_home, then let the operator remove the lost object from the robot cell, then I want to continue somewhere else in my main program after he pressed cycle start; and in my go_home program it will check that same variable which makes sure that it does the following:
    lostobject = 0
    MC HOLD
    MC PRIME HOOFD,,44
    Otherwise it wil continue from where it went into interrupts and go to the next drop point without any object which can result in unnecessary waste of time.
    I'm understanding this is a possibility even when all my interrupts are located in different subroutines?
    My main program contains a lot of CALL functions so I think this way it is the most "stable possibility"?
    By the way, 2 things:
    What exactly do you mean with the setting the flag? (want to learn haha :fine: )
    And as soon as there is a chance that an object falls on the floor, it must be checked by other staff for deviations because of our high quality guarantee. So it's not the intention to let the operator place anything back in the gripper.
    Anyway, Thank you a lot for replying! You inspire me with the knowledge!
    Maybe if you're okay with it, we can keep contact using something more real-time than the forum?
    Thanks in advance! :beerchug:

  • PC Programs are natively for monitoring, background comms and non motion instructions and have low priority as they sit at the very end of the CPU clock cycle.
    Main priority is given to motion planning which is where all your motion instructions are executed and therefore the Main program area or 'foreground task' is for this purpose to maximise efficiently.
    Therefore the most efficient way of programming is to minimise non motion instructions by putting them in a PC Program.


    Unfortunately, when it comes to interrupting the motion planner, then this has to be given priority, so therefore ON/ONI is classed as a motion instruction and prevented from being used in a PC Program.........


    When I said 'flag' sorry old habits.......internal signals or true and false markers which get set.
    - So if you have individual programs for each part of the process....set a flag at the beginning and clear it at the end and maybe monitor for it to determine what the operator must do to restart after the interruption.
    - but you seem to be doing this already with lostobject = 0.......not the only way to do it, you could use TRUE or FALSE, or even 0 and -1......


    If the operator is not to put anything back in the gripper, then that part of process has not been completed, so therefore I would assume, that needs repeating....so just prime that part of the process from the start of the routine again.
    - By having your lost object routine to look for the 'lost object' flag in conjunction with a CASE statement to select the correct program based on process markers and MC PRIME xxxxx that way......excluding the step no......PRIME/MC PRIME will always prime from step 1 as a default without needing to enter a step no.
    - In the process routine always check at the beginning if a 'lost object' marker is set and then lock in a conditional statement and IF Panel message to force the operator to go into Teach Mode, manually move the robot clear, then Check/Go which would include motion to home, when it gets home, look for the dedicated signal for home and THEN reset any lost object/process markers.
    - So if the operator was to press cycle start.....nothing would happen...until recovered to home and home dedicated signal is set and flags reset.
    - Therefore you will always be in the correct program, correct location to restart that part of the process.


    Using PRIME and a step no. in automatic is not something I would recommend unless the step no. is part of the process that does some conditional checking first, otherwise you could move the robot to ANY location, and the PRIME,,step no may drive the robot through something.
    - However, I am not saying it's wrong, just something to consider perhaps......


    I prefer to share any knowledge I have via the forum as it may benefit others, but feel free to PM me, but I would recommend utilizing the forum as much as possible, as there are a lot of users who frequent it and many ideas and comments from several people aid to the learning experience, plus as you get more experience, you'll assist others too...

  • Hello all, I'm using a vacuum gripper, how to explain this? A sucker which moves down until it gets a vacuum! :icon_smile:
    I understand kwakisaki and I will use the forum as much as possible!
    However, I have a really large program so I don't know if it's appropriate to post it...
    I want to keep it simple but the disadvantage is: If I let the robot just continue after its motion stopped due to the interrupt when losing it's vacuum. It will proceed with the movement, thinking it's placing a cooler in the coining station, which requires PLC clearance etc. all and all it takes too much time because it's gonna be placed in 24/7 automotive production!
    What if I let it jump into a lost_object subroutine with my interrupt an just make it hold, without the homing etc. then the operator removes the lost object from robot cell. then when it presses cycle start (EXT.Cycle start via PLC) it start all the way on top of my main program.
    Would my lost_object program look like:
    .PROGRAM lost_object()
    BRAKE
    aantalgepakt = aantalgepakt+1 ;this is to tell my vision system it skips the current cooler handling so it's starts looking for the next one)
    currmodel = currmodel+1 ;ditto
    IFPDISP 1
    IFPWPRINT 1="LOST COOLER, GO TO HOME-POSITION, CHECK ROBOT CELL AND RESUME WITH CYCLE START"
    lostobject = 1
    TWAIT 5 (for displaying the message above, because in my home program it will immediately print something else!)
    CALL go_home
    .END
    The cycle through my home program, which is okay, then cycle start.
    Then on the end of my home program i made this:
    if Lostobject= true call hoofd (which is dutch for main)
    on the start of my main program i made:
    IF lostobject = true then goto afterlost (So it moves to the label afterlost, which is located where I want to let the robot continue!
    I hope this is gonna work!

  • :dance::beerchug::dance2:


    Excellent, I was just reading through, but difficult to visualize complete operation without 'hands on'.
    - I am very specific, so I would also 'destruct' test it also to see if any bugs present.
    - If any are found, you at least know that the 'core' programs are working.......and then resolve them etc.
    - If it operates in the way you intended, then WELL DONE.....always nice to see the results of hard work.


    You can post your filesave, it is allowed, but takes long time to scroll through............full file save is not too large.....but takes long time to scroll through it.
    - If I post code, I try and limit it to the main areas - maybe just program data.
    - Check out variation of SAVE command switches (/p, /l, /r etc) in AS Manual - Section 5.3 I think.........



    :cheer: :cheer: :cheer: :cheer: :cheer:

  • What do you mean with destruct test?
    I am testing at this moment and somehow it's doesn't listen to a Signalwat (SWAIT) instruction, it just continues without waiting for the signal. Checked my inputs, they're all off.
    I will put my filesave (program data) beneath here (including my I/F panel so some of you can simulate it if you want):


    .INTER_PANEL_D
    0,4,0,"TRAINING"," ON ON "," OFF OFF "," ",10,2,4,2219,2220,0
    4,4,0,"VisionLink"," OFF OFF "," ON ON ","1 ",10,2,4,2251,2254,0
    5,1," TCP Link"," "," 1"," ",10,15,4,0,2256,0
    6,1," TCP Act."," "," 1"," ",10,15,1,0,2255,0
    8,9,2,4,9
    12,9,3,1,0
    14,4,0," GRIPPER:"," VACUUM "," CLAMPING "," ",10,1,7,2202,2201,0
    15,9,1,4,6
    19,3," product"," search","","",10,4,13,0,0,2023,2024,0
    20,3," product"," pick","set","",10,4,13,0,0,2025,2026,0
    21,8,"invoernummer"," product"," number",10,11,3,1,0
    22,8,"invoerhoogte"," product","height(mm)",8,12,3,2,0
    23,8,"invoerhoek"," corner-"," rot.",9,12,5,2,0
    24,8,"invoerkantelx","tilt"," tool x",9,12,5,2,0
    25,8,"invoerkantely","tilt"," tool y",9,12,5,2,0
    26,3," save","values"," in ","database",10,4,13,0,0,2027,2028,0
    27,3," load","values"," from ","database",10,4,13,0,0,2021,2022,0
    28,4,0,"production"," OFF OFF ON ON "," ON ON "," ",10,2,4,2219,2220,0
    29,4,2,"VISIONLINK","OFF","ON","1",10,2,4,2251,2254,0
    30,4,2,"Calibrated?NO","NO","YES","",10,2,4,0,2001,0
    31,10,"LINEAIR","LEAVE","200MM","",10,4,6,0,"do ldepart 200",0
    32,4,2,"VACUUM","ON","OFF","",10,4,2,11,0,0
    35,8,"aantalgepakt"," caught","number",10,11,2,1,0
    36,8,"watzoeken","Where","start?",10,11,2,1,0
    37,8,"currmodel","currmodel","",10,11,2,1,0
    38,10,"GO HOME","","","",10,4,6,1,"do jmove #thuis",0
    42,8,"metkoeler","SPEED IN %","WITH COOLER",10,2,3,1,0
    43,8,"mettray","SPEED IN %","WITH TRAY",10,9,3,1,0
    44,8,"zonderobject","SPEED IN %","GENERAL",9,1,3,1,0
    45,10,"ZERO POS","IN CASE OF","CONTROLLER","SHUTDOWN",10,2,6,2,"do jmove #zero",0
    49,9,3,4,6
    .END
    .INTER_PANEL_COLOR_D
    182,3,224,244,28,159,252,255,251,255,0,31,2,241,52,219,
    .END
    .SIG_COMMENT
    .END
    .PROGRAM al()
    SPEED 100 ALWAYS
    ALIGN
    .END
    .PROGRAM autostart.pc()
    MC prime hoofd
    CALL tcpcomm
    .END
    .PROGRAM autostart2.pc()
    CALL pcif
    .END
    .PROGRAM autostart3.pc()
    CALL pc3
    .END
    .PROGRAM cameracheck()
    SPEED metkoeler ALWAYS
    JAPPRO #voorcamera,200
    ACCURACY 1
    JMOVE #voorcamera
    PULSE o_cam_start,1
    DO
    IF SIG(i_camera_goed) THEN
    CALL fsp3
    RETURN
    END
    IF SIG(i_camera_fout) THEN
    CALL nio
    RETURN
    END
    UNTIL FALSE
    RETURN
    .END
    .PROGRAM database()
    IFPDISP 1
    IF invoernummer<>invoernummeroud THEN
    invoernummeroud = invoernummer
    nr = invoernummer
    $nr = "["+$ENCODE(/I3,nr)+"]"
    IF EXISTCHAR("$db_model"+$nr) THEN
    IFPWPRINT 1="Model "+$nr+" selected: "+$db_model[nr]
    ELSE
    IFPWPRINT 1="Model "+$nr+" selected: vision name unkown yet"
    END
    END
    IF SIG(s_loadfromdb) THEN
    IF NOT SWITCH(TPKEY_S ) THEN
    IFPWPRINT 1="Use the S key with this button to load values from the database"
    SWAIT -s_loadfromdb
    GOTO next1
    END
    nr = invoernummer
    IF nr<1 OR nr>9999 THEN
    IFPWPRINT 1="Non-valid PRODUCTNUMBER"
    SWAIT -s_loadfromdb
    GOTO next1
    END
    $nr = "["+$ENCODE(/I,nr)+"]"
    IF NOT EXISTREAL("corr_rx"+$nr) THEN
    corr_rx[nr] = 0
    END
    IF NOT EXISTCHAR("$db_model"+$nr) THEN
    $db_model[nr] = "*"
    END
    IF NOT EXISTREAL("corr_ry"+$nr) THEN
    corr_ry[nr] = 0
    END
    IF NOT EXISTREAL("corr_rz"+$nr) THEN
    corr_rz[nr] = 0
    END
    IF NOT EXISTREAL("corr_z"+$nr) THEN
    corr_z[nr] = 0
    END
    IF NOT EXISTREAL("db_grijper"+$nr) THEN
    db_grijper[nr] = 0
    END
    invoerkantelx = corr_rx[nr]
    invoerkantely = corr_ry[nr]
    invoerhoogte = corr_z[nr]
    invoerhoek = corr_rz[nr]
    $lastfound = $db_model[nr]
    IF db_grijper[nr]==0 THEN
    SIGNAL s_vacuumgrijper,-s_klemgrijper
    ELSE
    SIGNAL -s_vacuumgrijper,s_klemgrijper
    END
    PULSE s_loadfromlamp,2
    IFPWPRINT 1="Values loaded from database"
    SWAIT -s_loadfromdb
    END
    IF SIG(s_savetodb) THEN
    IF NOT SWITCH(TPKEY_S ) THEN
    IFPWPRINT 1="Use the S button with this key to save values to database"
    SWAIT -s_savetodb
    GOTO next1
    END
    nr = invoernummer
    IF nr<1 OR nr>9999 THEN
    IFPWPRINT 1="NON-VALID PRODUCTNUMBER"
    SWAIT -s_savetodb
    GOTO next1
    END
    corr_rx[nr] = invoerkantelx
    corr_ry[nr] = invoerkantely
    corr_z[nr] = invoerhoogte
    corr_rz[nr] = invoerhoek
    $db_model[nr] = $lastfound
    IF SIG(s_vacuumgrijper) THEN
    db_grijper[nr] = 0
    ELSE
    db_grijper[nr] = 1
    END
    PULSE s_savetolamp,2
    IFPWPRINT 1="Values saved in database"
    SWAIT -s_savetodb
    END
    IF SIG(s_trainingon) THEN
    IF SIG(s_zoekknop,-s_zoeklamp) THEN
    IF SIG(-2254) THEN
    IFPWPRINT 1="Communication not active!"
    SWAIT -s_zoekknop
    GOTO next1
    END
    $gezochtmodel = $vismodellen[nr]
    SIGNAL s_zoeklamp
    maxmodel = 1
    modelcount = 0
    SWAIT -s_zoekknop
    TIMER (2) = 0
    SIGNAL -2252,2253
    IFPWPRINT 1="Search is activated"
    END
    IF SIG(s_zoeklamp,2252,-2253) THEN
    IF modelcount>0 THEN
    $iftxt1 = "Model "+$vismodellen[0]+" found: "
    $iftxt2 = "X: "+$ENCODE(/F6.1,visxvals[0])+"mm, Y: "+$ENCODE(/F6.1,visyvals[0])+"mm, ROT.: "+$ENCODE(/F5.1,vishoeken[0])+" deg."
    $iftxt3 = "Searchtime: "+$ENCODE(/I5,TIMER(2)*1000)+"ms"
    IFPWPRINT 1=$iftxt1,$iftxt2,$iftxt3
    testx = visxvals[0]
    testy = visyvals[0]
    testhoek = vishoeken[0]
    $lastfound = $vismodellen[0]
    ELSE
    IFPWPRINT 1="model not found"
    END
    SIGNAL -s_zoeklamp
    END
    END
    RETURN
    next1:
    TWAIT 2
    IFPWPRINT 1=""
    .END
    .PROGRAM fsp3()
    SPEED metkoeler ALWAYS
    SWAIT (i_wt_aanwezig)
    JAPPRO fsp3,500
    ACCURACY 1 ALWAYS
    LAPPRO fsp3,100
    SPEED 50 MM/S
    LMOVE fsp3
    SIGNAL -o_zuiger
    IGNORE 1013
    IF SIG(i_prog2) OR (i_prog3) THEN ;Same as in the program inpraegen because it needs to count to know where it's at.
    currmodel = currmodel+1
    aantalgepakt = aantalgepakt+1
    END
    SPEED zonderobject ALWAYS
    ACCURACY 500 ALWAYS
    TWAIT 0.2
    LDEPART 500
    PULSE o_fsp3,1
    JMOVE #thuis
    RETURN
    .END
    .PROGRAM go_home()
    IFPDISP 1
    check:
    IF SIG(-s_home) THEN
    IFPWPRINT 1,1,1,1,6="Robot isn\'t in home position. Jog robot to homeposition in TEACH mode with CHECK-GO"
    SWAIT s_teach
    SPEED 20
    cond = 0
    JMOVE #thuis
    SIGNAL -o_zuiger
    WHILE cond==0 DO
    IF SIG(-s_teach) THEN
    BRAKE
    GOTO check
    END
    IF SIG(s_home) THEN
    IFPWPRINT 1,1,1,1,6="Robot reached homeposition. The program can now be started with repeat."
    cond = 1
    IF lostobject==TRUE THEN
    RETURN
    END
    END
    END
    END
    IF SIG(-s_home) GOTO check
    .END
    .PROGRAM hoofd()
    GOTO afterlost IF lostobject==TRUE
    IFPDISP 2
    ;*************************************************************
    ;****** ******
    ;****** Main Program ******
    ;****** ******
    ;****** During startup: IO will be initialized ******
    ;****** Go to Home position in teach with check-go ******
    ;****** if not in home yet,then it starts ******
    ;****** a program depending on PLC signal and ******
    ;****** executes this. When looking for coolers:******
    ;****** order is: traycoordinates>pick 4 coolers ******
    ;****** >put tray away. ******
    ;****** ******
    ;*************************************************************
    CALL rfa
    CALL iolijst
    ; INIT SPEED & ACCURACY
    SPEED zonderobject ALWAYS
    ACCURACY 500 ALWAYS
    CALL go_home
    ; ******* Initialisatie Vision camera 1 ******
    ;
    SIGNAL -2254,2251
    TWAIT 1
    SIGNAL 2254,-2251
    ;
    IF SIG(-s_gekalibreerd) THEN
    CALL viscalib
    PAUSE
    END
    ; ************ Main Program *************
    begincheck:
    IF NOT (EXISTREAL("corr_rx"+$nr) AND EXISTREAL("corr_ry"+$nr) AND EXISTREAL("corr_rz"+$nr) AND EXISTREAL("corr_z"+$nr) AND EXISTREAL("db_grijper"+$nr) AND EXISTCHAR("$db_model"+$nr)) THEN
    IFPWPRINT 3="Model "+$nr+" isn\'t trained yet"
    IFPDISP 1
    PAUSE
    GOTO begincheck
    ELSE
    IFPDISP 2
    IFPWPRINT 3="Model "+$nr+" is active"
    END
    ;
    SIGNAL (o_readynaarplc) ;Output 21, io initialized, calibrated, program set.
    PAUSE ; Wait for EXT.cycle start from PLC!
    WHILE TRUE DO
    afterlost: lostobject = FALSE
    ; **** program according to PLC HMI choices *******
    programma1:;program 1
    IF SIG(i_prog1) THEN
    IF SIG(i_metengoed) THEN
    CALL uitmeten
    CALL fsp3
    END
    IF SIG(i_metenfout) THEN
    CALL uitmeten
    CALL nio
    END
    IF SIG(i_praegengoed) THEN
    CALL uitpraegen
    CALL inmeten
    END
    IF SIG(i_praegenfout) THEN
    CALL uitpraegen
    CALL nio
    END
    IF TRUE THEN ;SIG(i_palletinpos,-i_palletleeg) THEN
    CASE aantalgepakt OF
    VALUE 4,9,14,19: ;decides if it needs to pick up a tray after it took 4 objects etc.
    JMOVE #thuis
    CALL paktray
    JMOVE #viapos
    CALL trayweg
    IF aantalgepakt==20 THEN
    aantalgepakt = 0
    watzoeken = 1
    JMOVE #thuis
    SWAIT (i_palletinpos)
    END
    GOTO programma1
    VALUE 0,5,10,15: ;Decides if it needs to start a new search command.(4 stacks)
    JMOVE #thuis
    SIGNAL s_zoek1,-s_gevonden1
    CALL pak
    JMOVE #viapos
    CALL inpraegen
    GOTO programma1
    VALUE 1,2,3,6,7,8,11,12,13,16,17,18:
    JMOVE #thuis
    CALL pak
    JMOVE #viapos
    CALL inpraegen
    GOTO programma1
    END
    ELSE
    IFPWPRINT 3="Pallet isn\'t in position or empty"
    JMOVE #thuis
    PAUSE
    GOTO programma1
    END
    IF watzoeken>=8 THEN
    watzoeken = 1
    SWAIT (i_palletinpos)
    GOTO programma1
    END
    END
    ;;;
    programma2:;program 2
    IF SIG(i_prog2) THEN
    IF TRUE THEN ;SIG(i_palletinpos,-i_palletleeg) THEN
    CASE aantalgepakt OF
    VALUE 4,9,14,19: ;decides if it needs to pick up a tray after it took 4 objects etc.
    JMOVE #thuis
    CALL paktray
    JMOVE #viapos
    CALL trayweg
    IF aantalgepakt==20 THEN
    aantalgepakt = 0
    watzoeken = 1
    JMOVE #thuis
    SWAIT (i_palletinpos)
    END
    GOTO programma2
    VALUE 0,5,10,15: ;Decides if it needs to start a new search command.(4 stacks)
    JMOVE #thuis
    SIGNAL s_zoek1,-s_gevonden1
    CALL pak
    JMOVE #viapos
    CALL fsp3
    GOTO programma2
    VALUE 1,2,3,6,7,8,11,12,13,16,17,18:
    JMOVE #thuis
    CALL pak
    JMOVE #viapos
    CALL fsp3
    GOTO programma2
    END
    ELSE
    IFPWPRINT 3="Pallet isn\'t in position or empty"
    JMOVE #thuis
    PAUSE
    GOTO programma2
    END
    IF watzoeken>=8 THEN
    watzoeken = 1
    SWAIT (i_palletinpos)
    GOTO programma2
    END
    END
    ;
    programma3:
    IF TRUE THEN ; NORMALLY: IF SIG(i_prog3) THEN
    IF TRUE THEN ;SIG(i_palletinpos,-i_palletleeg) THEN
    CASE aantalgepakt OF
    VALUE 4,9,14,19: ;decides if it needs to pick up a tray after it took 4 objects etc.
    JMOVE #thuis
    CALL paktray
    JMOVE #viapos
    CALL trayweg
    IF aantalgepakt==20 THEN
    aantalgepakt = 0
    watzoeken = 1
    JMOVE #thuis
    SWAIT (i_palletinpos)
    END
    GOTO programma3
    VALUE 0,5,10,15: ;Decides if it needs to start a new search command.(4 stacks)
    JMOVE #thuis
    SIGNAL s_zoek1,-s_gevonden1
    CALL pak
    JMOVE #viapos
    CALL cameracheck
    GOTO programma3
    VALUE 1,2,3,6,7,8,11,12,13,16,17,18:
    JMOVE #thuis
    CALL pak
    JMOVE #viapos
    CALL cameracheck
    GOTO programma3
    END
    ELSE
    IFPWPRINT 3="Pallet isn\'t in position or empty"
    JMOVE #thuis
    PAUSE
    GOTO programma3
    END
    IF watzoeken>=8 THEN
    watzoeken = 1
    SWAIT (i_palletinpos)
    GOTO programma3
    END
    END
    END ; end of while
    .END
    .PROGRAM inmeten()
    SWAIT (-i_metenbezet) ;wait for empty measuring station.
    SPEED metkoeler ALWAYS ;speed with cooler
    JAPPRO meten,500
    ACCURACY 1 ALWAYS
    LAPPRO meten,100
    SPEED 50 MM/S
    LMOVE meten
    SIGNAL -o_zuiger
    IGNORE 1013
    SPEED zonderobject ALWAYS
    TWAIT 0.2
    LDEPART 200
    PULSE o_meten,1
    ACCURACY 500 ALWAYS
    JMOVE #thuis
    RETURN
    .END
    .PROGRAM inpraegen()
    IF lostobject==TRUE THEN
    RETURN
    END
    SWAIT (-i_praegenbezet) ;wait for empty coining station.
    SPEED metkoeler ALWAYS
    JAPPRO praegen,500
    ACCURACY 1 ALWAYS
    LAPPRO praegen,100
    SPEED 50 MM/S
    LMOVE praegen
    SIGNAL -o_zuiger
    IGNORE 1013
    currmodel = currmodel+1
    aantalgepakt = aantalgepakt+1
    TWAIT 0.2
    SPEED zonderobject ALWAYS
    LDEPART 200
    PULSE o_praegen,1
    ACCURACY 500 ALWAYS
    JMOVE #thuis
    RETURN
    .END
    .PROGRAM iolijst()
    ; Outputs (1 to 4 are a 1 second pulse to PLC).
    o_afkeurband = 1 ;Robot gives this signal when he put the cooler on the belt and is out of area.
    o_praegen = 2 ;Robot gives this signal saying that coining station is cleared to start.
    o_meten = 3 ;Robot gives this signal saying that measuring station is cleared to start.
    o_fsp3 = 4 ;Robot gives this signal saying that leaktesting tray is cleared to start transport cooler (out of area).
    o_cam_start = 5 ;Start camera check.
    o_grijperdicht = 9 ;Toggles double solenoid for clamping tool (optional).
    o_grijperopen = 10 ;ditto.
    o_zuiger = 11 ;toggles vacuumvalve.
    o_readynaarplc = 21 ;Robot tells PLC that IO-list is initialized and ready for cycle start.
    ;
    ; DEDICATED OUTPUT SIGNALS
    ; TEMPORARILY : 17 = ROBOT IN AUTOMATIC.
    ; 22 = DEDICATED HOME SIGNAL..
    ; 29 = CYCLE START
    ; 30 = ROBOT IN AUTOMATIC (NOW TEMPORARILY 17).
    ; 31 = ERROR.
    ; 32 = MOTOR POWER ON!.
    ;
    ; DEDICATED INPUTS SIGNALS.
    ;1030 = EXT.CYCLE.START.
    ;1031 = EXT.ERROR.RESET.
    ;1032 = EXT.MOTOR.ON.
    ;
    ; Inputs (From PLC to robot)
    ;
    ;Coining
    i_praegenbezet = 1001 ;PLC Tells robot coining station is occupied.
    i_praegenfout = 1003 ;PLC tells robot coining failed so it places cooler on NIO belt. (rejected cooler)
    i_praegengoed = 1017 ;PLC tells robot coining succeeded so it continues with placing it into measuring station.
    ; Measuring
    i_metenbezet = 1002 ;PLC tells robot measuring statio is occupied.
    i_metenfout = 1004 ;PLC tells robot measuring failed so it places cooler on NIO belt. (rejected cooler)
    i_metengoed = 1018 ;PLC tells robot measuring succeeded so it continues with placing it into FSP3 leaktesting station.
    ; NIO
    i_nioband_vol = 1019 ;NIO belt is full, Robot waits until it's cleared again.
    ;Traystacks
    i_traystacks_vo = 1020 ;Traystacks are full, robot waits until it's cleared by operator.
    ; FSP3
    i_wt_aanwezig = 1005 ;PLC tells robot that FSP3 offers an empty tray (on which the robot waits when measuring is finished) and directly places cooler onto leaktesting tray when receiving this signal.
    ;
    ;Camera
    i_camera_goed = 1006 ;PLC tells robot that the camera approved the cooler so it places the cooler onto FSP3 leaktesting tray when above signal is received!
    i_camera_fout = 1007 ;PLC tells robot that the camera rejected the cooler so it places the cooler onto NIO belt. (Cooler rejected)
    ;
    ;Pallet
    i_palletinpos = 1008 ;As long as the pallet is in position the program 1,2 or 3 will cycle. After 1 cycle of 16 coolers robot waits until it receives this signal from PLC.
    i_palletleeg = 1009 ;PLC tells robot that pallet is empty, Robot goes to home-position so the operator can reload the pallet station.
    ;
    ;Program mode from PLC ;after selection on HMI > EXT.CYCLE START from PLC.
    i_prog1 = 1010 ;pick, coining, measuring, FSP3.
    i_prog2 = 1011 ;pick, FSP3.
    i_prog3 = 1012 ;pick, cameracheck, FSP3.
    ;
    i_vacuum = 1013 ; &14,15,16 Occupied internally, not adjustable according to RFA mechanic.
    ;
    s_zoek1 = 2006
    s_zoekenactief1 = 2007
    s_gevonden1 = 2008
    ;
    ; DON'T ADJUST BECAUSE IT'S RELATED TO I/F Panel!
    s_trainingon = 2219
    s_trainingoff = 2220
    s_loadfromdb = 2021
    s_loadfromlamp = 2022
    s_savetodb = 2027
    s_savetolamp = 2028
    s_zoekknop = 2023
    s_zoeklamp = 2024
    s_pakkenknop = 2025
    s_pakkenlamp = 2026
    s_klemgrijper = 2201 ; gripperselection
    s_vacuumgrijper = 2202 ; gripperselection
    s_home = 22
    s_home2 = 2011
    s_teach = 2012
    ;
    aantalgepakt = 0 ;vacuumcounter
    watzoeken = 1 ;Selects wanted vision model (4 areas, 8 images: 1,3,5,7 = TRAY DETECTION. 2,4,6,8 = COOLER DETECTION)
    basisz = -80 ;This needs to be changed when robot is mounted on floor!
    lastdrop = 0 ;Keeping track of in which traystack it dropped the tray for the last time.
    lostobject = FALSE ;Lost object?
    currmodel = 0 ;Current cooler picknumber for coordinates arrayindex (point oppakpunt [] )
    metkoeler = 30 ; Speed for moving with cooler in percentage of total speed!
    mettray = 50 ; DITTO; speed with tray
    zonderobject = 100 ;Speed without cooler
    ; SIGNAL (-s_gekalibreerd) ;activate this line if you want to enable calibration everytime IO-list is getting initialized.
    .END
    .PROGRAM lost_object()
    BRAKE
    aantalgepakt = aantalgepakt+1
    currmodel = currmodel+1
    IFPDISP 1
    IFPWPRINT 1="LOST COOLER, GO TO HOME-POSITION, CHECK ROBOT CELL AND RESUME WITH CYCLE START"
    lostobject = TRUE
    TWAIT 5
    CALL go_home
    IFPWPRINT 3="PRIME hoofdprogramma"
    IFPDISP 2
    PAUSE
    .END
    .PROGRAM nio()
    SWAIT (-i_nioband_vol)
    SPEED metkoeler ALWAYS
    JMOVE #bovennio
    ACCURACY 1
    JMOVE #dropnio
    SIGNAL -o_zuiger
    IGNORE 1013
    TWAIT 0.2
    SPEED zonderobject ALWAYS
    PULSE o_afkeurband,1
    LDEPART 500
    JMOVE #thuis
    RETURN
    .END
    .PROGRAM pak()
    IF SIG(i_prog1) THEN ;DON'T pick up cooler when coining station is occupied (Program mode 1)
    SWAIT (i_praegenbezet)
    END
    begin:
    SPEED zonderobject ALWAYS
    IF db_grijper[prnum]==0 THEN
    currgrip = 0
    o_grijper1 = 11
    o_grijper2 = -11
    i_grijper = i_vacuum
    ELSE
    o_grijper1 = 10
    o_grijper2 = 9
    currgrip = 1
    i_grijper = 10 ; dummy, grijper dicht output gebruiken omdat er geen input is
    END
    TOOL toolnr[currgrip]
    SIGNAL -o_grijper1,o_grijper2
    JMOVE #thuis
    CASE aantalgepakt OF
    VALUE 0,5,10,15:
    SWAIT s_gevonden1
    END
    JMOVE #bovenpakken[currgrip]
    lastgrip = currgrip
    IF currmodel==3 THEN
    POINT oppakpunt = TRANS(visxvals[3],visyvals[3],basisz+corr_z[prnum],corr_rz[prnum]-vis1hoek,180,0)+RX(corr_rx[prnum])+RY(corr_ry[prnum])
    watzoeken = watzoeken+1
    END
    IF currmodel<3 THEN ;kan dit?
    POINT oppakpunt = TRANS(visxvals[currmodel],visyvals[currmodel],basisz+corr_z[prnum],corr_rz[prnum]-vis1hoek,180,0)+RX(corr_rx[prnum])+RY(corr_ry[prnum])
    END
    IF INRANGE(oppakpunt) OR INRANGE(oppakpunt+TRANS(0,0,-100)) THEN
    IFPWPRINT 3="Out of range"
    GOTO begin
    END
    ACCURACY 1 ALWAYS
    JAPPRO oppakpunt,100
    SIGNAL o_zuiger
    SPEED 50 MM/S
    XMOVE oppakpunt+TRANS(,,50) TILL i_vacuum
    SPEED metkoeler ALWAYS
    ONI -1013 CALL lost_object
    LDEPART 250
    ACCURACY 500 ALWAYS
    RETURN
    .END
    .PROGRAM paktray()
    SPEED zonderobject ALWAYS
    currmodel = 0
    begin:
    IF db_grijper[prnum]==0 THEN
    currgrip = 0
    o_grijper1 = 11
    o_grijper2 = -11
    i_grijper = i_vacuum
    ELSE
    o_grijper1 = 10
    o_grijper2 = 9
    currgrip = 1
    i_grijper = 10 ; dummy, grijper dicht output gebruiken omdat er geen input is
    END
    TOOL toolnr[currgrip]
    SIGNAL -o_grijper1,o_grijper2
    JMOVE #thuis
    SWAIT s_gevonden1
    JMOVE #bovenpakken[currgrip]
    lastgrip = currgrip
    POINT oppakpunt = TRANS(vis1xtray,vis1ytray,basisz+corr_z[prnum],corr_rz[prnum]-vis1hoektray,180,0)+RX(corr_rx[prnum])+RY(corr_ry[prnum])
    IF INRANGE(oppakpunt) OR INRANGE(oppakpunt+TRANS(0,0,-100)) THEN
    IFPWPRINT 3="Out of range"
    GOTO begin
    END
    ACCURACY 1 ALWAYS
    JAPPRO oppakpunt,100
    SIGNAL o_zuiger
    SPEED 50 MM/S
    XMOVE oppakpunt+TRANS(,,50) TILL i_vacuum
    SPEED mettray ALWAYS
    ONI -1013 CALL lost_object
    LDEPART 250
    ACCURACY 500 ALWAYS
    RETURN
    .END
    .PROGRAM pc3()
    1 IF SIG(s_trainingon) THEN
    CALL database
    END
    IF SIG(s_trainingoff) THEN
    CALL pcpallet
    END
    GOTO 1
    .END
    .PROGRAM pcif()
    WHILE TRUE DO
    IF BITS(s_trainingon,2)<>trainbitsoud THEN
    IF SIG(s_trainingoff) THEN
    IF WHICHTASK("hoofd")<0 THEN
    MC zpow off
    TWAIT 0.5
    MC prime HOOFD
    MC zpow on
    IFPDISP 2
    END
    ELSE
    IF WHICHTASK("testen")<0 THEN
    MC zpow off
    TWAIT 0.5
    MC prime testen
    MC zpow on
    IFPDISP 1
    END
    END
    trainbitsoud = BITS(s_trainingon,2)
    END
    END
    .END
    .PROGRAM pcpallet()
    startzoek: IF SIG(s_zoek1) THEN
    skipzoek:
    SIGNAL -s_zoek1,s_zoekenactief1
    modelcount = 0
    maxmodel = 4
    CASE watzoeken OF
    VALUE 1: ;Tray linksboven
    $gezochtmodel = $db_model[5]
    prnum = 5
    VALUE 2: ;Koelers linksboven
    $gezochtmodel = $db_model[1]
    prnum = 1
    VALUE 3: ;Tray rechtsboven
    $gezochtmodel = $db_model[6]
    prnum = 6
    VALUE 4: ;Koelers rechtsboven
    $gezochtmodel = $db_model[2]
    prnum = 2
    VALUE 5: ;Tray linksonder
    $gezochtmodel = $db_model[7]
    prnum = 7
    VALUE 6: ;Koelers linksonder
    $gezochtmodel = $db_model[3]
    prnum = 3
    VALUE 7: ;Tray rechtsonder
    $gezochtmodel = $db_model[8]
    prnum = 8
    VALUE 8: ;Koelers rechtsonder
    $gezochtmodel = $db_model[4]
    prnum = 4
    VALUE 0,9,10:
    IFPWPRINT 3="correct:\'Where start?\'"
    TWAIT 5
    GOTO skipzoek
    END
    SIGNAL -2252,2253 ; START VISION.
    END
    IF SIG(s_zoekenactief1,2252) THEN ; VISION COMPLETED
    IF visstatus==6 THEN
    IFPDISP 1
    IFPWPRINT 2="wanted model isn\'t trained in vision!","train the model!"
    SIGNAL -2254,2251
    TWAIT 5
    IFPDISP 2
    GOTO skipzoek
    ELSE
    IFPWPRINT 2="Searching goes well"
    END
    IF (modelcount>0) THEN
    IFPWPRINT 3="Objects found"
    CASE watzoeken OF
    VALUE 1,3,5,7:
    vis1xtray = visxvals[0]
    vis1ytray = visyvals[0]
    vis1hoektray = vishoeken[0]
    IF watzoeken==8 THEN
    GOTO skipzoek
    END
    watzoeken = watzoeken+1
    GOTO skipzoek
    END
    ELSE
    IFPWPRINT 3="Not found-->Where am I > Where start?"
    GOTO skipzoek
    END
    SIGNAL s_gevonden1,-s_zoekenactief1
    END
    ;
    GOTO startzoek
    .END
    .PROGRAM rfa()
    IFPDISP 1
    $text1 = " Robot is programmed by: "
    $text2 = " Brord van der Linden. "
    $text3 = " tel: 06-1173863? "
    $text4 = " brordquad@gmail.comhttps://nl.linkedin.com/in/brord-van-der-linden-665177115 "
    IFPWPRINT 1,1,1,4,2=$text1+$text2+$text3+$text4
    TWAIT 5
    IFPDISP 2
    RETURN
    .END
    .PROGRAM tcpcomm()
    ; Hoofd communicatie programma voor Vision Link
    ;
    ; PARAMETERS:
    ; signal: 2256 - output status van de link
    ; signal: 2255 - output link activiteit
    ; signal: 2254 - link aan/uit
    ; signal: 2253 - data klaar om te versturen
    ; signal: 2252 - data ontvangen
    ; signal: 2251 - force vision uit (ism 2254)
    ; signal: 2250 - reserved
    ; signal: 2249 - reserved
    ; real: stat - reserved
    ; real: tcpretval - reserved
    ; real: tcpsockid - reserved
    ; real: tcpsendcount - reserved
    ; real: tcprecvcount - reserved
    ; string: $tcpsenddata[] - reserved
    ; string: $tcprecvdata[] - reserved
    ; real: ip[] - in: [1..4] De delen van het IP van de Vision PC (1.2.3.4)
    ; real: port - in: Het poort nummer waar de Vision software op draait
    ; real: visstatus - uit: status van laatste vis aanvraag
    ; real: modelcount
    ; in: start index model array
    ; out: aantal in model array (gerekend vanaf 0)
    ; real: maxmodel
    ; in: maximum aantal models
    ; uit: aantal opgehaalde models
    ; string: $gezochtmodel - in: model dat gezocht wordt (leeg = alles)
    ; string: $vismodellen[] - uit: array met modelnamen
    ; real: visxvals[] - uit: array met x waarden voor modellen
    ; real: visyvals[] - uit: array met y waarden voor modellen
    ; real: vishoeken[] - uit: array met hoeken van modellen
    ;
    tcpsockid = -1 ; invalidate socket
    SIGNAL -2255,-2256 ; reset lampen
    tcpconnerrcnt = 0
    init: IF (SIG(-2254)) THEN
    CALL tcpcomm_close
    END
    SWAIT 2254
    CALL tcpcomm_connect
    IF tcpretval<0 THEN
    ; Error met TCP.. Retry maar
    CALL tcpcomm_close; // voor de zekerheid
    tcpconnerrcnt = tcpconnerrcnt+1
    IF tcpconnerrcnt>9 THEN
    ; 10x fout
    TYPE "Connectie met Vision kan niet gemaakt worden."
    TYPE "Controleer of Vision draait en het netwerk goed is aangesloten."
    tcpconnerrcnt = 0 ; reste voor volgende keer
    SIGNAL -2254,2251 ; Force Vision uit
    END
    GOTO init
    END
    tcpconnerrcnt = 0 ; Connectie gemaakt, reset dus
    ; wacht op signal
    wtrans: WAIT SIG(-2254) OR SIG(2253)
    ; wat hadden we?
    skipwait: IF SIG(-2254) THEN ; TCP uit
    CALL tcpcomm_close
    GOTO init
    END
    IF SIG(2253) THEN ; Data te versturen
    SIGNAL -2253
    GOTO senddata
    END
    GOTO wtrans ; Signaal moet veranderd zijn...
    senddata: $tcpsenddata[0] = "reqmodel|"+$gezochtmodel+"|"
    $tcpsenddata[0] = $tcpsenddata[0]+$ENCODE(/I10,maxmodel)
    tcpsendcount = 1
    CALL tcpcomm_send
    IF tcpretval<0 THEN
    IF tcpretval==-1 OR tcpretval==-2212 OR tcpretval==-2232 THEN ; socket was dicht!
    IF SIG(2254) THEN
    CALL tcpcomm_connect
    IF tcpretval>=0 GOTO senddata ; Probeer nog een keer
    CALL tcpcomm_close; voor de zekerheid
    visstatus = 0
    SIGNAL 2252
    GOTO init
    ELSE
    CALL tcpcomm_close; voor de zekerheid
    visstatus = 0
    SIGNAL 2252
    GOTO init ; Ik was eigenlijk uit
    END
    ELSE
    CALL tcpcomm_close
    visstatus = 0
    SIGNAL 2252
    GOTO init ; reset comms maar
    END
    END
    recvdata: CALL tcpcomm_recv
    IF tcpretval<0 THEN
    visstatus = 0
    SIGNAL 2252
    GOTO init ; Kan toch niet recoveren
    END
    ; data binnen, bekijk
    $temp = $DECODE($tcprecvdata[0],"|",0)
    IF $temp=="notfound" THEN
    $temp = $DECODE($tcprecvdata[0],"|",1) ; delete seperator
    $temp = $DECODE($tcprecvdata[0],"|",0)
    visstatus = VAL($temp)
    SIGNAL 2252
    GOTO wtrans
    END
    IF $temp=="found" THEN
    $temp = $DECODE($tcprecvdata[0],"|",1) ; delete seperator
    $temp = $DECODE($tcprecvdata[0],"|",0)
    temp = VAL($temp)
    IF temp<maxmodel THEN
    maxmodel = temp
    END
    IF maxmodel==0 THEN
    maxmodel = temp
    END
    i = 1
    count = 0
    FOR count = 0 TO maxmodel-1
    arrayindex = count+modelcount
    IF (LEN($tcprecvdata[0])<120) AND (i<tcprecvcount) THEN
    $tcprecvdata[0] = $tcprecvdata[0]+$tcprecvdata[i]
    i = i+1
    END
    $temp = $DECODE($tcprecvdata[0],"|",1) ; delete seperator
    $temp = $DECODE($tcprecvdata[0],"|",0)
    $vismodellen[arrayindex] = $temp
    $temp = $DECODE($tcprecvdata[0],"|",1) ; delete seperator
    $temp = $DECODE($tcprecvdata[0],"|",0)
    visxvals[arrayindex] = VAL($temp)
    pno = arrayindex
    $temp = $DECODE($tcprecvdata[0],"|",1) ; delete seperator
    $temp = $DECODE($tcprecvdata[0],"|",0)
    visyvals[arrayindex] = VAL($temp)
    $temp = $DECODE($tcprecvdata[0],"|",1) ; delete seperator
    $temp = $DECODE($tcprecvdata[0],"|",0)
    vishoeken[arrayindex] = VAL($temp)
    END
    modelcount = modelcount+maxmodel
    visstatus = 1
    SIGNAL 2252
    GOTO wtrans
    END
    ; foutieve data
    visstatus = 0
    maxmodel = 0
    SIGNAL 2252
    GOTO wtrans
    .END
    .PROGRAM tcpcomm_close()
    ;
    ; Sluit een socket
    ;
    ; PARAMETERS:
    ; real: tcpsockid - ID van socket. Wordt ook naar -1 gezet
    ;
    ; RETURN VALUE:
    ; geen
    ;
    IF tcpsockid<0 THEN
    TYPE "Socked already closed"
    RETURN
    END
    TCP_CLOSE stat,tcpsockid
    SIGNAL -2256
    tcpsockid = -1
    TYPE "Socked closed"
    .END
    .PROGRAM tcpcomm_connect()
    ; connect naar de opgegeven Vision PC
    ; Protocol versie: 1
    ;
    ; PARAMETERS:
    ; real: port - poort nummer van server
    ; real[1..4]: ip - IP van server
    ; real: tcpsockid - ID van socket. Wordt naar socket id gezet bij succes
    ;
    ; RETURN VALUE:
    ; real: tcpretval - socket nummer, of negatief bij error
    ;
    IF tcpsockid>=0 THEN
    TYPE "Socket already connected"
    CALL tcpcomm_close
    tcpretval = tcpsockid
    RETURN
    END
    TCP_CONNECT stat,port,ip[1]
    IF stat<0 THEN
    TYPE "Failed to connect to server"
    tcpretval = stat
    RETURN
    END
    tcpsockid = stat
    ;
    ; Connectie gemaakt, kijk of versies ed. kloppen
    ;
    nr = 1
    TCP_RECV stat,tcpsockid,$inarray[0],nr,10
    IF stat<0 THEN
    ; iedere error is fout bij connecten
    TYPE "Failed to receive welcome message"
    tcpretval = stat
    CALL tcpcomm_close
    RETURN
    END
    $temp = $DECODE($inarray[0]," ",0)
    IF $temp!="P1" THEN
    TYPE "TCP protocol mismatch"
    tcpretval = -1
    CALL tcpcomm_close
    RETURN
    END
    $temp = $DECODE($inarray[0]," ",1) ; Drop seperator
    TYPE $inarray[0]
    ;
    ; Connectie gereed
    ;
    SIGNAL 2256
    tcpretval = tcpsockid
    RETURN
    .END
    .PROGRAM tcpcomm_recv()
    ; Ontvang data over de socket
    ;
    ; PARAMETERS:
    ; real: tcpsockid - ID van socket
    ; string: $tcprecvdata[] - ontvangst buffer, beginnend bij index 0
    ; real: tcprecvcount - aantal ontvangen strings
    ;
    ; RETURN VALUE:
    ; real: tcpretval - 0 als OK, sock error id bij error, -1 bij geen sock
    ;
    ;
    IF tcpsockid<0 THEN
    TYPE "Socket isn\'t open"
    tcpretval = -1
    RETURN
    END
    SIGNAL 2255
    TCP_RECV stat,tcpsockid,$tcprecvdata[0],tcprecvcount,30,120
    DLYSIG -2255,1
    IF stat<0 THEN
    tcpretval = stat
    IF stat==-2212 THEN
    TYPE "Socket was remotely closed"
    CALL tcpcomm_close
    RETURN
    END
    IF stat==-2232 THEN
    TYPE "Socket locally closed without notice"
    tcpsockid = -1
    RETURN
    END
    RETURN
    END
    ;
    ; Data is ontvangen
    ;
    TYPE $tcprecvdata[0]
    tcpretval = 0
    RETURN
    .END
    .PROGRAM tcpcomm_send()
    ; Stuur data over de socket
    ; Verbreekt de verbinding als de socket remote gesloten is.
    ;
    ; PARAMETERS:
    ; real: tcpsockid - ID van socket.
    ; string: $tcpsenddata[] - te versturen strings, beginnend bij index 0
    ; real: tcpsendcount - aantal te versturen strings
    ;
    ; RETURN VALUE:
    ; real: tcpretval - 0 als OK, sock error id by error, -1 bij geen sock
    ;
    IF tcpsockid<0 THEN
    TYPE "Socket isn\'t open"
    tcpretval = -1
    RETURN
    END
    SIGNAL 2255
    TYPE $tcpsenddata[0]
    TCP_SEND stat,tcpsockid,$tcpsenddata[0],tcpsendcount,15
    ;TYPE $tcpsenddata[0]
    DLYSIG -2255,1
    IF stat<0 THEN
    tcpretval = stat
    IF stat==-2209 THEN
    TYPE "To much data for socket"
    RETURN
    END
    IF stat==-2212 THEN
    TYPE "Socket was remotely closed"
    CALL tcpcomm_close
    RETURN
    END
    IF stat==-2232 THEN
    TYPE "Socket locally closed without notice"
    tcpsockid = -1
    RETURN
    END
    END
    ;
    ; Data is verzonden
    ;
    tcpretval = 0
    RETURN
    .END
    .PROGRAM testclamps()
    1 SIGNAL o_zuiger
    SWAIT i_vacuum
    TWAIT 2
    SIGNAL -o_zuiger
    IGNORE 1013
    TWAIT 0.2
    TWAIT 2
    GOTO 1
    .END
    .PROGRAM testen()
    lastgrip = -1
    CALL testpakken
    .END
    .PROGRAM testpakken()
    SPEED zonderobject ALWAYS
    begin:
    IF SIG(s_vacuumgrijper) THEN
    currgrip = 0
    ELSE
    currgrip = 1
    END
    IF currgrip<>lastgrip THEN
    TOOL toolnr[currgrip]
    JMOVE #bovenpakken[currgrip]
    lastgrip = currgrip
    END
    POINT oppakpunt = TRANS(testx,testy,basisz+invoerhoogte,invoerhoek-testhoek,180,0)+RX(invoerkantelx)+RY(invoerkantely)
    JMOVE SHIFT(oppakpunt BY 0,0,0)-TRANS(0,0,100)
    LMOVE SHIFT(oppakpunt BY 0,0,0)
    BREAK
    LMOVE SHIFT(oppakpunt BY 0,0,0)-TRANS(0,0,100)
    GOTO begin
    .END
    .PROGRAM testtool()
    JMOVE #bovtest1
    LMOVE SHIFT(testtool BY 0,0,30)
    LMOVE SHIFT(testtool BY 0,0,0)
    BREAK
    LMOVE SHIFT(testtool BY 0,0,30)
    JMOVE #bovtest1
    JMOVE #bovtest2
    LMOVE SHIFT(testtool BY 0,0,30)+RZ(180)
    LMOVE SHIFT(testtool BY 0,0,0)+RZ(180)
    BREAK
    LMOVE SHIFT(testtool BY 0,0,30)+RZ(180)
    JMOVE #bovtest2
    .END
    .PROGRAM trayweg()
    SWAIT (-i_traystacks_vo) ;Wait for empty traystack station.
    SPEED mettray ALWAYS
    ACCURACY 10 ALWAYS
    IF lastdrop==1 THEN
    JMOVE #bovendrop2
    LMOVE #droptray2
    SIGNAL -o_zuiger
    IGNORE 1013
    aantalgepakt = aantalgepakt+1
    LMOVE #bovendrop2
    lastdrop = 2
    ELSE
    JMOVE #bovendrop1
    LMOVE #droptray1
    SIGNAL -o_zuiger
    IGNORE 1013
    aantalgepakt = aantalgepakt+1
    SPEED zonderobject ALWAYS
    LMOVE #bovendrop1
    lastdrop = 1
    END
    ACCURACY 500 ALWAYS
    JMOVE #thuis
    RETURN
    .END
    .PROGRAM uitmeten()
    IF SIG(i_metenbezet) THEN
    SPEED zonderobject ALWAYS
    JAPPRO meten,500
    ACCURACY 1 ALWAYS
    LAPPRO meten,50
    SIGNAL o_zuiger
    SPEED 50 MM/S
    XMOVE meten+TRANS(,,50) TILL i_vacuum
    ONI -1013 CALL lost_object
    SPEED metkoeler ALWAYS
    LDEPART 200
    ACCURACY 500 ALWAYS
    END
    RETURN
    .END
    .PROGRAM uitpraegen()
    IF SIG(i_praegenbezet) THEN
    SPEED zonderobject ALWAYS
    JAPPRO praegen,500
    ACCURACY 1 ALWAYS
    LAPPRO praegen,50
    SIGNAL o_zuiger
    SPEED 50 MM/S
    XMOVE praegen+TRANS(,,50) TILL i_vacuum
    ONI -1013 CALL lost_object
    SPEED metkoeler ALWAYS
    LDEPART 200
    ACCURACY 500 ALWAYS
    END
    RETURN
    .END
    .PROGRAM vacuumtest()
    ;CAUTION ROBOT WILL MOVE! WATCH OUT FOR OBJECTS IN RANGE
    SPEED 100 ALWAYS
    tellertje = 0
    SPEED 10
    JMOVE #gestrekt
    TWAIT 5
    SIGNAL o_zuiger
    TWAIT 10
    1 JMOVE #testpos1
    TWAIT 2
    JMOVE #testpos2
    TWAIT 2
    tellertje = tellertje+1
    IF tellertje>=5 THEN
    GOTO einde
    ELSE
    GOTO 1
    END
    einde:
    SPEED 10
    JMOVE #gestrekt
    TWAIT 10
    SIGNAL -o_zuiger
    IGNORE 1013
    .END
    .PROGRAM viscalib()
    SPEED 10 ALWAYS
    ACCURACY 1 ALWAYS
    JMOVE calib1
    WHILE SIG(-s_gekalibreerd) DO
    LMOVE calib1
    TWAIT 2
    LMOVE calib2
    TWAIT 2
    LMOVE calib4
    TWAIT 2
    LMOVE calib3
    TWAIT 2
    END
    JMOVE #thuis
    SPEED 100 ALWAYS
    RETURN
    .END

  • .....'destruct test'.......sorry old habits again..............


    - Not in the literal sense obviously, but when I make mods/create new I always test it out for holes/bugs....that's what I meant.
    - If I can introduce issues conventionally from a 'day to day' operation, then I consider it potentially weak...
    - In my experience, operators (not intentionally) highlight these during use, especially if there is an element of interaction on their part.
    - The worse part of applying a change is being half way up the road and receiving a phone call.
    - Returning and discovering an oversight......I call it 'belt and braces'.
    - Purely dependent on just how complex the mod/change has been of course........


    Which SWAIT commands are you referring to - there are many?
    - Never use SWAIT with signals within parenthesis (brackets), the command is 'evaluated' instead.
    - The result is NOT the signal no. you are waiting for, so therefore it doesn't wait.
    - I would check this......but definately remove the parentheses from all commands like:
    - SWAIT (i_wt_aanwezig), SWAIT (i_palletinpos), SWAIT (-i_metenbezet) etc etc...
    - I think this maybe where your problem is.

  • They are required in that context....'if it is THEN' Do something......if not, GOTO or ELSE or END.
    - So very basic OR gate if required.


    SWAIT, this an actual condition command it is dedicated for exact SIGNALS status match and prevents forward planning until the signal condition matches the command.
    - It also produces a 'pause' icon on the teach pendant - teach screen too.


    You can also use a WAIT command, but WAIT is not specific to signals, it can have multiple conditional checks such as signals, variables and timer values - but does not produce a 'pause' icon.


    You could write it like:
    WAIT (SIG(1001) AND SIG(1) AND NOT SIG(2001)); is exactly the same.


    Usually it is purely the programmers preference that you get variations of 'waiting', and so don't be surprised if you come across WAIT for signals instead of SWAIT.
    - I believe SWAIT was introduced in the AS language later on as a command.

Advertising from our partners