Posts by brordautomation

    Hey guys!
    How to determine which port is need to be set up in KR-Term?
    I'm a little confused, clicked in the crosscable.. network settings in controller are:
    IP 192.168.0.2
    Host: (empty)
    Subnet 255.255.255.0
    The rest is empty as well, so when setting up the TCP/IP connection in KR-Term I need to set the IP above? Or the IP that ipconfig command gives me??!
    And then ... the tricky one is finding the port number.. tried every port that showed up in windos commandprompt with netstat -a...
    Someone please give me a quick push in the right direction so I will understand this just a bit better! Thanks a lot!


    Are we discussing ABB code and what it means?
    - If so, this will need to moved to ABB forum.


    Partly yes, but it's because I want something similar for the Kawasaki.
    Can we also teach something like working areas? I know you can use working areas to trigger a signal. but for guidance back to a home position?
    I want the operator to press one of the buttons located on around the working cell>robot finishes the "putaway" cycle and then moves to home.
    Then it releases the gate locks and the gates can be opened. But there's one button for each door, opening independently so I think this is done through our PLC. Maybe it's more simple than I thought but it's about safety so I'm gonna put a little more study into this haha!

    Here I have a homing program for a ABB robot, which only reaches linearly into machines, typical pick and place software.
    Not 100% sure I understand it, but it matches with Kwakisaki's 2nd recovery program, but then it's not only comparing it's height but also the X and Y value in relation to the WObj0 (which is the default work object in ABB)


    MODULE Home
    ! Send robot to home position
    ! ***************************************************
    PROC go_to_Home()
    ConfJ\On;
    ConfL\On;
    pActposhome := CRobT(\Tool:=Tool_1 \WObj:=Wobj0);
    IF pActposhome.trans.Z < 850 THEN
    pActposhome.trans.z := 990;
    MoveL pActposhome, v300, fine, Tool_1;
    ENDIF
    IF pActposhome.trans.Z > 1000 THEN
    pActposhome.trans.z := 1000;
    MoveL pActposhome, v300, fine, Tool_1;
    ENDIF
    IF pActposhome.trans.X > 1000 THEN
    pActposhome.trans.X := 750;
    MoveL pActposhome, v300, fine, Tool_1;
    ENDIF
    IF pActposhome.trans.Y > 800 THEN
    pActposhome.trans.Y := 400;
    MoveJ pActposhome, v300, fine, Tool_1;
    ENDIF
    MoveJ pHome, v300, z10, Tool_1;
    ENDPROC


    ! Send robot to base position 1 ( Product_pickup )
    ! **************************************************
    PROC Base_position_1()
    MoveJ pBase_1, SpdToolNoEmpty, z100, Tool_1;
    ENDPROC


    ! Send robot to base position 2
    ! *********************************
    PROC Base_position_2()
    MoveJ pBase_2, SpdToolNoEmpty, z200, Tool_1;
    ENDPROC


    ! Send robot to base position 3
    ! *********************************
    PROC Base_position_3()
    MoveL pBase_3, SpdToolNoEmpty, z200, Tool_1;
    ENDPROC


    ! Send robot to base position 4
    ! *********************************
    PROC Base_position_4()
    Movej pBase_4, SpdToolEmpty, z200, Tool_1;
    ENDPROC

    ! Send robot to base position 5
    ! *********************************
    PROC Base_position_5()
    MoveJ pBase_5, SpdToolEmpty, z200, Tool_1;
    ENDPROC

    ! Send robot to base position 6
    ! *********************************
    PROC Base_position_6()
    MoveJ pBase_6, SpdToolEmpty, z80, Tool_1;
    ENDPROC

    ! Send robot to base position 7
    ! *********************************
    PROC Base_position_7()
    MoveJ pBase_7, SpdToolEmpty, z80, Tool_1;
    ENDPROC
    PROC Calirb()
    MoveAbsJ [[0,0,0,0,0,0],[9E+09,9E+09,9E+09,9E+09,9E+09,9E+09]]\NoEOffs, v1000, z50, Tool_1;
    ENDPROC

    ENDMODULE

    Hello Kwakisaki!


    I've found the problem!
    I checked all the harnesses but they were okay, so I began disassembling the power block if I'm right? (picture)
    The "certified" Kawasaki mechanic forgot to connect C1! So Where you will see three capacitors connected to eachother on the power block.
    He completely forgot to wire 1 of the 3. See attached picture!
    The wiring was just loose in the controller so I think it could've done a lot more damage if the loose connections had been in contact with another component or shielding.


    I waited till the capacitors drained which is about 7 minutes according to Kawasaki manuals. Then reconnected the last capacitor.
    And there it was, no D1008 error anymore!
    Thank you for your explanation! It helped me understand the electrical drawings just a little better!

    Hey guys,


    Just started up with a coffee and when I turned to Servo power on. it immediately shut off and gave me an error (D1008 P-N low voltage)
    It happened one day after a qualified mechanic ran a big maintenance routine.
    It has to do something without it, because the robot isn't in production yet, I've been playing with it to learn a lot about it for when it actually goes into production.
    Can anyone tell me how to fix this? He replaced the capacitors, I think there is a faulty connection at the capacitors in the Power block.
    Kawasaki troubleshooting says the following:
    Main cause:
    1. Disconnection or connection defect of each harness between the MC unit (1KQ board)/1NQ board and the power block.
    2. Defect in the 1KB/1RB (arm control board), the 1KP (power sequence board), the 1KQ/1NQ (power cicuit board), etc.
    3. Defect in the power block.
    4. Defect in the MC unit.
    Countermeasure:
    1. Check the connection harnesses.
    2. Replace the 1KB/1RB, the 1KP, the 1KQ/1NQ, the power block, the harnesses or the MC unit.


    Well, I did the first thing, but countermeasure 2 is nearly the same as buying a new controller...


    I'm pretty handy with electrical circuits and diagrams, so I was wondering what could've caused it.
    It says the voltage across P-N is 60 VDC or less when motor power is ON, or the connection between X212 (1KB/1RB board) and X502 (1KC/1KD boards) is abnormal. Registered as error only when servo is ON.
    Error level C: Abormalities without possibility of damaging equipment: Errors processed by servo software and AS software.
    What do they mean with processed by servo and AS software? The programming part? Because that's something that didn't change and it ran the software before.


    Thank you guys in advance! I've been learning a lot lately!
    Anyone have any experience with this error?

    Yes indeed, I know that. but what if the robot needs to follow a specific path from it's current position (which can be anywhere) to it's home position?
    I a case where the robot has to travel over some barrier or obstacle... you can't just take the quickest way back with JMOVE or something like that, it would cause a crash!

    I did exactly what the manual said and it just went full retard... So I changed the tool values manually, made my T (from O,A,T,) a minus 90 instead of just 90. so now my Y direction is more logical for operator etc.
    Thanks anyway! I also checked the auto load measurement function in the AUX but that's not relevant for me because my max load is like 2 kg's.
    so in the end... the coffee cup is not only good for me but also for manual tool teaching ;) (at least some clear reference :uglyhammer2:)

    Hey guys!
    yesterday I had a conversation with another robot programmer and he told me a homing program is very important! But at that moment I didn't pursue his mention.
    But later yesterday I started questioning myself, how he would do it in that case...
    In my opinion a homing program is a subroutine that is called, in which it will directly move to home position. But I guess in a real "homing program" it will determine it's current position, and from there on decide the best way to it's home position without colliding with any object or something like that?
    Just curious! :toothy9:
    So... I stole his program out of the controller when no-one was looking ;)
    It was an ABB robot, but that doesn't mean that it's not suitable for this discussion:
    it was like: if x axis is < 1000 then ... = 1000
    the same for y axis, and twice for z axis (+ and -)
    Couldn't go any further that day.. so that's all i have for now
    Maybe someone knows a bit more? :fine:
    Have a good day guys!

    Hello guys! Me again haha!
    During the last 13 weeks that I've been working with a Kawasaki FS06L with D71F controller, I had the TCP set up with a transformation variable. like:
    toolnr[0] = blablabla :n1:
    toolnr[1] = blablabla
    ... the values in there are measured by hand and I don't think it's accurate enough. because I have a 50mm sucker. and when i let it move inside a coffee cup, it does touch the edges.
    From that experience xD I can tell that it doesn't really know the center.
    The tool (sucker) is on a 45 degree steel triangular tube or socket whatever it's called (see pictures)
    The guys who programmed the kawa before me did it with a sort of as code, but I don't really liked that method, because I saw Auto tool calibration in the AUX menu.. I liked how it sounds :angel: but don't know how to use it.
    Besides that, how do you actually zero the robot? Just moving it to the zero increment "stripes" , shutdown mtr_pwr and then zero + rotation count reset?
    I check internal cabling for rotation,corrected that already, anything else to check on? that you guys know? The robot has been in a storage for 6 years... so maybe I overlooked something.
    And I see a lot of dip switches on my 1KB and 1KA board, what do they do? I thought they we're used to compare addresses and detect address mismatches?
    Would love to get an answer to a lot of these questions because I want to learn more and more!
    So if you guys know anything cool to do with the kawasaki or other cool aux functions that make things a lot easier, please tell me. (Not for welding and stuff, just pick&place>Pallet unloading and going to different stations.)
    Cheers and have a great "TCP Tuesday :uglyhammer2: "

    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

    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!

    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 :n1: )
    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: