Am I do someting wrong with tool measuring?

I have a 5 position ATC on my CNC. I use an M931 for the automatic tool measuring when tools are picked up, and M31 for touching down to my material.
I run about a 50% success rate when changing tools with regard to the tip of the tool being right at the previously measured material surface location.
For example if I touch down to my material with T1 and then after running the file for that bit, pick up T2 it may or may not have it's Z0 right at the material surface. When this happens I've noticed that the discrepancy is about equal to the difference between the length of the 2 bits. That is, if T1 is 1/4" longer than T2, T2 would be 1/4" above the material.
The M931 that runs at each tool pickup seems to be recording that tool length in the tool table properly. But the UCCNC internal math may or may not calculate the right position for the 2nd bit to be on the material surface at Z0......or may not apply it at all.
This has been going on for a long time and I thought I'd finally ask here if there might be something I'm missing or doing wrong.
Ask away and I'll try and provide more details as they might be requested. I will add that I have two touch down probes.....one fixed location for the tool rack and one portable to put on top of my material.
I'll post my M931 file below.
Thanks,
BH
**********************************************************
M931 file
// Set Tool Offset
// Called from M6.txt
// Get tool number
int tool = exec.Getcurrenttool();
// If current tool is invalid, abort with a warning.
if (tool < 0)
{
exec.Code("M0");
MessageBox.Show("The current tool is invalid.\n\n" +
"Your program has been stopped ( M0 ) and the Set Tool Offset function is aborted.\n\n" +
"Please set the current tool and try again.", "Select Current Tool");
return;
}
// If we don't have a tool we're done.
if (tool == 0)
{
return;
}
// If we make it here, we have a valid tool.
// Confirm proper modal states.
exec.Code("M5");
exec.Code("M9");
exec.Code("G90");
// Initialize paramters.
int saveToolTableButtonId = 780;
string SECTION = "RapidChange";
string zSafeToolSetter = exec.Readkey(SECTION, "zSafeSet", "0");
string xToolSetter = exec.Readkey(SECTION, "xSetter", "0");
string yToolSetter = exec.Readkey(SECTION, "ySetter", "0");
string zSeekStart = exec.Readkey(SECTION, "zSeek", "0");
string zSeekTarget = exec.Readkey(SECTION, "seekTarget", "0");
string seekFeedRate = exec.Readkey(SECTION, "fSeek", "0");
string setFeedRate = exec.Readkey(SECTION, "fSet", "0");
string seekRetreat = exec.Readkey(SECTION, "seekRetreat", "0");
string zSafeClearance = exec.Readkey(SECTION, "zSafeClear", "0");
double tloReference = double.Parse(exec.Readkey(SECTION, "tloRef", "0"));
double machToWorkOffset = exec.GetZmachpos() - exec.GetZpos();
double zTargetWorkPos = double.Parse(zSeekTarget) - machToWorkOffset;
string zTargetWork = zTargetWorkPos.ToString("F2");
exec.Code("G53 G0 Z" + zSafeToolSetter);
exec.Code("G53 G0 X" + xToolSetter + "Y" + yToolSetter);
exec.Code("G53 G0 Z" + zSeekStart);
exec.Code("G31 Z" + zTargetWork + " F" + seekFeedRate);
WaitForMove();
exec.Wait(200);
double retreatDistance = double.Parse(seekRetreat);
double retreatHeight = exec.GetZmachpos() + retreatDistance;
exec.Code("G53 G0 Z" + retreatHeight.ToString());
exec.Code("G31 Z" + zTargetWork + " F" + setFeedRate);
WaitForMove();
exec.Wait(200);
// double setterRef = double.Parse(exec.Readkey(SECTION, "setterRef", "0"));
// double offset = exec.GetZmachpos() - setterRef;
double offset = exec.GetZmachpos() - tloReference;
int fieldNum = GetToolOffsetFieldNumber(tool);
AS3.Setfield(offset, fieldNum);
exec.Callbutton(saveToolTableButtonId);
exec.Wait(200);
exec.Code("G43 H" + tool.ToString());
exec.Code("G53 G0 Z" + zSafeClearance);
WaitForMove();
#Events
void WaitForMove()
{
while (exec.IsMoving()) {}
}
int GetToolOffsetFieldNumber(int toolNum)
{
if (toolNum >= 1 && toolNum <= 20)
{
return 195 + toolNum;
}
else if (toolNum >= 21 && toolNum <= 96)
{
return 920 + toolNum;
}
else
{
return -1;
}
}
I run about a 50% success rate when changing tools with regard to the tip of the tool being right at the previously measured material surface location.
For example if I touch down to my material with T1 and then after running the file for that bit, pick up T2 it may or may not have it's Z0 right at the material surface. When this happens I've noticed that the discrepancy is about equal to the difference between the length of the 2 bits. That is, if T1 is 1/4" longer than T2, T2 would be 1/4" above the material.
The M931 that runs at each tool pickup seems to be recording that tool length in the tool table properly. But the UCCNC internal math may or may not calculate the right position for the 2nd bit to be on the material surface at Z0......or may not apply it at all.
This has been going on for a long time and I thought I'd finally ask here if there might be something I'm missing or doing wrong.
Ask away and I'll try and provide more details as they might be requested. I will add that I have two touch down probes.....one fixed location for the tool rack and one portable to put on top of my material.
I'll post my M931 file below.
Thanks,
BH
**********************************************************
M931 file
// Set Tool Offset
// Called from M6.txt
// Get tool number
int tool = exec.Getcurrenttool();
// If current tool is invalid, abort with a warning.
if (tool < 0)
{
exec.Code("M0");
MessageBox.Show("The current tool is invalid.\n\n" +
"Your program has been stopped ( M0 ) and the Set Tool Offset function is aborted.\n\n" +
"Please set the current tool and try again.", "Select Current Tool");
return;
}
// If we don't have a tool we're done.
if (tool == 0)
{
return;
}
// If we make it here, we have a valid tool.
// Confirm proper modal states.
exec.Code("M5");
exec.Code("M9");
exec.Code("G90");
// Initialize paramters.
int saveToolTableButtonId = 780;
string SECTION = "RapidChange";
string zSafeToolSetter = exec.Readkey(SECTION, "zSafeSet", "0");
string xToolSetter = exec.Readkey(SECTION, "xSetter", "0");
string yToolSetter = exec.Readkey(SECTION, "ySetter", "0");
string zSeekStart = exec.Readkey(SECTION, "zSeek", "0");
string zSeekTarget = exec.Readkey(SECTION, "seekTarget", "0");
string seekFeedRate = exec.Readkey(SECTION, "fSeek", "0");
string setFeedRate = exec.Readkey(SECTION, "fSet", "0");
string seekRetreat = exec.Readkey(SECTION, "seekRetreat", "0");
string zSafeClearance = exec.Readkey(SECTION, "zSafeClear", "0");
double tloReference = double.Parse(exec.Readkey(SECTION, "tloRef", "0"));
double machToWorkOffset = exec.GetZmachpos() - exec.GetZpos();
double zTargetWorkPos = double.Parse(zSeekTarget) - machToWorkOffset;
string zTargetWork = zTargetWorkPos.ToString("F2");
exec.Code("G53 G0 Z" + zSafeToolSetter);
exec.Code("G53 G0 X" + xToolSetter + "Y" + yToolSetter);
exec.Code("G53 G0 Z" + zSeekStart);
exec.Code("G31 Z" + zTargetWork + " F" + seekFeedRate);
WaitForMove();
exec.Wait(200);
double retreatDistance = double.Parse(seekRetreat);
double retreatHeight = exec.GetZmachpos() + retreatDistance;
exec.Code("G53 G0 Z" + retreatHeight.ToString());
exec.Code("G31 Z" + zTargetWork + " F" + setFeedRate);
WaitForMove();
exec.Wait(200);
// double setterRef = double.Parse(exec.Readkey(SECTION, "setterRef", "0"));
// double offset = exec.GetZmachpos() - setterRef;
double offset = exec.GetZmachpos() - tloReference;
int fieldNum = GetToolOffsetFieldNumber(tool);
AS3.Setfield(offset, fieldNum);
exec.Callbutton(saveToolTableButtonId);
exec.Wait(200);
exec.Code("G43 H" + tool.ToString());
exec.Code("G53 G0 Z" + zSafeClearance);
WaitForMove();
#Events
void WaitForMove()
{
while (exec.IsMoving()) {}
}
int GetToolOffsetFieldNumber(int toolNum)
{
if (toolNum >= 1 && toolNum <= 20)
{
return 195 + toolNum;
}
else if (toolNum >= 21 && toolNum <= 96)
{
return 920 + toolNum;
}
else
{
return -1;
}
}