m6 linear changer with tools to 96 sorted.
Posted: Sun Aug 30, 2020 5:51 pm
lots of people have asked how i did this. so heres my code to see.
also has optional probing after tool change controlled on or off with var#1
lots of time went into writing it originally.
it can be seen working on my machine here https://www.youtube.com/watch?v=v4qEWMI5zeM&t=191s
also has optional probing after tool change controlled on or off with var#1
lots of time went into writing it originally.
it can be seen working on my machine here https://www.youtube.com/watch?v=v4qEWMI5zeM&t=191s
- Code: Select all
//Duzzit-atc
exec.Setvar(1, 100);//stops manual change macroloop blocking the output for eject
int Currenttool = 0;
int Chuckopenport = 3;
int Chuckopenpin = 3;
int toollockcheckport = 5;
int toollockcheckpin = 13;
int headdownport = 3;
int headdownpin = 6;
int checkcolletopenport = 5;
int checkcolletopenpin = 12;
int atcslidefwdport = 5;
int atcslidefwdpin = 17;
int dustshoeport = 3;
int dustshoepin = 5;
double xclear= -106; /// x clearance of toolholder before lift up
double yclear= 0; /// y clearance of toolholder before lift up
double zraise=-5;
double SafeZ = -1;
double Ztoolrelease = -92; //-92
double Ztoolpickup = -92.5; //-92.5
int tpx=0;
int tpy=0;
double[] ToolX = new double[11];
double[] ToolY = new double[11];
ToolX[0] = 0; // Tool0 X position
ToolY[0] = 0; // Tool0 Y position
//Tool positions definition
ToolX[1] = 6; // Tool1 X position
ToolY[1] = -1393; // Tool1 Y position
ToolX[2] = 6; // Tool2 X position
ToolY[2] = -1273; // Tool2 Y position
ToolX[3] = 6; // Tool3 X position
ToolY[3] = -1153; // Tool3 Y position
ToolX[4] = 6; // Tool4 X position
ToolY[4] = -1033; // Tool4 Y position
ToolX[5] = 6; // Tool5 X position
ToolY[5] = -913; // Tool5 Y position
ToolX[6] = 6; // Tool6 X position
ToolY[6] = -793; // Tool6 Y position
ToolX[7] = 6; // Tool7 X position
ToolY[7] = -673; // Tool7 Y position
ToolX[8] = 6; // Tool8 X position
ToolY[8] = -553; // Tool8 Y position
ToolX[9] = 6; // Tool9 X position
ToolY[9] = -433; // Tool9 Y position
ToolX[10] = 6; // Tool10 X position
ToolY[10] = -313; // Tool10 Y position
int Newtool = exec.Getnewtool();
// ***set tool field number***
int Boxnumber = 195;// fieldnumber for tools 1-20 (field 196)
if (Newtool >20)
{
Boxnumber = 921-21;// fieldnumber for tools 21-96. minus 21 so tool increment is correct
}
// ***end of set tool field number***
exec.AddStatusmessage("new tool is "+Newtool);
//int Currenttool = exec.Getcurrenttool(); //// use readkey?
string writelasttool="0";
string read11=exec.Readkey("lasttool","lasttool",writelasttool);
double write11 = Convert.ToDouble(read11);
//int Currenttool = (int)write11;
double toolast=Convert.ToDouble(AS3.Getfield(897));
Currenttool =(int)toolast; // exec.Getcurrenttool();
//exec.AddStatusmessage("currenttool is "+Currenttool);
if(Currenttool == 0)
{
double val = exec.Question("What tool number is in spindle?");
//double val2 = exec.Question("CONFIRM What tool number is in spindle?");
MessageBox.Show("Tool in spindle is "+val +"Press STOP if incorrect");
MessageBox.Show("Ensure return pocket is empty for tool "+val);
Currenttool = (int)val;
}
if(Newtool == -1) // If new tool number is -1 means a missing T code, so we need to stop here...
{
exec.AddStatusmessage("new tool number missing");
exec.Wait(10);
MessageBox.Show("Tool change abort: missing T number");
exec.Wait(100);
exec.AddStatusmessage("new tool number missing or out of range");
exec.Wait(10);
exec.StopWithDeccel();
return;
}
if(Newtool <1 || Newtool >96) // Tool number is out of range, so we need to stop here...
{
MessageBox.Show("Tool change abort: tool number out of range.");
exec.Wait(100);
exec.AddStatusmessage("new tool out of range");
exec.Wait(10);
exec.StopWithDeccel();
return;
}
if(Newtool == Currenttool) // Same tool was selected, so do nothing, stop here...
return;
if(!exec.GetLED(56)||!exec.GetLED(57)||!exec.GetLED(58)) // If machine was not homed then it is unsafe to move in machine coordinates, stop here...
{
MessageBox.Show("The machine was not yet homed, do homeing before executing a tool change!");
exec.Stop();
return;
}
while(exec.IsMoving()){}
// Get current XY machine coordinates to return to this position at the end of the macro
double Xoriginalpos = exec.GetXmachpos();
double Yoriginalpos = exec.GetYmachpos();
// Stop spindle if running and Move Z up
exec.Stopspin();
exec.Code("G00 G53 Z"+ SafeZ); // Move Z up
while(exec.IsMoving()){}
string content1=AS3.Getfield(20401);
string content2=AS3.Getfield(20402);
string content3=AS3.Getfield(20403);
string content4=AS3.Getfield(20404);
string content5=AS3.Getfield(20405);
string content6=AS3.Getfield(20406);
string content7=AS3.Getfield(20407);
string content8=AS3.Getfield(20408);
string content9=AS3.Getfield(20409);
string content10=AS3.Getfield(20410);
// 100
double th1 = Convert.ToDouble(content1);
double th2 = Convert.ToDouble(content2);
double th3 = Convert.ToDouble(content3);
double th4 = Convert.ToDouble(content4);
double th5 = Convert.ToDouble(content5);
double th6 = Convert.ToDouble(content6);
double th7 = Convert.ToDouble(content7);
double th8 = Convert.ToDouble(content8);
double th9 = Convert.ToDouble(content9);
double th10 = Convert.ToDouble(content10);
// dust shoe up
exec.Setoutpin(dustshoeport,dustshoepin);
exec.Wait(10);
// check if tool is in rack *****Put back code*****
int returnfound=0;
//for (int i = 1; i <= 11; i++)
int check1 = (int) th1;
//exec.AddStatusmessage("check1 is" +check1);
if (Currenttool == check1)
{
//exec.AddStatusmessage("old Tool matches pocket 1" );
tpx=1;tpy=1;returnfound=1;
}
int check2 = (int) th2;
//exec.AddStatusmessage("check2 is" +check2);
if (Currenttool == check2)
{
//exec.AddStatusmessage("old Tool matches pocket 2 " );
tpx=2;tpy=2;returnfound=1;
}
int check3 = (int) th3;
//exec.AddStatusmessage("check3 is" +check3);
if (Currenttool == check3)
{
//exec.AddStatusmessage("old Tool matches pocket 3" );
tpx=3;tpy=3;returnfound=1;
}
int check4 = (int) th4;
//exec.AddStatusmessage("check4 is" +check4);
if (Currenttool == check4)
{
//exec.AddStatusmessage("old Tool matches pocket 4" );
tpx=4;tpy=4;returnfound=1;
}
int check5 = (int) th5;
//exec.AddStatusmessage("check5 is" +check5);
if (Currenttool == check5)
{
//exec.AddStatusmessage("old Tool matches pocket 5" );
tpx=5;tpy=5;returnfound=1;
}
int check6 = (int) th6;
//exec.AddStatusmessage("check6 is" +check6);
if (Currenttool == check6)
{
//exec.AddStatusmessage("old Tool matches pocket 6" );
tpx=6;tpy=6;returnfound=1;
}
int check7 = (int) th7;
//exec.AddStatusmessage("check7 is" +check7);
if (Currenttool == check7)
{
//exec.AddStatusmessage("old Tool matches pocket 7" );
tpx=7;tpy=7;returnfound=1;
}
int check8 = (int) th8;
//exec.AddStatusmessage("check8 is" +check8);
if (Currenttool == check8)
{
//exec.AddStatusmessage("old Tool matches pocket 8" );
tpx=8;tpy=8;returnfound=1;
}
int check9 = (int) th9;
//exec.AddStatusmessage("check9 is" +check9);
if (Currenttool == check9)
{
//exec.AddStatusmessage("old Tool matches pocket 9" );
tpx=9;tpy=9;returnfound=1;
}
int check10 = (int) th10;
//exec.AddStatusmessage("check10 is" +check10);
if (Currenttool == check10)
{
//exec.AddStatusmessage("old Tool matches pocket 10" );
tpx=10;tpy=10;returnfound=1;
}
if (returnfound == 0)
{
exec.AddStatusmessage("Return pocket not matched" );
//tpx=10;tpy=10;
MessageBox.Show("Tool change abort- pocket not found.");
exec.Setvar(0, 100);//stops manual change macroloop blocking the output for eject
exec.Stop();
return;
}
///****add else do something like tool 0 etc*********
// 200
//drop old tool section { }
if (Currenttool!=0) //&& (AS3.GetLED(132))) // // No need to drop down tool if current tool number is zero
{
// Move to old tool position on XY plane
double ToolXmove =0;
double ToolYmove =0;
ToolXmove =ToolX[tpx] + xclear; ToolYmove = ToolY[tpy] + yclear; // calculate slide out clear position
exec.Code("G00 G53 X" + ToolXmove + " Y" + ToolYmove); // move to slide out position
while(exec.IsMoving()){}
//*******ensure spindle is not still running- vfd run relay check****
while(AS3.GetLED(130)) // check spindle stopped: relay on vfd
{
exec.Wait(300);
if(exec.Ismacrostopped())
{
exec.Setvar(0, 100);//stops manual change macroloop blocking the output for eject
MessageBox.Show("Tool change was interrupted by no signal at spindle stop");
exec.StopWithDeccel();
return;
}
}
//end of spindle stopped check
//atcfwd
exec.Setoutpin(atcslidefwdport,atcslidefwdpin);
exec.Wait(100);
// end of atcfwd
//HEAD down
exec.Setoutpin(headdownport,headdownpin);
exec.Wait(100);
// end of head down
// Drop current tool
exec.Code("G00 G53 Z"+ Ztoolrelease); // Move Z axis down to tool holder position
while(exec.IsMoving()){}
exec.Code("G1 f5000 G53 X" + ToolX[tpx] + " Y" + ToolY[tpy]); // move into holder slowly
exec.Setoutpin(Chuckopenport, Chuckopenpin); // Open the chuck with pneumatic valve
exec.Wait(10);
while(!AS3.GetLED(131)) // check Collet has opened
{
Thread.Sleep(1);
if(exec.Ismacrostopped())
{
exec.Clroutpin(Chuckopenport, Chuckopenpin);
exec.Wait(10);
exec.Clroutpin(atcslidefwdport,atcslidefwdpin); // atc slide back
exec.Wait(10);
exec.StopWithDeccel();
exec.Setvar(0, 100);//stops manual change macroloop blocking the output for eject
MessageBox.Show("Tool change was interrupted at collet open!");
return;
}
}
while(AS3.GetLED(132)) // check tool has released
{
Thread.Sleep(1);
if(exec.Ismacrostopped())
{
exec.Clroutpin(Chuckopenport, Chuckopenpin);
exec.Wait(10);
exec.Clroutpin(atcslidefwdport,atcslidefwdpin);
exec.Wait(10);
exec.StopWithDeccel();
exec.Setvar(0, 100);//stops manual change macroloop blocking the output for eject
MessageBox.Show("Tool not released");
return;
}
}
exec.Setcurrenttool(0); //Set the current tool as 0 =empty
exec.Wait(100);
//***head up***
// ***change to wait for tool released signal*** re write key here***
exec.Code("G00 G53 Z"+ SafeZ); // Move Z up
while(exec.IsMoving()){}
}
// write tool holder content to profile
content1=AS3.Getfield(20401);
exec.Writekey("tp1","holder1",content1);
content2=AS3.Getfield(20402);
exec.Writekey("tp2","holder2",content2);
content3=AS3.Getfield(20403);
exec.Writekey("tp3","holder3",content3);
content4=AS3.Getfield(20404);
exec.Writekey("tp4","holder4",content4);
content5=AS3.Getfield(20405);
exec.Writekey("tp5","holder5",content5);
content6=AS3.Getfield(20406);
exec.Writekey("tp6","holder6",content6);
content7=AS3.Getfield(20407);
exec.Writekey("tp7","holder7",content7);
content8=AS3.Getfield(20408);
exec.Writekey("tp8","holder8",content8);
content9=AS3.Getfield(20409);
exec.Writekey("tp9","holder9",content9);
content10=AS3.Getfield(20410);
exec.Writekey("tp10","holder10",content10);
//***** calculate new tool position***********
// Move to new tool position on XY plane
int matchnew=0;
if (Newtool == check1)
{
exec.AddStatusmessage("new Tool matches pocket 1" );
tpx=1;tpy=1;matchnew=1;
}
if (Newtool == check2)
{
exec.AddStatusmessage("new Tool matches pocket 2" );
tpx=2;tpy=2;matchnew=1;
}
if (Newtool == check3)
{
exec.AddStatusmessage("new Tool matches pocket 3" );
tpx=3;tpy=3;matchnew=1;
}
if (Newtool == check4)
{
exec.AddStatusmessage("new Tool matches pocket 4" );
tpx=4;tpy=4;matchnew=1;
}
if (Newtool == check5)
{
exec.AddStatusmessage("new Tool matches pocket 5" );
tpx=5;tpy=5;matchnew=1;
}
if (Newtool == check6)
{
exec.AddStatusmessage("new Tool matches pocket 6" );
tpx=6;tpy=6;matchnew=1;
}
if (Newtool == check7)
{
exec.AddStatusmessage("new Tool matches pocket 7" );
tpx=7;tpy=7;matchnew=1;
}
if (Newtool == check8)
{
exec.AddStatusmessage("new Tool matches pocket 8" );
tpx=8;tpy=8;matchnew=1;
}
if (Newtool == check9)
{
exec.AddStatusmessage("new Tool matches pocket 9" );
tpx=9;tpy=9;matchnew=1;
}
if (Newtool == check10)
{
exec.AddStatusmessage("new Tool matches pocket 10" );
tpx=10;tpy=10;matchnew=1;
}
if (matchnew == 0)
{
exec.AddStatusmessage("Requested tool not in tool rack" );
exec.StopWithDeccel();
exec.Setvar(0, 100);//stops manual change macroloop blocking the output for eject
exec.Clroutpin(atcslidefwdport,atcslidefwdpin);
exec.Wait(10);
MessageBox.Show("Tool change abort- new tool not found.");
return;
}
exec.Code("G00 G53 X" + ToolX[tpx] + " Y" + ToolY[tpy]);
while(exec.IsMoving()){}
// Pick new tool
exec.Code("G00 G53 Z"+ Ztoolpickup); // Move Z axis down to tool holder position
while(exec.IsMoving()){}
exec.Clroutpin(Chuckopenport, Chuckopenpin); // Close the chuck with pneumatic valve
exec.Wait(10); // Wait one 1000msec
while(AS3.GetLED(131)) // check Collet has closed
{
exec.Wait(100);
if(exec.Ismacrostopped())
{
exec.Setvar(0, 100);//stops manual change macroloop blocking the output for eject
exec.StopWithDeccel();
MessageBox.Show("Tool change was interrupted by user!at collet closed");
return;
}
}
// security checks done
double ToolXmov =0; /// note different spelling
double ToolYmov =0;
ToolXmov =ToolX[tpx] + xclear; ToolYmov = ToolY[tpy] + yclear; // calculate slide out clear position
exec.Code("G0 G53 X" + ToolXmov + " Y" + ToolYmov); // move to slide out position
//atcback
exec.Clroutpin(atcslidefwdport,atcslidefwdpin);
exec.Wait(100);
// end of backfwd
while(exec.IsMoving()){}
exec.Code("G00 G53 Z"+ SafeZ); // Move Z up
while(exec.IsMoving()){}
exec.Wait(100);
while(AS3.GetLED(132)) // check tool has locked
{
exec.Wait(1000);
if (AS3.GetLED(132))
{
exec.AddStatusmessage("Tool not locked or missing ?" );
}
if(exec.Ismacrostopped())
{
exec.Setvar(0, 100);//stops manual change macroloop blocking the output for eject
MessageBox.Show("Tool not locked or no tool!");
exec.StopWithDeccel();
break;
}
}
// Move back to start point
//exec.Code("G00 G53 X" + Xoriginalpos + " Y" + Yoriginalpos);
//while(exec.IsMoving()){}
// Measure new tool will go here....
//********probing************
int headnumber = 1; //hsd
int head1downport = 3;
int head1downpin = 6;
int head2downport = 3;
int head2downpin = 7;
// Probing settings//
double Zmin = -200;
double Zmin2 = -3;
double Feedrate = 1000;
double Feedrate2 = 30;
double SafeZ2 = -50;
double retractheight = 10;
double retractheight2 = 1.5;
//int Boxnumber = 195;// fieldnumber for tools 1-20 (field 196)
double probeyes = exec.Getvar (1);
double ToolXchgpos = -200; // Toolchange X position
double ToolYchgpos = -1550; // Toolchange Y position // HSD
double probeheight = -170.71;// hsd // use m312 to get exact position of probe with no tool
double probeX = 4; // HSD
double probeY = -1586;
//M31 probing macro
if (probeyes <1)
{ // probe if #1=0 *********************
if(!exec.GetLED(56)||!exec.GetLED(57)||!exec.GetLED(58)) // If machine was not homed then it is unsafe to move in machine coordinates, stop here...
{
MessageBox.Show("MACHINE NOT HOMED, home the machine before tool change!");
exec.Stop();
return;
}
while(exec.IsMoving()){}
exec.Wait(200);
if(exec.GetLED(37)) // if probe signal is on - probe stuck! stop here...
{
MessageBox.Show("The probe signal isnt ready-check probe!");
exec.Setvar(0, 100);//stops manual change macroloop blocking the output for eject
exec.Stop();
return;
}
//HEAD DOWN
exec.Setoutpin(headdownport,headdownpin);
double Zoriginalpos = exec.GetZmachpos(); // Get the current Z machine coordinates
exec.Setvar(5063,0);
exec.Code("G00 G53 X" + probeX +" Y" + probeY + "Z-5");// // Move to the probe sensor position in XY
while(exec.IsMoving()){}
//********switch to incremental *********
exec.Code("G91");
exec.Code("G31 Z" + Zmin + "F" + Feedrate); // Move to the probe sensor position in z
while(exec.IsMoving()){}
exec.Wait(100);
Console.Beep();
if(!exec.GetLED(244)) // if didnt hit probe stop here...
{
MessageBox.Show("The probe didnt hit!");
exec.Stop();
return;
}
double probed1 = exec.Getvar(5063); // Get the current Z coordinates//*****using vars
//exec.AddStatusmessage("probe at "+ probed1);
exec.Code("G90");
exec.Code("G01 f200 Z" + probed1 );
while(exec.IsMoving()){}
exec.Wait(100);
Console.Beep();
double Zoriginalposprobed = exec.GetZmachpos(); // Get the current Z machine coordinates
double Zoriginalposprobed2 = exec.GetZmachpos(); // Get the current Z machine coordinates
double probedpos= Zoriginalposprobed - Zoriginalpos;
double probedpos2= Zoriginalposprobed2 - Zoriginalpos;// *****using vars
//exec.AddStatusmessage("Tool length old method1 "+ probedpos);
exec.Code("G91");
//double backoff = exec.GetZmachpos() + retractheight2;
//exec.Code("G00 G53 Z" + backoff); // Move few mm?? above probe plate
exec.Code("G00 Z"+ retractheight2 ); // Move 2 mm?? above probe plate
while(exec.IsMoving()){}
exec.Wait(100);
exec.Setvar(5063,0);
//Console.Beep();
if(exec.GetLED(37)) // if probe signal is on- probe stuck! stop here...
{
MessageBox.Show("The probe signal isnt ready-check probe!");
exec.Setvar(0, 100);//stops manual change macroloop blocking the output for eject
exec.Stop();
return;
}
exec.Code("G31 Z" + Zmin2 + "F" + Feedrate2); // slow probe
while(exec.IsMoving()){}
exec.Wait(100);
Console.Beep();
if(!exec.GetLED(244)) // if didnt hit probe stop here...
{
MessageBox.Show("The probe didnt hit!");
exec.Setvar(0, 100);//stops manual change macroloop blocking the output for eject
exec.Stop();
return;
}
double probed2 = exec.Getvar(5063); // Get the current Z coordinates//*****using vars
//exec.AddStatusmessage("probed position "+ probed2);
exec.Code("G90");
exec.Code("G01 f200 Z" + probed2 );
while(exec.IsMoving()){}
exec.Wait(100);
Console.Beep();
//Zoriginalposprobed2= exec.GetZmachpos(); // Get the current Z machine coordinates
//********switch to absolute *********
exec.Code("G90");
if(!exec.Ismacrostopped()) // If tool change was not interrupted with a stop only then validate
{
Zoriginalposprobed = exec.GetZmachpos(); // Get the current Z machine coordinates
double goodprobed = exec.Getvar(5060); // ****using vars
//exec.AddStatusmessage("probe good? "+ goodprobed);
probedpos= Zoriginalposprobed - Zoriginalpos;
exec.Wait(100);
//probedpos2= Zoriginalposprobed2 - Zoriginalpos;//*****using vars
double tooloffset= Zoriginalposprobed - probeheight;
exec.AddStatusmessage("Tool length now "+ tooloffset);
exec.Code("G00 G53 Z-5");// // Move z to -5 from home switch
while(exec.IsMoving()){}
exec.Wait(100);
exec.Code("G00 G53 x-200");// // Move x to -5 from home switch
while(exec.IsMoving()){}
exec.Wait(100);
// **** Set tool table ****
int fieldtoset= (Boxnumber + Newtool);// different field numbers now with extra tools added in this version
AS3.Setfield(tooloffset, fieldtoset);
exec.Wait(100);
AS3.Validatefield(fieldtoset);
//exec.AddStatusmessage("field # "+ fieldtoset);
exec.Callbutton(168);// apply all settings
exec.Wait(100);
exec.Callbutton(167);// save all settings
exec.Wait(100);
AS3.Setfield(tooloffset, 169);//set tooloffset z
exec.Wait(200);
AS3.Validatefield(169); // this updates all settings with new z offset.
exec.Wait(100);
while(exec.IsMoving()){}
if(!exec.Ismacrostopped()) // If tool change was not interrupted with a stop only then validate new tool number
{
exec.Code("G0 G43 H"+ Newtool); // Load new tool offset
exec.Wait(100);
exec.Setcurrenttool(Newtool); //Set the current tool -> the new tool
exec.Wait(100);
// MessageBox.Show("Tool change done.");
exec.AddStatusmessage("Tool PROBED OK Tool # "+ Newtool);
}
else
{
exec.StopWithDeccel();
exec.Setvar(0, 100);//stops manual change macroloop blocking the output for eject
MessageBox.Show("Tool change was interrupted by user!");
}
}
} //end of no probe loop *****************
else
//exec.Code("G0 G43 H"+Newtool); // Load new tool offset
exec.Wait(200);
while(exec.IsMoving()){}
if(!exec.Ismacrostopped()) // If tool change was not interrupted with a stop only then validate new tool number
{
exec.Setcurrenttool(Newtool); //Set the current tool -> the new tool
exec.Wait(100);
exec.Code("G0 G43 H"+(Newtool));
//save current tool key to profile//
int lastool = exec.Getcurrenttool();
writelasttool = Convert.ToString(lastool);
exec.Writekey("lasttool","lasttool",writelasttool);
//exec.AddStatusmessage("profile last tool updated to T: "+writelasttool);
exec.Setvar(0,100 );
// MessageBox.Show("Tool change done.");
}
else
{
exec.StopWithDeccel();
exec.Setvar(0,100 );
MessageBox.Show("Tool change was interrupted by user!");
}