M6/M31 Macro Pair to emulate Carbide3D Bitzero Probing

Here is where you can drop off Examples of WORKING macros,plugins,Gcode programs , macro Wizards etc.
Please give a brief description of what it is and how it works.

Re: M6/M31 Macro Pair to emulate Carbide3D Bitzero Probing

Postby Precision Composites » Wed Sep 04, 2024 1:45 am

I need to do this very thing, but with our 5-axis head-head (B/C Head) as we currently have a 3 foot Z. After doing roughing or a facing pass and changing bits, our reference Z is gone.

I'm assuming instead of using the C-DRO for the differential, I'd change it to the A in the coding.
Also, when homing, the machine DROs don't zero out. I'm assuming it's because something isn't checked/set correctly in the Axes Setup. Otherwise, machine runs fine (with exception of not having RTCP funtionality).
Precision Composites
 
Posts: 12
Joined: Mon Mar 06, 2023 9:26 pm

Re: M6/M31 Macro Pair to emulate Carbide3D Bitzero Probing

Postby evanevery » Wed Sep 04, 2024 12:53 pm

Yes, if you are using the C DRO in your 5-Axis machine then you should choose a different DRO. (You will need to make those changes in both the XYZ Probing Macro and the ToolChange Macro (M6) since they both reference the offset value)

You can also save/retrieve the offset info in UCCNC using internal variables or save/retrieve data from the profile INI.

I chose to use the C DRO (as have others) because it is a visible value and easy to visually confirm. But you can use other methods (as above). If I have some time today, I may give this a try (just for fun ;-)
evanevery
 
Posts: 20
Joined: Tue Jan 11, 2022 3:57 pm

Re: M6/M31 Macro Pair to emulate Carbide3D Bitzero Probing

Postby evanevery » Wed Sep 04, 2024 3:51 pm

OK, I have updated the two macros ("XYZ Probe Zero" M20031 and "Tool Change" M6) to enable the use of multiple storage/retrieval methods. If you need to keep your C-Axis DRO "undisturbed" then you can use an alternate method. Here is how that works:

There is a variable in the configuration block named "StorageMethod":

- If it is set to "-1", then M6/M20031 will use the C-Axis DRO for storage/retrieval of the Plate Offset (this is the default method)
- If it is set to "-2", then the Plate Offset will be stored/retrieved in/from the currently running profile (file)
- if it is set to any other integer (i.e. "StorageMethod = 100"), then the corresponding internal variable will be used (0-5999, noting that 5060-5066 and 5039 are reserved and should not be used)

*** Note that the same "StorageMethod" must be defined in both M6 and M20031 for the pair to communicate properly

I have also made a few other changes to the files and cleaned them up a bit. Most notable:

- Both files now share a common "Configuration Block" such that it can be edited once and then copy/pasted between both macros. This means there are a couple of variables in the block which are only actually used by one macro or the other (as noted). They don't need to be deleted, they just wont serve any purpose in the Macro which doesn't actually need them...

- I added a delay timer ("OKDelay") such that you can have a few seconds (ms actually) between hitting "OK" and the start of the XYZ probing sequence. This will give you time to hold and stabilize the mobile plate if so desired. It can be set to "0" if you don't need/want this.

- I have added a configuration variable ("Do2ndYPass") to enable/disable the second Y Axis probe if so desired. The second Y-Axis probe is now disabled by default ("false"). You can turn it on ("true") if you want a bit of increased accuracy after the X-Axis probe centers the probe more precisely.

- I am now using a different Mobile Plate. It is a generic "Chinese" plate, is cheaper than the OpenBuilds plate, the XY hole is bigger, and less wiring is required. As such, the Mobile Plate characteristics in the attached files no longer represent the OpenBuilds plate. Please adjust your Mobile Plate characteristics accordingly if you are using the OpenBuilds plate. (You can find my OpenBuilds Mobile Plate characteristics in my original posting in this thread).

* Also, rather than posting a dedicated macro for testing the M6 function (previously M20006) I have decided it isn't really necessary (and was a bit confusing). (The only difference between M6 and M20006 was that M20006 had the Tool Number detection turned off so it could be tested with a custom button press). Moving forward, it is a lot less confusing (I think) to simply call the M6 macro from the UCCNC command line and just specify a dummy tool number if you want to test it. I.E. "M6 T1"

As always, please post any questions or suggestions to this thread. Thanks!


M20031 XYZ Probing Macro
Code: Select all
// Custom M20031 PROBING MACRO
// Simulates Carbide Motion (Nomad, Shapeko) BITZERO Probing Function (X, Y, Z)

// Requires Both a Mobile Plate (For initial M31 Workspace X, Y, Z) and a Fixed Plate (to support ongoing automatic Zeroing in the Z axis after M6 tool changes)

// * Mobile Plate: An XYZ Touch Plate (with XY Hole) is used to simulate the Carbide3D BitZero functionality
// * Fixed Plate: Any standard Touch Plate may be affixed to the router bed

// * UCCNC must be specifically configured (in Settings) to run an M6 Macro (default setting = do nothing)

// * The design software post processor for the machine must be configured to support tool changes (a "UCCNC ATC" vectric post processor is also provided)

// The machine must be Homed prior to this activity
// The operator should use a cylindrical touch bit probe in the chuck (not a router bit) for best accuracy
// The operator should manually position the touch bit probe down into the approximate center of the XY Hole of the mobile plate before running this operation
// This macro will first run the X/Y probe inside the mobile plate XY Hole, then lift and reposition to perform a Z probe on the mobile plate
// The Y-Axis probe will run twice for increased accuracy after the approximate center is found (ie: Y probe, X probe, second Y probe)
// This macro will then transition to the location of the fixed plate to calculate the height difference between the Workspace and Fixed plates
// The Z Offset difference between the workspace and fixed plate is stored/maintained in the C-Axis DRO, as a Profile Entry, or an internal variable as specified by "StorageMethod".
// The companion M6 macro is required to retrieve the Mobile/Fixed Plate Difference (offset) and support the Fixed Plate and automatic Workspace Z Zeroing during tool changes


// Start Configuration Block:  ***************************************************************************
// Can be directly copy/pasted (shared) between M20031 and M6 macros - as such some variables are not actually used by both macros

// MOBILE Plate Characteristics      // (Only used by M20031)
double MobilePlateThickness = 5.10;   // Thickness of the Probing Plate
double MobilePlateHoleDiameter = 14.7;   // Diameter of Origin Hole (used for side probe limits)
double MobilePlateHoleDepth = 4.9;   // Depth of the Origin Hole (used for retract: 2x)
double MobilePlateHoleOffsetX = 18;   // Offset to Z Probe Point (Relative from Origin Center)
double MobilePlateHoleOffsetY = 18;   // Offset to Z Probe Point (Relative from Origin Center)

// FIXED Plate Characteristics
double FixedPlateX = 364.4;      // Fixed plate X position (machine coordinate)
double FixedPlateY = 20.7;      // Fixed plate Y position (machine coordinate)

// TOOL CHANGE Location
double ToolChangeX = 180;        // Tool change X position (machine coordinate)
double ToolChangeY = 0;        // Tool change Y position (machine coordinate)
double ToolChangeZ = 0;         // Tool change Z position (machine coordinate)

// Tuning Parameters
double SafeZ = 0;         // Safe Z in (machine coordinate) Note: Machine homing should produce a Z=0 (Machine Coord) at Upper limit of Safe Z Travel
double RetractDistance = 1;        // Height above Z0 to which probe will retract
double CoarseRate = 150;       // Feed rate for initial probing
double FineRate = 25;           // Feed rate for fine probing
double ZMaxProbeDist = 70;       // maximum probing distance
bool   DustShoe = true;         // Pause/Prompt for Dust Shoe?
int    StorageMethod = -1;      // -1 to use C-Axis DRO, -2 to use Profile (file), or any other integer for internal variable (0-5999 excluding 5060-5066 and 5039 which are reserved)
int    OKDelay = 5000;         // Time to wait (ms) after "OK" on initial probe prompt (to allow manual stabilization of Mobile Touch Plate) (Only used by M20031)
bool   Do2ndYPass = false;      // Do a second Y Zero pass for increased accuracy (again after X Zero) (Only used by M20031)
bool   ReturnToOriginalXY = true;   // return to the same coordinates where the Tool Change was requested (Only used by M6)
bool   PerformToolCheck = true;      // Enable check for valid tool number (T#) (disable for manual testing) (Only used by M6)
bool   ValidOffsetCheck = true;      // Enable check for valid plate offset (non-zero) (Only used by M6)

// End Configuration Block:  *****************************************************************************


// Macro ID (For use in title of Message Boxes)
string MacroID = "M20031";

// Calculated Parameters
double XYProbeRetract = MobilePlateHoleDepth * 2;
double DoubleRetractDistance = RetractDistance * 2;

// Working Variables
double XSave;
double YSave;
double ZSave;
double YMax;
double YMin;
double XMax;
double XMin;
double XCenter;
double YCenter;
double ZMobilePlate;
double ZFixedPlate;
double PlateOffset;

// Machine must be homed for safety
if(!exec.GetLED(56)||!exec.GetLED(57)||!exec.GetLED(58)) {
   ShowMessage("The machine must be HOMED before this activity!", MacroID + ": Fatal Error!");
   exec.Stop();
   return;
}

// Get current X, Y, Z
XSave = exec.GetXmachpos();
YSave = exec.GetYmachpos();
ZSave = exec.GetZmachpos();

// Request Probe Action
if (DustShoe) ShowMessage("Please remove DUST SHOE and prepare MOBILE Probe (Attach Lead, Position the Probe and Spindle!)", MacroID + ": Prepare MOBILE Probe");
else ShowMessage("Please prepare MOBILE Probe (Attach Lead, Position the Probe and Spindle!)", MacroID + ": Prepare MOBILE Probe");

// Allow a few seconds for the operator to hold/stabilize the Mobile Touch Plate after clicking "OK"
exec.Wait(OKDelay);

// ***** Probe Y (Negative)
Probe_RC('Y', '-', MobilePlateHoleDiameter, RetractDistance, CoarseRate, FineRate);

// Get YMin
YMin = exec.GetYmachpos();

// Retract to Y starting Location (Machine Coords)
ExecAndWait("G53 G0 Y" + YSave);

// ***** Probe Y (Positive)
Probe_RC('Y', '+', MobilePlateHoleDiameter, RetractDistance, CoarseRate, FineRate);

// Get YMax
YMax = exec.GetYmachpos();

// Move Y to Calculated Center (Machine Coords)
YCenter = (YMax + YMin) / 2;
ExecAndWait("G53 G0 Y" + YCenter);

// ***** Probe X (Negative)
Probe_RC('X', '-', MobilePlateHoleDiameter, RetractDistance, CoarseRate, FineRate);

// Get XMin
XMin = exec.GetXmachpos();

// Retract to X starting Location (Machine Coords)
ExecAndWait("G53 G0 X" + XSave);

// ***** Probe X (Positive)
Probe_RC('X', '+', MobilePlateHoleDiameter, RetractDistance, CoarseRate, FineRate);

// Get XMax
XMax = exec.GetXmachpos();

// Move X to Calculated Center (Machine Coords)
XCenter = (XMax + XMin) / 2;
ExecAndWait("G53 G0 X" + XCenter);

if (Do2ndYPass) {
   // Probe Y once again now that X has been centered (for better detail)
   Probe_RC('Y', '-', MobilePlateHoleDiameter, RetractDistance, CoarseRate, FineRate);

   // Get YMin
   YMin = exec.GetYmachpos();

   // Retract to Y starting Location (Machine Coords)
   ExecAndWait("G53 G0 Y" + YCenter);

   // ***** Probe Y (Positive)
   Probe_RC('Y', '+', MobilePlateHoleDiameter, RetractDistance, CoarseRate, FineRate);

   // Get YMax
   YMax = exec.GetYmachpos();

   // Move Y to Calculated Center (Machine Coords)
   YCenter = (YMax + YMin) / 2;
   ExecAndWait("G53 G0 Y" + YCenter);
}

// Set all workspaces to new X Zero
SetAllWorkspaceX(0);

// Set all workspaces to new Y Zero
SetAllWorkspaceY(0);

// Retract Z and move to Z probe Location (Relative)
exec.Code("G91");
ExecAndWait("G0 Z" + XYProbeRetract);
ExecAndWait("G0 X" + MobilePlateHoleOffsetX + " Y" + MobilePlateHoleOffsetY);
exec.Code("G90");

// ***** Probe Z
Probe_RC('Z', '-', XYProbeRetract, RetractDistance, CoarseRate, FineRate);

// Get ZProbe Height in machine coordinate
ZMobilePlate = exec.GetZmachpos();

// Set all workspaces to probed Z Height
SetAllWorkspaceZ(MobilePlateThickness);

// Request Probe Action
ExecAndWait("G53 G0 Z" + SafeZ);
ShowMessage("Please remove MOBILE Probe (Detach Lead!)", MacroID + ": Remove MOBILE Probe");

// ***** Probe the Fixed Plate

// Move to the Fixed Plate
SafeMove_MC(SafeZ, FixedPlateX, FixedPlateY, SafeZ);

// Request Probe Action
ShowMessage("Please prepare FIXED Probe (Attach Lead!)", MacroID + ": Prepare FIXED Probe");

// Probe Z
Probe_RC('Z', '-', ZMaxProbeDist, RetractDistance, CoarseRate, FineRate);

// Get the Z-value for the Fixed Plate
ZFixedPlate = exec.GetZmachpos();

// Calculate the difference between the fixed plate and Probed Zero
PlateOffset = ZFixedPlate - ZMobilePlate + MobilePlateThickness;

// PRESERVE Plate Difference using desired Storage Method
SavePlateOffset(PlateOffset, StorageMethod);

// Request Probe Action
ExecAndWait("G53 G0 Z" + SafeZ);
ShowMessage("Please disable FIXED Probe (Detach Lead!)", MacroID + ": Disable FIXED Probe");

// Prepare for Tool Change (If Needed)
SafeMove_MC(SafeZ, ToolChangeX, ToolChangeY, ToolChangeZ);

// Reinstall Dust Shoe?
if (DustShoe) ShowMessage("Please re-install DUST SHOE", MacroID + ": XYZ Probe Complete!");

// ***** Support FUNCTIONS **********************************************************

#Events

void ShowMessage(string Message, string Title="") {
   MessageBox.Show(exec.mainform, Message, Title);
}

void SafeMove_MC(double SafeZ_MC, double X_MC, double Y_MC, double Z_MC, int msWait=200) {

   // Retract to SafeZ
   ExecAndWait("G53 G0 Z" + SafeZ_MC, msWait);

   // Move to X, Y
   ExecAndWait("G53 G0 X" + X_MC + " Y" + Y_MC, msWait);

   // Move to Z
   ExecAndWait("G53 G0 Z" + Z_MC, msWait);

}

void Probe_RC(char Axis, char Direction, double MaxDist, double RetractDist, double CoarseRate, double FineRate, int msWait=200) {

   double FineDist = RetractDist * 2;

   // Set Relative Mode for Probing
   exec.Code("G91");

   // Probe Quickly
   if (Direction == '-') ExecAndWait("G31 " + Axis + '-' + MaxDist + "F" + CoarseRate, msWait);
   else ExecAndWait("G31 " + Axis + MaxDist + "F" + CoarseRate, msWait);

   // Retract (Reverse)
   if (Direction == '-') ExecAndWait("G0 " + Axis + RetractDist, msWait);
   else ExecAndWait("G0 " + Axis + '-' + RetractDist, msWait);

   // Probe Slowly
   if (Direction == '-') ExecAndWait("G31 " + Axis + '-' + FineDist + "F" + FineRate, msWait);
   else ExecAndWait("G31 " + Axis + FineDist + "F" + FineRate, msWait);

   // Reset Absolute Mode
   exec.Code("G90");
}

double GetPlateOffset(int method = -1) {

   // RETRIEVE the Plate Difference

   switch(method) {
        case -2:            // From the running Profile
             return Convert.ToDouble(exec.Readkey("XYZProbeData", "PlateOffset", "0.0000"));

        case -1:            // From the C axis DRO
             return exec.GetCpos();

        default:            // From the specified internal variable
             return exec.Getvar(method);

   }
}

void SavePlateOffset(double offset, int method = -1) {


   // PRESERVE the Plate Difference

   switch(method) {
        case -2:            // To the running Profile
             exec.Writekey("XYZProbeData", "PlateOffset", Convert.ToString(offset));
         break;

        case -1:            // To the C axis DRO
             SetAllWorkspaceC(offset);
         break;

        default:            // To the specified internal variable
             exec.Setvar(offset, method);
         break;

   }

   return;
}

void ExecAndWait(string Command, int msWait=200) {

   exec.Code(Command);
   while(exec.IsMoving()){}
   exec.Wait(msWait);

}

void SetAllWorkspaceX(double value) {
   exec.mainform.sumoffsetcontrol1.G54.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G55.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G56.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G57.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G58.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G59.newCxinput(value);
}

void SetAllWorkspaceY(double value) {
   exec.mainform.sumoffsetcontrol1.G54.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G55.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G56.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G57.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G58.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G59.newCyinput(value);
}

void SetAllWorkspaceZ(double value) {
   exec.mainform.sumoffsetcontrol1.G54.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G55.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G56.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G57.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G58.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G59.newCzinput(value);
}

void SetAllWorkspaceC(double value) {
   exec.mainform.sumoffsetcontrol1.G54.newCcinput(value);
   exec.mainform.sumoffsetcontrol1.G55.newCcinput(value); 
   exec.mainform.sumoffsetcontrol1.G56.newCcinput(value); 
   exec.mainform.sumoffsetcontrol1.G57.newCcinput(value); 
   exec.mainform.sumoffsetcontrol1.G58.newCcinput(value); 
   exec.mainform.sumoffsetcontrol1.G59.newCcinput(value);
}


M6 Tool Change Macro
Code: Select all
// Custom M6 Manual TOOL CHANGE MACRO
// Simulates Carbide Motion (Nomad, Shapeko) BITZERO Probing Function (X, Y, Z)

// Requires Both a Mobile Plate (For initial M31 Workspace X, Y, Z) and a Fixed Plate (to support ongoing automatic Zeroing in the Z axis after M6 tool changes)

// * Mobile Plate: An XYZ Touch Plate (with XY Hole) is used to simulate the Carbide3D BitZero functionality
// * Fixed Plate: Any standard Touch Plate may be affixed to the router bed

// * UCCNC must be specifically configured (in Settings) to run an M6 Macro (default setting = do nothing)

// * The design software post processor for the machine must be configured to support tool changes (a "UCCNC ATC" vectric post processor is also provided)

// The machine must be Homed prior to this activity
// The macro will position the spindle at the desired location for a manual tool change
// The macro will then transition to the fixed plate to Z-Probe the new router bit and update the Workspace Z Zero.
// The Z Offset difference between the fixed plate and workspace Zero is stored/maintained in the C-Axis DRO, as a Profile Entry, or an internal variable as specified by "StorageMethod".
// The companion M31 macro is required to perform the initial probing and store the Workspace/Fixed Plate Z Offset as desired


// Start Configuration Block:  ***************************************************************************
// Can be directly copy/pasted (shared) between M20031 and M6 macros - as such some variables are not actually used by both macros

// MOBILE Plate Characteristics      // (Only used by M20031)
double MobilePlateThickness = 5.10;   // Thickness of the Probing Plate
double MobilePlateHoleDiameter = 14.7;   // Diameter of Origin Hole (used for side probe limits)
double MobilePlateHoleDepth = 4.9;   // Depth of the Origin Hole (used for retract: 2x)
double MobilePlateHoleOffsetX = 18;   // Offset to Z Probe Point (Relative from Origin Center)
double MobilePlateHoleOffsetY = 18;   // Offset to Z Probe Point (Relative from Origin Center)

// FIXED Plate Characteristics
double FixedPlateX = 364.4;      // Fixed plate X position (machine coordinate)
double FixedPlateY = 20.7;      // Fixed plate Y position (machine coordinate)

// TOOL CHANGE Location
double ToolChangeX = 180;        // Tool change X position (machine coordinate)
double ToolChangeY = 0;        // Tool change Y position (machine coordinate)
double ToolChangeZ = 0;         // Tool change Z position (machine coordinate)

// Tuning Parameters
double SafeZ = 0;         // Safe Z in (machine coordinate) Note: Machine homing should produce a Z=0 (Machine Coord) at Upper limit of Safe Z Travel
double RetractDistance = 1;        // Height above Z0 to which probe will retract
double CoarseRate = 150;       // Feed rate for initial probing
double FineRate = 25;           // Feed rate for fine probing
double ZMaxProbeDist = 70;       // maximum probing distance
bool   DustShoe = true;         // Pause/Prompt for Dust Shoe?
int    StorageMethod = -1;      // -1 to use C-Axis DRO, -2 to use Profile (file), or any other integer for internal variable (0-5999 excluding 5060-5066 and 5039 which are reserved)
int    OKDelay = 5000;         // Time to wait (ms) after "OK" on initial probe prompt (to allow manual stabilization of Mobile Touch Plate) (Only used by M20031)
bool   Do2ndYPass = false;      // Do a second Y Zero pass for increased accuracy (again after X Zero) (Only used by M20031)
bool   ReturnToOriginalXY = true;   // return to the same coordinates where the Tool Change was requested (Only used by M6)
bool   PerformToolCheck = true;      // Enable check for valid tool number (T#) (disable for manual testing) (Only used by M6)
bool   ValidOffsetCheck = true;      // Enable check for valid plate offset (non-zero) (Only used by M6)

// End Configuration Block:  *****************************************************************************


// Macro ID (For use in title of Message Boxes)
string MacroID = "M6";

// Working Variables
int Newtool;
int Currenttool;
double PlateOffset;
double XOriginal_MC;
double YOriginal_MC;
double ZOriginal_WC;

// Machine must be homed for safety
if(!exec.GetLED(56)||!exec.GetLED(57)||!exec.GetLED(58)) {
   ShowMessage("The machine must be HOMED before this activity!", MacroID + ": Fatal Error!");
   exec.Stop();
   return;
}

Newtool = exec.Getnewtool();
Currenttool = exec.Getcurrenttool();

// Check/Process Tool Number (T#)
if(PerformToolCheck) {

   // If new tool number is -1 means a missing T code
   if(Newtool == -1) {
      ShowMessage("No Tool Specified.  Missing T code!", MacroID + ": Fatal Error!");
      exec.Stopspin();
      exec.Stop();
      return;
   }

   // Same tool was selected, nothing to do...
   if(Newtool == Currenttool) {
      ShowMessage("Same Tool Requested.  Nothing to do.  Hit OK to continue...", MacroID + ": Info");
      return;
   }
}

// Turn off spindle
exec.Stopspin();

// Retrieve the plate difference from the chosen storage method
PlateOffset = GetPlateOffset(StorageMethod);

// If PlateOffset is EXACTLY zero, its EXTREMELY likely that the M20031 has not yet been run...
if(ValidOffsetCheck && (PlateOffset == 0.0)) {
   ShowMessage("Plate Offset does not appear to be valid (0.00 exactly)!  Has M20031 been run?", MacroID + ": Fatal Error!");
   exec.Stop();
   return;
}

// Get the current machine coordinates
XOriginal_MC = exec.GetXmachpos();   // (machine coordinate)
YOriginal_MC = exec.GetYmachpos();   // (machine coordinate)
ZOriginal_WC = exec.GetZpos();      // (workspace coordinate)

// Move to tool change position
SafeMove_MC(SafeZ, ToolChangeX, ToolChangeY, ToolChangeZ);

// Prompt: Tool Change
if (DustShoe) ShowMessage("TOOL " + Newtool + " Requested. Please remove DUST SHOE and perform TOOL CHANGE", MacroID + ": Perform Tool Change");
else ShowMessage("TOOL " + Newtool + " Requested. Please perform TOOL CHANGE", MacroID + ": Perform Tool Change");   

//Move to Fixed Plate Position
SafeMove_MC(SafeZ, FixedPlateX, FixedPlateY, SafeZ);

// Prompt: Attach Probe
ShowMessage("Please Attach FIXED PLATE Probe", MacroID + ": Prepare FIXED Probe");
   
// Probe Z
Probe_RC('Z', '-', ZMaxProbeDist, RetractDistance, CoarseRate, FineRate);

// Update G54-G59 to new Z zero (Tip of the router bit is now at "PlateOffset")
SetAllWorkspaceZ(PlateOffset);

// Prompt: Detach Probe
SafeMove_MC(SafeZ, FixedPlateX, FixedPlateY, SafeZ);
if (DustShoe) ShowMessage("Please Remove FIXED PLATE Probe and install DUST SHOE", MacroID + ": Tool Change Complete!");
else ShowMessage("Please Remove FIXED PLATE Probe", MacroID + ": Tool Change Complete!");   

// Return to Original X, Y or to Tool Change as desired (Machine Coords)
if(ReturnToOriginalXY) SafeMove_MC(SafeZ, XOriginal_MC, YOriginal_MC, SafeZ);
else SafeMove_MC(SafeZ, ToolChangeX, ToolChangeY, ToolChangeZ);

// ***** Support FUNCTIONS **********************************************************

#Events

void ShowMessage(string Message, string Title="") {
   MessageBox.Show(exec.mainform, Message, Title);
}

void SafeMove_MC(double SafeZ_MC, double X_MC, double Y_MC, double Z_MC, int msWait=200) {

   // Retract to SafeZ
   ExecAndWait("G53 G0 Z" + SafeZ_MC, msWait);

   // Move to X, Y
   ExecAndWait("G53 G0 X" + X_MC + " Y" + Y_MC, msWait);

   // Move to Z
   ExecAndWait("G53 G0 Z" + Z_MC, msWait);

}

void Probe_RC(char Axis, char Direction, double MaxDist, double RetractDist, double CoarseRate, double FineRate, int msWait=200) {

   double FineDist = RetractDist * 2;

   // Set Relative Mode for Probing
   exec.Code("G91");

   // Probe Quickly
   if (Direction == '-') ExecAndWait("G31 " + Axis + '-' + MaxDist + "F" + CoarseRate, msWait);
   else ExecAndWait("G31 " + Axis + MaxDist + "F" + CoarseRate, msWait);

   // Retract (Reverse)
   if (Direction == '-') ExecAndWait("G0 " + Axis + RetractDist, msWait);
   else ExecAndWait("G0 " + Axis + '-' + RetractDist, msWait);

   // Probe Slowly
   if (Direction == '-') ExecAndWait("G31 " + Axis + '-' + FineDist + "F" + FineRate, msWait);
   else ExecAndWait("G31 " + Axis + FineDist + "F" + FineRate, msWait);

   // Reset Absolute Mode
   exec.Code("G90");
}

double GetPlateOffset(int method = -1) {

   // RETRIEVE the Plate Difference

   switch(method) {
        case -2:            // From the running Profile
             return Convert.ToDouble(exec.Readkey("XYZProbeData", "PlateOffset", "0.0000"));

        case -1:            // From the C axis DRO
             return exec.GetCpos();

        default:            // From the specified internal variable
             return exec.Getvar(method);

   }
}

void SavePlateOffset(double offset, int method = -1) {


   // PRESERVE the Plate Difference

   switch(method) {
        case -2:            // To the running Profile
             exec.Writekey("XYZProbeData", "PlateOffset", Convert.ToString(offset));
         break;

        case -1:            // To the C axis DRO
             SetAllWorkspaceC(offset);
         break;

        default:            // To the specified internal variable
             exec.Setvar(offset, method);
         break;

   }

   return;
}

void ExecAndWait(string Command, int msWait=200) {

   exec.Code(Command);
   while(exec.IsMoving()){}
   exec.Wait(msWait);

}

void SetAllWorkspaceX(double value) {
   exec.mainform.sumoffsetcontrol1.G54.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G55.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G56.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G57.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G58.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G59.newCxinput(value);
}

void SetAllWorkspaceY(double value) {
   exec.mainform.sumoffsetcontrol1.G54.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G55.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G56.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G57.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G58.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G59.newCyinput(value);
}

void SetAllWorkspaceZ(double value) {
   exec.mainform.sumoffsetcontrol1.G54.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G55.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G56.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G57.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G58.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G59.newCzinput(value);
}

void SetAllWorkspaceC(double value) {
   exec.mainform.sumoffsetcontrol1.G54.newCcinput(value);
   exec.mainform.sumoffsetcontrol1.G55.newCcinput(value); 
   exec.mainform.sumoffsetcontrol1.G56.newCcinput(value); 
   exec.mainform.sumoffsetcontrol1.G57.newCcinput(value); 
   exec.mainform.sumoffsetcontrol1.G58.newCcinput(value); 
   exec.mainform.sumoffsetcontrol1.G59.newCcinput(value);
}
evanevery
 
Posts: 20
Joined: Tue Jan 11, 2022 3:57 pm

Re: M6/M31 Macro Pair to emulate Carbide3D Bitzero Probing

Postby Precision Composites » Wed Sep 04, 2024 5:28 pm

Thank you! The vendor/builder for our machine and myself are looking into this.

Moments ago, I solved the issue of machine DROs not zeroing out during homing: Auto Set for each axis not selected. This will make it faster to reset the machine DROs after a crash.

FYI- We do use the XYZ block from OpenBuilds, but currently use the Macro from Triquetra-CNC. I never use the hole in the block.
Precision Composites
 
Posts: 12
Joined: Mon Mar 06, 2023 9:26 pm

Re: M6/M31 Macro Pair to emulate Carbide3D Bitzero Probing

Postby evanevery » Wed Sep 04, 2024 9:37 pm

Yup, I was going to mention the Axis setup to make sure your machine coordinates are zero'ed when homing... Homing gives you a repeatable coordinate system for your physical machine and these M6/M20031 macros give you a repeatable coordinate system for your work piece.

Precision Composites wrote:...FYI- We do use the XYZ block from OpenBuilds, but currently use the Macro from Triquetra-CNC. I never use the hole in the block.


I started using the XYZ block from OpenBuilds but found I was always fighting with the cable connector and the pull of the cables trying to twist the block. These macros work the same with any plate with an XY hole but I actually like the simplicity of the "Chinese" XYZ block. The only thing which changes is the mobile plate characteristics in the "configuration block" in the macros. (I actually had code in there to allow me to swap mobile plates (OpenBuilds <-> Chinese) with a single edit but I found I wasn't using the OpenBuilds at all and I thought it might be unnecessarily confusing to the community).

I also have the Triquetra mobile plate and I like how stable and heavy it is. (I also really like the strength of their magnet/probe). I've never used their macro's though. I think zeroing with an XY hole is far superior to the Triquetra's edge detection since the diameter of the probing bit and the offset/width of the plate edges don't need to be specified (the methodology of the XY hole makes them irrelevant).

Since I liked the Triquetra magnet/probe so much, I also designed a 3D printed magnet probe to replicate it. I never cut open the Triquetra magnet/probe so I had to figure out a way to make a reliable electrical connection to a cylindrical neodymium magnet. Can't solder to a magnet, can't drill a magnet, etc... My magnetic probe consists of a 3d printed cylinder/sleeve and end cap, a cylindrical neodymium magnet, a spring to solder the lead wire to, and a ball bearing which is pressed between the spring and the cylindrical magnet to maintain a reliable electrical connection. The magnet slides down into the sleeve where there is a little internal ridge to hold it. Epoxy is then injected into a hole in the side of the 3D printed sleeve and the magnet is rotated by hand to smear it around. (There is also a little channel on the inside of the sleeve around the magnet to aid the distribution of the epoxy). The positioning ridge also helps keep the epoxy from seeping down further into the sleeve (where the electrical connection is made). Once the epoxy has set, the ball bearing and spring/wire are then dropped into the other end of the sleeve and an end cap (with hole for wire) is then glued in place to hold it together (and maintain tension on the spring and ball bearing). Made 8 of them now (the original 4 - Version 1.0 - didn't have the internal ridge, epoxy hole, or epoxy channel).
evanevery
 
Posts: 20
Joined: Tue Jan 11, 2022 3:57 pm

Re: M6/M31 Macro Pair to emulate Carbide3D Bitzero Probing

Postby evanevery » Thu Sep 05, 2024 3:00 pm

You mentioned "resetting DRO's after a crash". This got me thinking. With a few simple additions to the macro's, we could preserve data in the profile (file) to document the critical info of each zero'ing (M20031) and bit change (M6) operation. By doing this, that data could be used to quite easily restore the coordinate environment after a crash (or power outage, etc). So, here are the updated macro's to support this. Changes are as follows:

* Note that the following changes are independent of the operational "StorageMethod" in use (can be enabled/disabled by using the "SaveRecoveryData" variable):
- Tool Change Macro (M20031) now preserves the XY Machine coords for the workspace XY zero in the profile
- Tool Change Macro (M20031) now preserves the "PlateOffset" value (difference between fixed plate Z-Zero and Workpiece Z-Zero) in the profile
- Both Macro's now also store the BIT-DEPENDENT Z Machine coord for the Workspace Z-Zero (after calculating this using the fixed plate) in the profile. NOTE that this value is only really of any use if the tool bit HAS NOT BEEN CHANGED since the "crash".

- I also added the ability to have the XYZ Probe Macro (M20031) automatically perform the homing operation if it has not already been performed (instead of simply posting an error). This can be disabled/enabled using the "AutoHome" variable. The goal here is that M20031 can simply serve as an all-around "initialization" macro (homing + probing)

- I've added versioning info to the file (as we now have several versions posted)

I'm going to develop a couple of "recovery" macro's next. (This shouldn't take long) They will use the most recent probing data preserved in the profile to quickly re-establish a zeroed coordinate system from an "interrupted" job (crash, power outage, etc)


M20031 Initialization (XYZ Probing) Macro
Code: Select all
// Custom M20031 PROBING MACRO
// Simulates Carbide Motion (Nomad, Shapeko) BITZERO Probing Function (X, Y, Z)

// Edward C. Van Every, Version 1.03

// Requires Both a Mobile Plate (For initial M31 Workspace X, Y, Z) and a Fixed Plate (to support ongoing automatic Zeroing in the Z axis after M6 tool changes)

// * Mobile Plate: An XYZ Touch Plate (with XY Hole) is used to simulate the Carbide3D BitZero functionality
// * Fixed Plate: Any standard Touch Plate may be affixed to the router bed

// * UCCNC must be specifically configured (in Settings) to run an M6 Macro (default setting = do nothing)

// * The design software post processor for the machine must be configured to support tool changes (a "UCCNC ATC" vectric post processor is also provided)

// The machine must be Homed prior to this activity
// The operator should use a cylindrical touch bit probe in the chuck (not a router bit) for best accuracy
// The operator should manually position the touch bit probe down into the approximate center of the XY Hole of the mobile plate before running this operation
// This macro will first run the X/Y probe inside the mobile plate XY Hole, then lift and reposition to perform a Z probe on the mobile plate
// The Y-Axis probe will run twice for increased accuracy after the approximate center is found (ie: Y probe, X probe, second Y probe)
// This macro will then transition to the location of the fixed plate to calculate the height difference between the Workspace and Fixed plates
// The Z Offset difference between the workspace and fixed plate is stored/maintained in the C-Axis DRO, as a Profile Entry, or an internal variable as specified by "StorageMethod".
// The companion M6 macro is required to retrieve the Mobile/Fixed Plate Difference (offset) and support the Fixed Plate and automatic Workspace Z Zeroing during tool changes


// Start Configuration Block:  ***************************************************************************
// Can be directly copy/pasted (shared) between M20031 and M6 macros - as such some variables are not actually used by both macros

// MOBILE Plate Characteristics      // (Only used by M20031)
double MobilePlateThickness = 5.10;   // Thickness of the Probing Plate
double MobilePlateHoleDiameter = 14.7;   // Diameter of Origin Hole (used for side probe limits)
double MobilePlateHoleDepth = 4.9;   // Depth of the Origin Hole (used for retract: 2x)
double MobilePlateHoleOffsetX = 18;   // Offset to Z Probe Point (Relative from Origin Center)
double MobilePlateHoleOffsetY = 18;   // Offset to Z Probe Point (Relative from Origin Center)

// FIXED Plate Characteristics
double FixedPlateX = 364.4;      // Fixed plate X position (machine coordinate)
double FixedPlateY = 20.7;      // Fixed plate Y position (machine coordinate)

// TOOL CHANGE Location
double ToolChangeX = 180;        // Tool change X position (machine coordinate)
double ToolChangeY = 0;        // Tool change Y position (machine coordinate)
double ToolChangeZ = 0;         // Tool change Z position (machine coordinate)

// Tuning Parameters
double SafeZ = 0;         // Safe Z in (machine coordinate) Note: Machine homing should produce a Z=0 (Machine Coord) at Upper limit of Safe Z Travel
double RetractDistance = 1;        // Height above Z0 to which probe will retract
double CoarseRate = 150;       // Feed rate for initial probing
double FineRate = 25;           // Feed rate for fine probing
double ZMaxProbeDist = 70;       // maximum probing distance
bool   DustShoe = true;         // Pause/Prompt for Dust Shoe?
int    StorageMethod = -1;      // -1 to use C-Axis DRO, -2 to use Profile (file), or any other integer for internal user variable (0-999)
bool   SaveRecoveryData = true;      // Enabling this will save workspace coordinate translation data to the current profile to assist in post-crash recoveries.
bool   AutoHome = true;         // Will automatically solicit the homing process if not already done (otherwise post error and quit) (Only used by M20031)
int    OKDelay = 5000;         // Time to wait (ms) after "OK" on initial probe prompt (to allow manual stabilization of Mobile Touch Plate) (Only used by M20031)
bool   Do2ndYPass = false;      // Do a second Y Zero pass for increased accuracy (again after X Zero) (Only used by M20031)
bool   ReturnToOriginalXY = true;   // return to the same coordinates where the Tool Change was requested (Only used by M6)
bool   PerformToolCheck = true;      // Enable check for valid tool number (T#) (disable for manual testing) (Only used by M6)
bool   ValidOffsetCheck = true;      // Enable check for valid plate offset (non-zero) (Only used by M6)

// End Configuration Block:  *****************************************************************************


// Macro ID (For use in title of Message Boxes)
string MacroID = "M20031";

// Calculated Parameters
double XYProbeRetract = MobilePlateHoleDepth * 2;
double DoubleRetractDistance = RetractDistance * 2;

// Working Variables
double XSave;
double YSave;
double ZSave;
double YMax;
double YMin;
double XMax;
double XMin;
double XCenter;
double YCenter;
double ZMobilePlate;
double ZFixedPlate;
double PlateOffset;

// Machine must be homed for safety
if(!exec.GetLED(56)||!exec.GetLED(57)||!exec.GetLED(58)) {

   if(AutoHome) {
      ShowMessage("Device not HOMED!  Press OK to perform AutoHome.");
      PerformAutoHome();

   } else {
      ShowMessage("The machine must be HOMED before this activity!", MacroID + ": Fatal Error!");
      exec.Stop();
      return;
   }
}

// Get current X, Y, Z
XSave = exec.GetXmachpos();
YSave = exec.GetYmachpos();
ZSave = exec.GetZmachpos();

// Request Probe Action
if (DustShoe) ShowMessage("Please remove DUST SHOE and prepare MOBILE Probe (Attach Lead, Position the Probe and Spindle!)", MacroID + ": Prepare MOBILE Probe");
else ShowMessage("Please prepare MOBILE Probe (Attach Lead, Position the Probe and Spindle!)", MacroID + ": Prepare MOBILE Probe");

// Allow a few seconds for the operator to hold/stabilize the Mobile Touch Plate after clicking "OK"
exec.Wait(OKDelay);

// ***** Probe Y (Negative)
Probe_RC('Y', '-', MobilePlateHoleDiameter, RetractDistance, CoarseRate, FineRate);

// Get YMin
YMin = exec.GetYmachpos();

// Retract to Y starting Location (Machine Coords)
ExecAndWait("G53 G0 Y" + YSave);

// ***** Probe Y (Positive)
Probe_RC('Y', '+', MobilePlateHoleDiameter, RetractDistance, CoarseRate, FineRate);

// Get YMax
YMax = exec.GetYmachpos();

// Move Y to Calculated Center (Machine Coords)
YCenter = (YMax + YMin) / 2;
ExecAndWait("G53 G0 Y" + YCenter);

// ***** Probe X (Negative)
Probe_RC('X', '-', MobilePlateHoleDiameter, RetractDistance, CoarseRate, FineRate);

// Get XMin
XMin = exec.GetXmachpos();

// Retract to X starting Location (Machine Coords)
ExecAndWait("G53 G0 X" + XSave);

// ***** Probe X (Positive)
Probe_RC('X', '+', MobilePlateHoleDiameter, RetractDistance, CoarseRate, FineRate);

// Get XMax
XMax = exec.GetXmachpos();

// Move X to Calculated Center (Machine Coords)
XCenter = (XMax + XMin) / 2;
ExecAndWait("G53 G0 X" + XCenter);

if (Do2ndYPass) {
   // Probe Y once again now that X has been centered (for better detail)
   Probe_RC('Y', '-', MobilePlateHoleDiameter, RetractDistance, CoarseRate, FineRate);

   // Get YMin
   YMin = exec.GetYmachpos();

   // Retract to Y starting Location (Machine Coords)
   ExecAndWait("G53 G0 Y" + YCenter);

   // ***** Probe Y (Positive)
   Probe_RC('Y', '+', MobilePlateHoleDiameter, RetractDistance, CoarseRate, FineRate);

   // Get YMax
   YMax = exec.GetYmachpos();

   // Move Y to Calculated Center (Machine Coords)
   YCenter = (YMax + YMin) / 2;
   ExecAndWait("G53 G0 Y" + YCenter);
}

// Set all workspaces to new X Zero
SetAllWorkspaceX(0);

// Set all workspaces to new Y Zero
SetAllWorkspaceY(0);

// Retract Z and move to Z probe Location (Relative)
exec.Code("G91");
ExecAndWait("G0 Z" + XYProbeRetract);
ExecAndWait("G0 X" + MobilePlateHoleOffsetX + " Y" + MobilePlateHoleOffsetY);
exec.Code("G90");

// ***** Probe Z
Probe_RC('Z', '-', XYProbeRetract, RetractDistance, CoarseRate, FineRate);

// Get ZProbe Height in machine coordinate
ZMobilePlate = exec.GetZmachpos();

// Set all workspaces to probed Z Height
SetAllWorkspaceZ(MobilePlateThickness);

// Request Probe Action
ExecAndWait("G53 G0 Z" + SafeZ);
ShowMessage("Please remove MOBILE Probe (Detach Lead!)", MacroID + ": Remove MOBILE Probe");

// ***** Probe the Fixed Plate

// Move to the Fixed Plate
SafeMove_MC(SafeZ, FixedPlateX, FixedPlateY, SafeZ);

// Request Probe Action
ShowMessage("Please prepare FIXED Probe (Attach Lead!)", MacroID + ": Prepare FIXED Probe");

// Probe Z
Probe_RC('Z', '-', ZMaxProbeDist, RetractDistance, CoarseRate, FineRate);

// Get the Z-value for the Fixed Plate
ZFixedPlate = exec.GetZmachpos();

// Calculate the difference between the fixed plate and Probed Zero
PlateOffset = ZFixedPlate - ZMobilePlate + MobilePlateThickness;

// PRESERVE Plate Difference using desired Storage Method
SavePlateOffset(PlateOffset, StorageMethod);

// Preserve X/Y Recovery data to current profile if so configured
if (SaveRecoveryData) {
   exec.Writekey("XYZProbeData", "WorkXZero", Convert.ToString(XCenter));
   exec.Writekey("XYZProbeData", "WorkYZero", Convert.ToString(YCenter));
   exec.Writekey("XYZProbeData", "WorkZZero", Convert.ToString(ZMobilePlate - MobilePlateThickness));   // Accurate for this bit only!
   exec.Writekey("XYZProbeData", "PlateOffset", Convert.ToString(PlateOffset));            // Can be used to calc ZZero with a different bit
}

// Request Probe Action
ExecAndWait("G53 G0 Z" + SafeZ);
ShowMessage("Please disable FIXED Probe (Detach Lead!)", MacroID + ": Disable FIXED Probe");

// Prepare for Tool Change (If Needed)
SafeMove_MC(SafeZ, ToolChangeX, ToolChangeY, ToolChangeZ);

// Reinstall Dust Shoe?
if (DustShoe) ShowMessage("Please re-install DUST SHOE", MacroID + ": XYZ Probe Complete!");

// ***** Support FUNCTIONS **********************************************************

#Events

void ShowMessage(string Message, string Title="") {
   MessageBox.Show(exec.mainform, Message, Title);
}

void SafeMove_MC(double SafeZ_MC, double X_MC, double Y_MC, double Z_MC, int msWait=200) {

   // Retract to SafeZ
   ExecAndWait("G53 G0 Z" + SafeZ_MC, msWait);

   // Move to X, Y
   ExecAndWait("G53 G0 X" + X_MC + " Y" + Y_MC, msWait);

   // Move to Z
   ExecAndWait("G53 G0 Z" + Z_MC, msWait);

}

void Probe_RC(char Axis, char Direction, double MaxDist, double RetractDist, double CoarseRate, double FineRate, int msWait=200) {

   double FineDist = RetractDist * 2;

   // Set Relative Mode for Probing
   exec.Code("G91");

   // Probe Quickly
   if (Direction == '-') ExecAndWait("G31 " + Axis + '-' + MaxDist + "F" + CoarseRate, msWait);
   else ExecAndWait("G31 " + Axis + MaxDist + "F" + CoarseRate, msWait);

   // Retract (Reverse)
   if (Direction == '-') ExecAndWait("G0 " + Axis + RetractDist, msWait);
   else ExecAndWait("G0 " + Axis + '-' + RetractDist, msWait);

   // Probe Slowly
   if (Direction == '-') ExecAndWait("G31 " + Axis + '-' + FineDist + "F" + FineRate, msWait);
   else ExecAndWait("G31 " + Axis + FineDist + "F" + FineRate, msWait);

   // Reset Absolute Mode
   exec.Code("G90");
}

void PerformAutoHome(int mswait=1000) {

   exec.Callbutton(113);
   exec.Wait(mswait);
   while(true) {
      if(!exec.GetLED(23)) {
         exec.Wait(mswait);
         if(!exec.GetLED(23)) break;
      }
   }
}

double GetPlateOffset(int method = -1) {

   // RETRIEVE the Plate Difference

   switch(method) {
        case -2:            // From the running Profile
             return Convert.ToDouble(exec.Readkey("XYZProbeData", "PlateOffset", "0.0000"));

        case -1:            // From the C axis DRO
             return exec.GetCpos();

        default:            // From the specified internal variable
             return exec.Getvar(method);

   }
}

void SavePlateOffset(double offset, int method = -1) {


   // PRESERVE the Plate Difference

   switch(method) {
        case -2:            // To the running Profile
             exec.Writekey("XYZProbeData", "PlateOffset", Convert.ToString(offset));
         break;

        case -1:            // To the C axis DRO
             SetAllWorkspaceC(offset);
         break;

        default:            // To the specified internal variable
             exec.Setvar(offset, method);
         break;

   }

   return;
}

void ExecAndWait(string Command, int msWait=200) {

   exec.Code(Command);
   while(exec.IsMoving()){}
   exec.Wait(msWait);

}

void SetAllWorkspaceX(double value) {
   exec.mainform.sumoffsetcontrol1.G54.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G55.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G56.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G57.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G58.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G59.newCxinput(value);
}

void SetAllWorkspaceY(double value) {
   exec.mainform.sumoffsetcontrol1.G54.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G55.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G56.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G57.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G58.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G59.newCyinput(value);
}

void SetAllWorkspaceZ(double value) {
   exec.mainform.sumoffsetcontrol1.G54.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G55.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G56.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G57.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G58.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G59.newCzinput(value);
}

void SetAllWorkspaceC(double value) {
   exec.mainform.sumoffsetcontrol1.G54.newCcinput(value);
   exec.mainform.sumoffsetcontrol1.G55.newCcinput(value); 
   exec.mainform.sumoffsetcontrol1.G56.newCcinput(value); 
   exec.mainform.sumoffsetcontrol1.G57.newCcinput(value); 
   exec.mainform.sumoffsetcontrol1.G58.newCcinput(value); 
   exec.mainform.sumoffsetcontrol1.G59.newCcinput(value);
}


M6 Tool Change Macro
Code: Select all
// Custom M6 Manual TOOL CHANGE MACRO
// Simulates Carbide Motion (Nomad, Shapeko) BITZERO Probing Function (X, Y, Z)

// Edward C. Van Every, Version 1.03

// Requires Both a Mobile Plate (For initial M31 Workspace X, Y, Z) and a Fixed Plate (to support ongoing automatic Zeroing in the Z axis after M6 tool changes)

// * Mobile Plate: An XYZ Touch Plate (with XY Hole) is used to simulate the Carbide3D BitZero functionality
// * Fixed Plate: Any standard Touch Plate may be affixed to the router bed

// * UCCNC must be specifically configured (in Settings) to run an M6 Macro (default setting = do nothing)

// * The design software post processor for the machine must be configured to support tool changes (a "UCCNC ATC" vectric post processor is also provided)

// The machine must be Homed prior to this activity
// The macro will position the spindle at the desired location for a manual tool change
// The macro will then transition to the fixed plate to Z-Probe the new router bit and update the Workspace Z Zero.
// The Z Offset difference between the fixed plate and workspace Zero is stored/maintained in the C-Axis DRO, as a Profile Entry, or an internal variable as specified by "StorageMethod".
// The companion M31 macro is required to perform the initial probing and store the Workspace/Fixed Plate Z Offset as desired


// Start Configuration Block:  ***************************************************************************
// Can be directly copy/pasted (shared) between M20031 and M6 macros - as such some variables are not actually used by both macros

// MOBILE Plate Characteristics      // (Only used by M20031)
double MobilePlateThickness = 5.10;   // Thickness of the Probing Plate
double MobilePlateHoleDiameter = 14.7;   // Diameter of Origin Hole (used for side probe limits)
double MobilePlateHoleDepth = 4.9;   // Depth of the Origin Hole (used for retract: 2x)
double MobilePlateHoleOffsetX = 18;   // Offset to Z Probe Point (Relative from Origin Center)
double MobilePlateHoleOffsetY = 18;   // Offset to Z Probe Point (Relative from Origin Center)

// FIXED Plate Characteristics
double FixedPlateX = 364.4;      // Fixed plate X position (machine coordinate)
double FixedPlateY = 20.7;      // Fixed plate Y position (machine coordinate)

// TOOL CHANGE Location
double ToolChangeX = 180;        // Tool change X position (machine coordinate)
double ToolChangeY = 0;        // Tool change Y position (machine coordinate)
double ToolChangeZ = 0;         // Tool change Z position (machine coordinate)

// Tuning Parameters
double SafeZ = 0;         // Safe Z in (machine coordinate) Note: Machine homing should produce a Z=0 (Machine Coord) at Upper limit of Safe Z Travel
double RetractDistance = 1;        // Height above Z0 to which probe will retract
double CoarseRate = 150;       // Feed rate for initial probing
double FineRate = 25;           // Feed rate for fine probing
double ZMaxProbeDist = 70;       // maximum probing distance
bool   DustShoe = true;         // Pause/Prompt for Dust Shoe?
int    StorageMethod = -1;      // -1 to use C-Axis DRO, -2 to use Profile (file), or any other integer for internal user variable (0-999)
bool   SaveRecoveryData = true;      // Enabling this will save workspace coordinate translation data to the current profile to assist in post-crash recoveries.
bool   AutoHome = true;         // Will automatically solicit the homing process if not already done (otherwise post error and quit) (Only used by M20031)
int    OKDelay = 5000;         // Time to wait (ms) after "OK" on initial probe prompt (to allow manual stabilization of Mobile Touch Plate) (Only used by M20031)
bool   Do2ndYPass = false;      // Do a second Y Zero pass for increased accuracy (again after X Zero) (Only used by M20031)
bool   ReturnToOriginalXY = true;   // return to the same coordinates where the Tool Change was requested (Only used by M6)
bool   PerformToolCheck = true;      // Enable check for valid tool number (T#) (disable for manual testing) (Only used by M6)
bool   ValidOffsetCheck = true;      // Enable check for valid plate offset (non-zero) (Only used by M6)

// End Configuration Block:  *****************************************************************************


// Macro ID (For use in title of Message Boxes)
string MacroID = "M6";

// Working Variables
int Newtool;
int Currenttool;
double PlateOffset;
double XOriginal_MC;
double YOriginal_MC;
double ZOriginal_WC;

// Machine must be homed for safety (If machine is not homed, then M20031 could never have been performed and zeroing data will not be valid!)
if(!exec.GetLED(56)||!exec.GetLED(57)||!exec.GetLED(58)) {
   ShowMessage("The machine must be HOMED before this activity!", MacroID + ": Fatal Error!");
   exec.Stop();
   return;
}

Newtool = exec.Getnewtool();
Currenttool = exec.Getcurrenttool();

// Check/Process Tool Number (T#)
if(PerformToolCheck) {

   // If new tool number is -1 means a missing T code
   if(Newtool == -1) {
      ShowMessage("No Tool Specified.  Missing T code!", MacroID + ": Fatal Error!");
      exec.Stopspin();
      exec.Stop();
      return;
   }

   // Same tool was selected, nothing to do...
   if(Newtool == Currenttool) {
      ShowMessage("Same Tool Requested.  Nothing to do.  Hit OK to continue...", MacroID + ": Info");
      return;
   }
}

// Turn off spindle
exec.Stopspin();

// Retrieve the plate difference from the chosen storage method
PlateOffset = GetPlateOffset(StorageMethod);

// If PlateOffset is EXACTLY zero, its EXTREMELY likely that the M20031 has not yet been run...
if(ValidOffsetCheck && (PlateOffset == 0.0)) {
   ShowMessage("Plate Offset does not appear to be valid (0.00 exactly)!  Has M20031 been run?", MacroID + ": Fatal Error!");
   exec.Stop();
   return;
}

// Get the current machine coordinates
XOriginal_MC = exec.GetXmachpos();   // (machine coordinate)
YOriginal_MC = exec.GetYmachpos();   // (machine coordinate)
ZOriginal_WC = exec.GetZpos();      // (workspace coordinate)

// Move to tool change position
SafeMove_MC(SafeZ, ToolChangeX, ToolChangeY, ToolChangeZ);

// Prompt: Tool Change
if (DustShoe) ShowMessage("TOOL " + Newtool + " Requested. Please remove DUST SHOE and perform TOOL CHANGE", MacroID + ": Perform Tool Change");
else ShowMessage("TOOL " + Newtool + " Requested. Please perform TOOL CHANGE", MacroID + ": Perform Tool Change");   

//Move to Fixed Plate Position
SafeMove_MC(SafeZ, FixedPlateX, FixedPlateY, SafeZ);

// Prompt: Attach Probe
ShowMessage("Please Attach FIXED PLATE Probe", MacroID + ": Prepare FIXED Probe");
   
// Probe Z
Probe_RC('Z', '-', ZMaxProbeDist, RetractDistance, CoarseRate, FineRate);

// Update G54-G59 to new Z zero (Tip of the router bit is now at "PlateOffset")
SetAllWorkspaceZ(PlateOffset);

// Update Z Recovery data for this specific bit to current profile if so configured
if (SaveRecoveryData) exec.Writekey("XYZProbeData", "WorkZZero", Convert.ToString(exec.GetZmachpos() - PlateOffset));

// Prompt: Detach Probe
SafeMove_MC(SafeZ, FixedPlateX, FixedPlateY, SafeZ);
ShowMessage("Please Remove FIXED PLATE Probe", MacroID + ": Remove FIXED Probe");

// Move back to Tool Change to allow Dust Boot to be attached   
SafeMove_MC(SafeZ, ToolChangeX, ToolChangeY, ToolChangeZ);
if (DustShoe) ShowMessage("Please Re-install DUST SHOE", MacroID + ": Re-Install Dust Shoe");

// Return to Original X, Y if so configured (Machine Coords)
if(ReturnToOriginalXY) SafeMove_MC(SafeZ, XOriginal_MC, YOriginal_MC, SafeZ);

// ***** Support FUNCTIONS **********************************************************

#Events

void ShowMessage(string Message, string Title="") {
   MessageBox.Show(exec.mainform, Message, Title);
}

void SafeMove_MC(double SafeZ_MC, double X_MC, double Y_MC, double Z_MC, int msWait=200) {

   // Retract to SafeZ
   ExecAndWait("G53 G0 Z" + SafeZ_MC, msWait);

   // Move to X, Y
   ExecAndWait("G53 G0 X" + X_MC + " Y" + Y_MC, msWait);

   // Move to Z
   ExecAndWait("G53 G0 Z" + Z_MC, msWait);

}

void Probe_RC(char Axis, char Direction, double MaxDist, double RetractDist, double CoarseRate, double FineRate, int msWait=200) {

   double FineDist = RetractDist * 2;

   // Set Relative Mode for Probing
   exec.Code("G91");

   // Probe Quickly
   if (Direction == '-') ExecAndWait("G31 " + Axis + '-' + MaxDist + "F" + CoarseRate, msWait);
   else ExecAndWait("G31 " + Axis + MaxDist + "F" + CoarseRate, msWait);

   // Retract (Reverse)
   if (Direction == '-') ExecAndWait("G0 " + Axis + RetractDist, msWait);
   else ExecAndWait("G0 " + Axis + '-' + RetractDist, msWait);

   // Probe Slowly
   if (Direction == '-') ExecAndWait("G31 " + Axis + '-' + FineDist + "F" + FineRate, msWait);
   else ExecAndWait("G31 " + Axis + FineDist + "F" + FineRate, msWait);

   // Reset Absolute Mode
   exec.Code("G90");
}

void PerformAutoHome(int mswait=1000) {

   exec.Callbutton(113);
   exec.Wait(mswait);
   while(true) {
      if(!exec.GetLED(23)) {
         exec.Wait(mswait);
         if(!exec.GetLED(23)) break;
      }
   }
}

double GetPlateOffset(int method = -1) {

   // RETRIEVE the Plate Difference

   switch(method) {
        case -2:            // From the running Profile
             return Convert.ToDouble(exec.Readkey("XYZProbeData", "PlateOffset", "0.0000"));

        case -1:            // From the C axis DRO
             return exec.GetCpos();

        default:            // From the specified internal variable
             return exec.Getvar(method);

   }
}

void SavePlateOffset(double offset, int method = -1) {


   // PRESERVE the Plate Difference

   switch(method) {
        case -2:            // To the running Profile
             exec.Writekey("XYZProbeData", "PlateOffset", Convert.ToString(offset));
         break;

        case -1:            // To the C axis DRO
             SetAllWorkspaceC(offset);
         break;

        default:            // To the specified internal variable
             exec.Setvar(offset, method);
         break;

   }

   return;
}

void ExecAndWait(string Command, int msWait=200) {

   exec.Code(Command);
   while(exec.IsMoving()){}
   exec.Wait(msWait);

}

void SetAllWorkspaceX(double value) {
   exec.mainform.sumoffsetcontrol1.G54.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G55.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G56.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G57.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G58.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G59.newCxinput(value);
}

void SetAllWorkspaceY(double value) {
   exec.mainform.sumoffsetcontrol1.G54.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G55.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G56.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G57.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G58.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G59.newCyinput(value);
}

void SetAllWorkspaceZ(double value) {
   exec.mainform.sumoffsetcontrol1.G54.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G55.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G56.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G57.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G58.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G59.newCzinput(value);
}

void SetAllWorkspaceC(double value) {
   exec.mainform.sumoffsetcontrol1.G54.newCcinput(value);
   exec.mainform.sumoffsetcontrol1.G55.newCcinput(value); 
   exec.mainform.sumoffsetcontrol1.G56.newCcinput(value); 
   exec.mainform.sumoffsetcontrol1.G57.newCcinput(value); 
   exec.mainform.sumoffsetcontrol1.G58.newCcinput(value); 
   exec.mainform.sumoffsetcontrol1.G59.newCcinput(value);
}
evanevery
 
Posts: 20
Joined: Tue Jan 11, 2022 3:57 pm

Re: M6/M31 Macro Pair to emulate Carbide3D Bitzero Probing

Postby evanevery » Thu Sep 05, 2024 4:27 pm

OK, here are some "Recovery" macros which use the newly stored data in the active profile (file).

Note that the accuracy of these recovery macros are going to be somewhat dependent on the repeatable precision of your end stops or limit switches. As long as you have reasonably good end stops or limit switches, which produce a reasonably repeatable homing operation, then we should be able to restore the machine and work coordinate system after some sort of crash or power outage, etc.

These Recovery Macros are dependent on the information preserved in the profile by my specific XYZ Probe (M20031) and Tool Change (M6) macros. As long as you are routinely using both of them, then this data will be correspondingly maintained and accurate.

I have provided TWO "Recovery" macros:

The "Old Bit" Recovery macro can be used after a crash/outage as long as the tool bit in the spindle is exactly the same one that was in place during the event. It can not have been re-seated, replaced, broken, etc. The exact length of the tool bit (below the spindle) is a critical in re-establishing the coordinate systems if you want to use the "Old Bit" Recovery Macro. Its quick, requires no gantry moves (unless its necessary to AutoHome the machine), and does not require use of the Fixed Plate at all.

The "New Bit" Recovery macro can be used if the tool bit has been changed (or not). It will restore the preserved profile data and then use the fixed plate to adjust the Z coordinate for a new bit. It takes a little longer (due to the Z Probing) but it can be used in the event that the bit was replaced or re-seated.

OLD BIT Recovery Macro:
Code: Select all
// "Old Bit" Recovery
// Restores workspace coordinate system from data preserved in profile

// ONLY VALID if the tool bit has NOT been changed since the crash, power outage, etc

// Edward C. Van Every, Version 1.03

// Operational Configuration
bool AutoHome = true;               // Enable automatic homing if not already done
bool GotoZero = false;            // Goto workspace X/Y/Z zero (for confirmation) at end of operation (CAUTION!)
string MacroID = "M20002";      // Macro ID (For use in title of Message Boxes)
double SafeZ = 0.00;               // Safe Z in Machine Coords

// Machine must be homed for safety
if(!exec.GetLED(56)||!exec.GetLED(57)||!exec.GetLED(58)) {

   if(AutoHome) {
      ShowMessage("Device not HOMED!  Press OK to perform AutoHome.", MacroID + ": AutoHome?");
      PerformAutoHome();

   } else {
      ShowMessage("The machine must be HOMED before this activity!", MacroID + ": Fatal Error!");
      exec.Stop();
      return;
   }
}

// Get current X, Y, Z (machine coords)
double X_MC = exec.GetXmachpos();
double Y_MC = exec.GetYmachpos();
double Z_MC = exec.GetZmachpos();

// Get previously probed data from Profile
double PlateOffset = Convert.ToDouble(exec.Readkey("XYZProbeData", "PlateOffset", "0.0000"));
double WorkXZero = Convert.ToDouble(exec.Readkey("XYZProbeData", "WorkXZero", "0.0000"));
double WorkYZero = Convert.ToDouble(exec.Readkey("XYZProbeData", "WorkYZero", "0.0000"));
double WorkZZero = Convert.ToDouble(exec.Readkey("XYZProbeData", "WorkZZero", "0.0000"));

// Attempt to validate the Profile data (Its extremely unlikely that ANY would be exactly 0.00)
if ((PlateOffset == 0.0) || (WorkXZero == 0.0) || (WorkYZero == 0.0) || (WorkZZero == 0.0)) {

      ShowMessage("It appears that the data stored in the profile is either missing or invalid!", MacroID + ": Fatal Error!");
      exec.Stop();
      return;
}

// Update current work coordinates
SetAllWorkspaceX(X_MC - WorkXZero);
SetAllWorkspaceY(Y_MC - WorkYZero);
SetAllWorkspaceZ(Z_MC - WorkZZero);

// Goto workspace X/Y/Z zero (if configured)
if(GotoZero) SafeMove_WC(SafeZ, 0.00, 0.00, 0.00);


// Display Completion Message
ShowMessage("Done!", MacroID + ": Coordinates Restored");

// ***** Support FUNCTIONS **********************************************************

#Events

void ShowMessage(string Message, string Title="") {
   MessageBox.Show(exec.mainform, Message, Title);
}

void PerformAutoHome(int mswait=1000) {

   exec.Callbutton(113);
   exec.Wait(mswait);
   while(true) {
      if(!exec.GetLED(23)) {
         exec.Wait(mswait);
         if(!exec.GetLED(23)) break;
      }
   }
}

void SafeMove_WC(double SafeZ_MC, double X_WC, double Y_WC, double Z_WC, int msWait=200) {

   // Retract to SafeZ
   ExecAndWait("G53 G0 Z" + SafeZ_MC, msWait);

   // Move to X, Y
   ExecAndWait("G0 X" + X_WC + " Y" + Y_WC, msWait);

   // Move to Z
   ExecAndWait("G0 Z" + Z_WC, msWait);

}

void ExecAndWait(string Command, int msWait=200) {

   exec.Code(Command);
   while(exec.IsMoving()){}
   exec.Wait(msWait);

}

void SetAllWorkspaceX(double value) {
   exec.mainform.sumoffsetcontrol1.G54.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G55.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G56.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G57.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G58.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G59.newCxinput(value);
}

void SetAllWorkspaceY(double value) {
   exec.mainform.sumoffsetcontrol1.G54.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G55.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G56.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G57.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G58.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G59.newCyinput(value);
}

void SetAllWorkspaceZ(double value) {
   exec.mainform.sumoffsetcontrol1.G54.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G55.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G56.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G57.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G58.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G59.newCzinput(value);
}


NEW BIT Recovery Macro:
Code: Select all
// "New Bit" Recovery
// Restores workspace coordinate system from data preserved in profile

// Can be used if the tool bit HAS been changed since the crash, power outage, etc

// Edward C. Van Every, Version 1.03

// Operational Configuration
bool AutoHome = true;               // Enable automatic homing if not already done
bool GotoZero = false;            // Goto workspace X/Y/Z zero (for confirmation) at end of operation (CAUTION!)
string MacroID = "M20003";      // Macro ID (For use in title of Message Boxes)
double SafeZ = 0.00;               // Safe Z in Machine Coords
double FixedPlateX = 364.4;      // Fixed plate X position (machine coordinate)
double FixedPlateY = 20.7;      // Fixed plate Y position (machine coordinate)
double RetractDistance = 1;     // Height above Z0 to which probe will retract
double CoarseRate = 150;          // Feed rate for initial probing
double FineRate = 25;              // Feed rate for fine probing
double ZMaxProbeDist = 70;       // maximum probing distance

// Machine must be homed for safety
if(!exec.GetLED(56)||!exec.GetLED(57)||!exec.GetLED(58)) {

   if(AutoHome) {
      ShowMessage("Device not HOMED!  Press OK to perform AutoHome.", MacroID + ": AutoHome?");
      PerformAutoHome();

   } else {
      ShowMessage("The machine must be HOMED before this activity!", MacroID + ": Fatal Error!");
      exec.Stop();
      return;
   }
}

// Get current X, Y, Z (machine coords)
double X_MC = exec.GetXmachpos();
double Y_MC = exec.GetYmachpos();
double Z_MC = exec.GetZmachpos();

// Get previously probed data from Profile
double PlateOffset = Convert.ToDouble(exec.Readkey("XYZProbeData", "PlateOffset", "0.0000"));
double WorkXZero = Convert.ToDouble(exec.Readkey("XYZProbeData", "WorkXZero", "0.0000"));
double WorkYZero = Convert.ToDouble(exec.Readkey("XYZProbeData", "WorkYZero", "0.0000"));
double WorkZZero = Convert.ToDouble(exec.Readkey("XYZProbeData", "WorkZZero", "0.0000"));

// Attempt to validate the Profile data (Its extremely unlikely that ANY would be exactly 0.00)
if ((PlateOffset == 0.0) || (WorkXZero == 0.0) || (WorkYZero == 0.0) || (WorkZZero == 0.0)) {

      ShowMessage("It appears that the data stored in the profile is either missing or invalid!", MacroID + ": Fatal Error!");
      exec.Stop();
      return;
}


// Update current XY work coordinates
SetAllWorkspaceX(X_MC - WorkXZero);
SetAllWorkspaceY(Y_MC - WorkYZero);

//Move to Fixed Plate Position
SafeMove_MC(SafeZ, FixedPlateX, FixedPlateY, SafeZ);

// Prompt: Attach Probe
ShowMessage("Please Attach FIXED PLATE Probe", MacroID + ": Prepare FIXED Probe");
   
// Probe Z
Probe_RC('Z', '-', ZMaxProbeDist, RetractDistance, CoarseRate, FineRate);

// Update G54-G59 to new Z zero (Tip of the router bit is now at "PlateOffset")
SetAllWorkspaceZ(PlateOffset);

// Update Z Recovery data for this new bit to current profile
exec.Writekey("XYZProbeData", "WorkZZero", Convert.ToString(exec.GetZmachpos() - PlateOffset));

// Prompt: Detach Probe
SafeMove_MC(SafeZ, FixedPlateX, FixedPlateY, SafeZ);
ShowMessage("Please Remove FIXED PLATE Probe", MacroID + ": Remove FIXED Probe");

// Goto workspace X/Y/Z zero (if configured)
if(GotoZero) SafeMove_WC(SafeZ, 0.00, 0.00, 0.00);


// Display Completion Message
ShowMessage("Done!", MacroID + ": Coordinates Restored");

// ***** Support FUNCTIONS **********************************************************

#Events

void ShowMessage(string Message, string Title="") {
   MessageBox.Show(exec.mainform, Message, Title);
}

void PerformAutoHome(int mswait=1000) {

   exec.Callbutton(113);
   exec.Wait(mswait);
   while(true) {
      if(!exec.GetLED(23)) {
         exec.Wait(mswait);
         if(!exec.GetLED(23)) break;
      }
   }
}

void Probe_RC(char Axis, char Direction, double MaxDist, double RetractDist, double CoarseRate, double FineRate, int msWait=200) {

   double FineDist = RetractDist * 2;

   // Set Relative Mode for Probing
   exec.Code("G91");

   // Probe Quickly
   if (Direction == '-') ExecAndWait("G31 " + Axis + '-' + MaxDist + "F" + CoarseRate, msWait);
   else ExecAndWait("G31 " + Axis + MaxDist + "F" + CoarseRate, msWait);

   // Retract (Reverse)
   if (Direction == '-') ExecAndWait("G0 " + Axis + RetractDist, msWait);
   else ExecAndWait("G0 " + Axis + '-' + RetractDist, msWait);

   // Probe Slowly
   if (Direction == '-') ExecAndWait("G31 " + Axis + '-' + FineDist + "F" + FineRate, msWait);
   else ExecAndWait("G31 " + Axis + FineDist + "F" + FineRate, msWait);

   // Reset Absolute Mode
   exec.Code("G90");
}

void SafeMove_MC(double SafeZ_MC, double X_MC, double Y_MC, double Z_MC, int msWait=200) {

   // Retract to SafeZ
   ExecAndWait("G53 G0 Z" + SafeZ_MC, msWait);

   // Move to X, Y
   ExecAndWait("G53 G0 X" + X_MC + " Y" + Y_MC, msWait);

   // Move to Z
   ExecAndWait("G53 G0 Z" + Z_MC, msWait);

}

void SafeMove_WC(double SafeZ_MC, double X_WC, double Y_WC, double Z_WC, int msWait=200) {

   // Retract to SafeZ
   ExecAndWait("G53 G0 Z" + SafeZ_MC, msWait);

   // Move to X, Y
   ExecAndWait("G0 X" + X_WC + " Y" + Y_WC, msWait);

   // Move to Z
   ExecAndWait("G0 Z" + Z_WC, msWait);

}

void ExecAndWait(string Command, int msWait=200) {

   exec.Code(Command);
   while(exec.IsMoving()){}
   exec.Wait(msWait);

}

void SetAllWorkspaceX(double value) {
   exec.mainform.sumoffsetcontrol1.G54.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G55.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G56.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G57.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G58.newCxinput(value);
   exec.mainform.sumoffsetcontrol1.G59.newCxinput(value);
}

void SetAllWorkspaceY(double value) {
   exec.mainform.sumoffsetcontrol1.G54.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G55.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G56.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G57.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G58.newCyinput(value);
   exec.mainform.sumoffsetcontrol1.G59.newCyinput(value);
}

void SetAllWorkspaceZ(double value) {
   exec.mainform.sumoffsetcontrol1.G54.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G55.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G56.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G57.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G58.newCzinput(value);
   exec.mainform.sumoffsetcontrol1.G59.newCzinput(value);
}
evanevery
 
Posts: 20
Joined: Tue Jan 11, 2022 3:57 pm

Re: M6/M31 Macro Pair to emulate Carbide3D Bitzero Probing

Postby Precision Composites » Thu Sep 05, 2024 11:51 pm

Jeezus! Wish I had the coding ability you have. I've only been at this since end of 2022 though.

Here is another thought: Can a pause be put in between probing the XYZ and the fixed plate?

The reason I ask this is because, like most, I set up the WCS on front left for a majority of work. However, I'm going to set up the fixed plate near home which is back left and close to the control cabinet. This requires switching the mag/clip leads between probes.

Also, when it goes to probe the fixed plate, I want to rotate C axis 180 as I'm trying to place the plate as far away from the normal working envelope as possible.

I designed and printed a tower yesterday out of ABS-GF for the fixed plate that the original puck button sets into.

There is the occasion where a workpiece will have a center setup. Think tip of a cone at highest Z with the base of the cone set on a square base. Not sure how to approach this with the same abilities. Normally I would manually dial in the WSC using a pointed bit, change the bit to my roughing bit and re-Z. Before roughing begins, I would take a measurement off the main base or do a Z difference and record that for the next bit change so as not to lose the reference.

I know there are a lot of variables here that I've listed and may not be a one solution fits all. You can always PM me for a time if you want to have a phone discussion.
Attachments
Tower 3D printed3.jpg
Assembled
Tower 3D printed2.jpg
Original Puck
Tower 3D printed1.jpg
Precision Composites
 
Posts: 12
Joined: Mon Mar 06, 2023 9:26 pm

Re: M6/M31 Macro Pair to emulate Carbide3D Bitzero Probing

Postby evanevery » Fri Sep 06, 2024 1:18 am

I'm happy to add any functionality you might need. (I love this kinda stuff. I've been coding since the early 80's - and "C" is my language of choice. So, Yeah - I'm THAT old! ;-)

However, it should already be doing that! The M20031 should pause both immediately before, and immediately after, EACH probe action (mobile and fixed) so the leads can be attached/detached when in the immediate proximity of each plate. The same with M6 wrt the Fixed plate.

I'm thinking you haven't tested the most recent version I posted (1.03)... ;-)

M6 was dragging the probe wire all the way back to the tool change location before prompting for it to be removed. While I have both my plates connected in parallel, and I typically only use a single probe wire (for both), I made that change EXACTLY for the reason you identified. The last version posted now prompts for probe removal while still in the vicinity of the fixed plate. I bet if you download and test it you will find it is already functioning as you want. "Great Minds" and all that... ;-)

Please confirm this is working as desired.

I'm intrigued with your other requirements. (Nice print job!) It shouldn't matter where, or how high, either plate is. I can also conditionally disable the X/Y probing function and just accept whatever X/Y coords are in effect when the probing function is requested if that would work. If I can better understand your requirements, we can pretty much get X/Y from any mechanism we wish. IOW: M6 doesn't care about XY - whatever/however we set XY in M20031 the ongoing auto Z probing can still be utilized/maintained by M6 with the fixed plate. I'll PM you with contact info and we can pick it up offline so as not to deviate too far from this topic here.
evanevery
 
Posts: 20
Joined: Tue Jan 11, 2022 3:57 pm

Re: M6/M31 Macro Pair to emulate Carbide3D Bitzero Probing

Postby evanevery » Sun Sep 08, 2024 10:32 pm

MAJOR UPDATE (v2.00) to the (M31 XYZ Probe and M6 Manual Tool Change) Macro's!

All data is now maintained (automatically saved/updated/restored) by a single GUI embedded in the M31 XYZ Probing Macro. Macros should never need to be edited for configuration. The single GUI in M31 controls the settings for the entire "family" of macros.

All configuration and operational data is now stored in, and shared from, a private section ("[XYZProbeData]") of the active UCCNC profile

Now supports:

- Surface Probing: Simple top down probing for Z only
- Hole Probing: XYZ Corner Probing using a plate-aligned hole
- Edge Probing: XYZ Corner Probing using a square plate

Provides multiple methods (macros) to automatically restore a probed workspace coordinate system following a crash, power outage, etc, including:

- OLD Bit Coordinate Restoration: Motionless coordinate restoration if the Tool Bit has not been disturbed
- NEW Bit Coordinate Restoration: Coordinate restoration if the tool bit has been replaced

Anyway, too much to discuss (replicate) here. PLEASE take a look at the ReadMe file in the attached archive for lots more info.

Comments and Suggestions are appreciated. Please post them in this thread.

(not sure why this entire message appears to be bolded...)
Attachments
M6_M31_Macros_v2_00.zip
M31 and M6 macros and documentation version 2.00
(99.46 KiB) Downloaded 278 times
evanevery
 
Posts: 20
Joined: Tue Jan 11, 2022 3:57 pm

Previous

Return to UCCNC TOOL BOX

Who is online

Users browsing this forum: No registered users and 1 guest