From 145cc61fa6fa65d954457ad945a0173a47385c32 Mon Sep 17 00:00:00 2001 From: flyfisher604 Date: Mon, 1 Feb 2021 23:11:29 -0800 Subject: [PATCH 01/24] Works as single file, before debug --- MPCNC.cps | 1659 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1659 insertions(+) create mode 100644 MPCNC.cps diff --git a/MPCNC.cps b/MPCNC.cps new file mode 100644 index 0000000..6cc00f1 --- /dev/null +++ b/MPCNC.cps @@ -0,0 +1,1659 @@ +/* + +https://github.com/guffy1234/mpcnc_posts_processor + +MPCNC posts processor for milling and laser/plasma cutting. + +*/ + +//--------------------- Refactored Firmware ---------------------- + +description = "MPCNC Milling/Laser - Marlin 2.0, Grbl 1.1, RepRap"; + +var eFirmware = { + MARLIN: 0, + GRBL: 1, + REPRAP: 2, + prop: { + 0: {name: "Marlin 2.0", value: 0, code: "S"}, + 1: {name: "Grbl 1.1", value: 1, code: "M"}, + 2: {name: "RepRap", value: 2, code: "L"} + } + }; + +var firmware = eFirmware.MARLIN; + +machineMode = undefined; //TYPE_MILLING, TYPE_JET + +/* +mergeProperties(properties, properties3dPrinter); +mergeProperties(propertyDefinitions, propertyDefinitions3dPrinter); +*/ + +function flushMotions() { + let fw = properties.jobSelectedFirmware; + + if (fw != eFirmware.GRBL) { + writeBlock(mFormat.format(400)); + } +} + +// Coolant +function CoolantA(on) { + let fw = properties.jobSelectedFirmware; + + // Firmware is Grbl? + if (fw == eFirmware.GRBL) { + writeBlock(mFormat.format(on ? properties.GrblCoolantA : 9)); + } + + // Default + else { + writeBlock(on ? properties.coolantAMarlinOn : properties.coolantAMarlinOff); + } +} + +function CoolantB(on) { + let fw = properties.jobSelectedFirmware; + + // Firmware is Grbl? + if (fw == eFirmware.GRBL) { + writeBlock(mFormat.format(on ? properties.GrblCoolantB : 9)); + } + + // Default + else { + writeBlock(on ? properties.coolantBMarlinOn : roperties.coolantBMarlinOff); + } +} + + +//--------------------- Common ---------------------- + +/* + +https://github.com/flyfisher604/mpcnc_post_processor + +MPCNC posts processor for milling and laser/plasma cutting. + +*/ + +// Internal properties +certificationLevel = 2; +extension = "gcode"; +setCodePage("ascii"); +capabilities = CAPABILITY_MILLING | CAPABILITY_JET; + +// vendor of MPCNC +vendor = "flyfisher604"; +vendorUrl = "https://github.com/flyfisher604/mpcnc_post_processor"; + + +// user-defined properties +properties = { + jobSelectedFirmware : firmware, // Firmware to use in special cases + + jobManualSpindlePowerControl: true, // Spindle motor is controlled by manual switch + + jobUseArcs: true, // Produce G2/G3 for arcs + + jobSetOriginOnStart: true, // Set origin when gcode start (G92) + jobGoOriginOnFinish: true, // Go X0 Y0 Z0 at gcode end + + jobSequenceNumbers: false, // show sequence numbers + jobSequenceNumberStart: 10, // first sequence number + jobSequenceNumberIncrement: 1, // increment for sequence numbers + jobSeparateWordsWithSpace: true, // specifies that the words should be separated with a white space + + fr0_TravelSpeedXY: 2500, // High speed for travel movements X & Y (mm/min) + fr1_TravelSpeedZ: 300, // High speed for travel movements Z (mm/min) + frA_ScaleFeedrate: false, // Will feedrated be scaled + frB_MaxCutSpeedXY: 900, // Max speed for cut movements X & Y (mm/min) + frC_MaxCutSpeedZ: 180, // Max speed for cut movements Z (mm/min) + frD_MaxCutSpeedXYZ: 1000, // Max feedrate after scaling + + mapD_RestoreFirstRapids: false, // Map first G01 --> G00 + mapE_RestoreRapids: false, // Map G01 --> G00 for SafeTravelsAboveZ + mapF_SafeZ: 10, // G01 mapped to G00 if Z is >= jobSafeZRapid + mapG_AllowRapidZ: true, // Allow G01 --> G00 for vertical retracts and Z descents above safe + + toolChangeEnabled: true, // Enable tool change code (bultin tool change requires LCD display) + toolChangeX: 0, // X position for builtin tool change + toolChangeY: 0, // Y position for builtin tool change + toolChangeZ: 40, // Z position for builtin tool change + toolChangeZProbe: true, // Z probe after tool change + toolChangeDisableZStepper: false, // disable Z stepper when change a tool + + probeOnStart: true, // Execute probe gcode to align tool + probeThickness: 0.8, // plate thickness + probeUseHomeZ: true, // use G28 or G38 for probing + probeG38Target: -10, // probing up to pos + probeG38Speed: 30, // probing with speed + + gcodeStartFile: "", // File with custom Gcode for header/start (in nc folder) + gcodeStopFile: "", // File with custom Gcode for footer/end (in nc folder) + gcodeToolFile: "", // File with custom Gcode for tool change (in nc folder) + gcodeProbeFile: "", // File with custom Gcode for tool probe (in nc folder) + + cutterOnVaporize: 100, // Persent of power to turn on the laser/plasma cutter in vaporize mode + cutterOnThrough: 80, // Persent of power to turn on the laser/plasma cutter in through mode + cutterOnEtch: 40, // Persent of power to turn on the laser/plasma cutter in etch mode + + coolantA_Mode: 0, // Enable issuing g-codes for control Coolant channel A + coolantB_Mode: 0, // Use issuing g-codes for control Coolant channel B + + commentWriteTools: true, + commentActivities: true, + commentSections: true, + commentCommands: true, + commentMovements: true, + + DuetMillingMode: "M453 P2 I0 R30000 F200", // GCode command to setup Duet3d milling mode + DuetLaserMode: "M452 P2 I0 R255 F200", // GCode command to setup Duet3d laser mode + + GrblCutterMode: 4, // GRBL mode laser/plasma cutter + GrblCoolantA: 7, // GCode command to turn on Coolant channel A + GrblCoolantB: 8, // GCode command to turn on Coolant channel A +}; + +propertyDefinitions = { + + jobSelectedFirmware: { + title: "Job: Select CNC Firmware", description: "Control GCode create for specific firmware", group: 1, + type: "integer", default_mm: 0, default_in: 0, + values: [ + { title: eFirmware.prop[eFirmware.MARLIN].name, id: eFirmware.MARLIN }, + { title: eFirmware.prop[eFirmware.GRBL].name, id: eFirmware.GRBL }, + { title: eFirmware.prop[eFirmware.REPRAP].name, id: eFirmware.REPRAP }, + ] + }, + + jobManualSpindlePowerControl: { + title: "Job: Manual Spindle On/Off", description: "Set Yes when your spindle motor is controlled by manual switch", group: 1, + type: "boolean", default_mm: true, default_in: true + }, + jobUseArcs: { + title: "Job: Use Arcs", description: "Use G2/G3 g-codes fo circular movements", group: 1, + type: "boolean", default_mm: true, default_in: true + }, + + jobMarlinEnforcFeFeedrate: { + title: "Job: Marlin Enforce Feedrate", description: "Add feedrate to each movement g-code", group: 1, + type: "boolean", default_mm: false, default_in: false + }, + + jobSetOriginOnStart: { + title: "Job: Reset on start (G92)", description: "Set origin when gcode start (G92)", group: 1, + type: "boolean", default_mm: true, default_in: true + }, + jobGoOriginOnFinish: { + title: "Job: Goto 0, 0 at end", description: "Go X0 Y0 at gcode end", group: 1, + type: "boolean", default_mm: true, default_in: true + }, + + jobSequenceNumbers: { + title: "Job: Line numbers", description: "Show sequence numbers", group: 1, + type: "boolean", default_mm: false, default_in: false + }, + jobSequenceNumberStart: { + title: "Job: Line # start", description: "First sequence number", group: 1, + type: "integer", default_mm: 10, default_in: 10 + }, + jobSequenceNumberIncrement: { + title: "Job: Line # increment", description: "Increment for sequence numbers", group: 1, + type: "integer", default_mm: 1, default_in: 1 + }, + jobSeparateWordsWithSpace: { + title: "Job: Separate words", description: "Specifies that the words should be separated with a white space", group: 1, + type: "boolean", default_mm: true, default_in: true + }, + + + fr0_TravelSpeedXY: { + title: "Feed: Travel speed X/Y", description: "High speed for Rapid movements X & Y (mm/min; in/min)", group: 2, + type: "spatial", default_mm: 2500, default_in: 100 + }, + fr1_TravelSpeedZ: { + title: "Feed: Travel Speed Z", description: "High speed for Rapid movements z (mm/min; in/min)", group: 2, + type: "spatial", default_mm: 300, default_in: 12 + }, + frA_ScaleFeedrate: { + title: "Feed: Scale feedrate", description: "Scale feedrate based on X, Y, Z axis maximums", group: 2, + type: "boolean", default_mm: false, default_in: false + }, + frB_MaxCutSpeedXY: { + title: "Feed: Max cut speed X or Y", description: "Max X or Y axis cut speed (mm/min; in/min)", group: 2, + type: "spatial", default_mm: 900, default_in: 35.43 + }, + frC_MaxCutSpeedZ: { + title: "Feed: Max cut speed Z", description: "Max Z axis cut speed (mm/min; in/min)", group: 2, + type: "spatial", default_mm: 180, default_in: 7.08 + }, + frD_MaxCutSpeedXYZ: { + title: "Feed: Max toolpath speed", description: "After scaling limit feedrate to this (mm/min; in/min)", group: 2, + type: "spatial", default_mm: 1000, default_in: 39.37 + }, + + + mapD_RestoreFirstRapids: { + title: "Map: First G1 -> G0 Rapids", description: "Convert first G1 of a cut to G0 Rapids", group: 3, + type: "boolean", default_mm: false, default_in: false + }, + mapE_RestoreRapids: { + title: "Map: G1 -> G0 Rapids", description: "When safe, convert G1s to G0 Rapids", group: 3, + type: "boolean", default_mm: false, default_in: false + }, + mapF_SafeZ: { + title: "Map: Safe Z for Rapids", description: "Z must be above or equal to this to map G01 --> G00", group: 3, + type: "integer", default_mm: 10, default_in: 0.590551 + }, + mapG_AllowRapidZ: { + title: "Map: Allow Rapid Z", description: "If G01 to Rapids allowed, then include vertical retracts and safe descents", group: 3, + type: "boolean", default_mm: true, default_in: true + }, + + + toolChangeEnabled: { + title: "Change: Enabled", description: "Enable tool change code (bultin tool change requires LCD display)", group: 4, + type: "boolean", default_mm: true, default_in: true + }, + toolChangeX: { + title: "Change: X", description: "X position for builtin tool change", group: 4, + type: "spatial", default_mm: 0, default_in: 0 + }, + toolChangeY: { + title: "Change: Y", description: "Y position for builtin tool change", group: 4, + type: "spatial", default_mm: 0, default_in: 0 + }, + toolChangeZ: { + title: "Change: Z ", description: "Z position for builtin tool change", group: 4, + type: "spatial", default_mm: 40, default_in: 1.6 + }, + toolChangeZProbe: { + title: "Change: Make Z Probe", description: "Z probe after tool change", group: 4, + type: "boolean", default_mm: true, default_in: true + }, + toolChangeDisableZStepper: { + title: "Change: Disable Z stepper", description: "Disable Z stepper when change a tool", group: 4, + type: "boolean", default_mm: false, default_in: false + }, + + probeOnStart: { + title: "Probe: On job start", description: "Execute probe gcode on job start", group: 5, + type: "boolean", default_mm: true, default_in: true + }, + probeThickness: { + title: "Probe: Plate thickness", description: "Plate thickness", group: 5, + type: "spatial", default_mm: 0.8, default_in: 0.032 + }, + probeUseHomeZ: { + title: "Probe: Use Home Z", description: "Use G28 or G38 for probing", group: 5, + type: "boolean", default_mm: true, default_in: true + }, + probeG38Target: { + title: "Probe: G38 target", description: "Probing up to Z position", group: 5, + type: "spatial", default_mm: -10, default_in: -0.5 + }, + probeG38Speed: { + title: "Probe: G38 speed", description: "Probing with speed (mm/min; in/min)", group: 5, + type: "spatial", default_mm: 30, default_in: 1.2 + }, + + cutterOnVaporize: { + title: "Laser: On - Vaporize", description: "Persent of power to turn on the laser/plasma cutter in vaporize mode", group: 6, + type: "number", default_mm: 100, default_in: 100 + }, + cutterOnThrough: { + title: "Laser: On - Through", description: "Persent of power to turn on the laser/plasma cutter in through mode", group: 6, + type: "number", default_mm: 80, default_in: 80 + }, + cutterOnEtch: { + title: "Laser: On - Etch", description: "Persent of power to on the laser/plasma cutter in etch mode", group: 6, + type: "number", default_mm: 40, default_in: 40 + }, + cutterMarlinMode: { + title: "Laser: Marlin/Reprap mode", description: "Marlin/Reprar mode of the laser/plasma cutter", group: 6, + type: "integer", default_mm: 106, default_in: 106, + values: [ + { title: "M106 S{PWM}/M107", id: 106 }, + { title: "M3 O{PWM}/M5", id: 3 }, + { title: "M42 P{pin} S{PWM}", id: 42 }, + ] + }, + cutterMarlinPin: { + title: "Laser: Marlin M42 pin", description: "Marlin custom pin number for the laser/plasma cutter", group: 6, + type: "integer", default_mm: 4, default_in: 4 + }, + + gcodeStartFile: { + title: "Extern: Start File", description: "File with custom Gcode for header/start (in nc folder)", group: 7, + type: "file", default_mm: "", default_in: "" + }, + gcodeStopFile: { + title: "Extern: Stop File", description: "File with custom Gcode for footer/end (in nc folder)", group: 7, + type: "file", default_mm: "", default_in: "" + }, + gcodeToolFile: { + title: "Extern: Tool File", description: "File with custom Gcode for tool change (in nc folder)", group: 7, + type: "file", default_mm: "", default_in: "" + }, + gcodeProbeFile: { + title: "Extern: Probe File", description: "File with custom Gcode for tool probe (in nc folder)", group: 7, + type: "file", default_mm: "", default_in: "" + }, + + + commentWriteTools: { + title: "Comment: Write Tools", description: "Write table of used tools in job header", group: 9, + type: "boolean", default_mm: true, default_in: true + }, + commentActivities: { + title: "Comment: Activities", description: "Write comments which somehow helps to understand current piece of g-code", group: 9, + type: "boolean", default_mm: true, default_in: true + }, + commentSections: { + title: "Comment: Sections", description: "Write header of every section", group: 9, + type: "boolean", default_mm: true, default_in: true + }, + commentCommands: { + title: "Comment: Trace Commands", description: "Write stringified commands called by CAM", group: 9, + type: "boolean", default_mm: true, default_in: true + }, + commentMovements: { + title: "Comment: Trace Movements", description: "Write stringified movements called by CAM", group: 9, + type: "boolean", default_mm: true, default_in: true + }, + + DuetMillingMode: { + title: "Duet: Milling mode", description: "GCode command to setup Duet3d milling mode", group: 10, + type: "string", default_mm: "M453 P2 I0 R30000 F200", default_in: "M453 P2 I0 R30000 F200" + }, + DuetLaserMode: { + title: "Duet: Laser mode", description: "GCode command to setup Duet3d laser mode", group: 10, + type: "string", default_mm: "M452 P2 I0 R255 F200", default_in: "M452 P2 I0 R255 F200" + }, + + + GrblCutterMode: { + title: "GRBL: Laser mode", description: "GRBL mode of the laser/plasma cutter", group: 11, + type: "integer", default_mm: 4, default_in: 4, + values: [ + { title: "M4 S{PWM}/M5 dynamic power", id: 4 }, + { title: "M3 S{PWM}/M5 static power", id: 3 }, + ] + }, + + // Coolant + + coolantA_Mode: { + title: "Coolant: A Mode", description: "Enable issuing g-codes for control Coolant channel A", group: 8, + type: "integer", default_mm: 0, default_in: 0, + values: [ + { title: "off", id: 0 }, + { title: "flood", id: 1 }, + { title: "mist", id: 2 }, + { title: "throughTool", id: 3 }, + { title: "air", id: 4 }, + { title: "airThroughTool", id: 5 }, + { title: "suction", id: 6 }, + { title: "floodMist", id: 7 }, + { title: "floodThroughTool", id: 8 } + ] + }, + coolantAMarlinOn: { + title: "Coolant: A On command", description: "GCode command to turn on Coolant channel A", group: 8, + type: "string", default_mm: "M42 P11 S255" + }, + coolantAMarlinOff: { + title: "Coolant: A Off command", description: "Gcode command to turn off Coolant A", group: 8, + type: "string", default_mm: "M42 P11 S0", default_in: "M42 P11 S0" + }, + + coolantB_Mode: { + title: "Coolant: B Mode", description: "Enable issuing g-codes for control Coolant channel B", group: 8, type: "integer", + default_mm: 0, default_in: 0, + values: [ + { title: "off", id: 0 }, + { title: "flood", id: 1 }, + { title: "mist", id: 2 }, + { title: "throughTool", id: 3 }, + { title: "air", id: 4 }, + { title: "airThroughTool", id: 5 }, + { title: "suction", id: 6 }, + { title: "floodMist", id: 7 }, + { title: "floodThroughTool", id: 8 } + ] + }, + coolantBMarlinOn: { + title: "Coolant: B On command", description: "GCode command to turn on Coolant channel B", group: 8, + type: "string", default_mm: "M42 P6 S255", default_in: "M42 P6 S255" + }, + coolantBMarlinOff: { + title: "Coolant: B Off command", description: "Gcode command to turn off Coolant channel B", group: 8, + type: "string", default_mm: "M42 P6 S0", default_in: "M42 P6 S0" + }, + + GrblCoolantA: { + title: "Grbl: Coolant A code", description: "GRBL g-codes for control Coolant channel A", group: 11, + type: "integer", default_mm: 7, default_in: 7, + values: [ + { title: "M7 flood", id: 7 }, + { title: "M8 mist", id: 8 }, + ] + }, + GrblCoolantB: { + title: "Grbl: Coolant B code", description: "GRBL g-codes for control Coolant channel B", group: 11, + type: "integer", default_mm: 8, default_in: 8, + values: [ + { title: "M7 flood", id: 7 }, + { title: "M8 mist", id: 8 }, + ] + }, +}; + +/* + +https://github.com/guffy1234/mpcnc_posts_processor + +MPCNC posts processor for milling and laser/plasma cutting. + +*/ + +var sequenceNumber; + +// Formats +var gFormat = createFormat({ prefix: "G", decimals: 1 }); +var mFormat = createFormat({ prefix: "M", decimals: 0 }); + +var xyzFormat = createFormat({ decimals: (unit == MM ? 3 : 4) }); +var xFormat = createFormat({ prefix: "X", decimals: (unit == MM ? 3 : 4) }); +var yFormat = createFormat({ prefix: "Y", decimals: (unit == MM ? 3 : 4) }); +var zFormat = createFormat({ prefix: "Z", decimals: (unit == MM ? 3 : 4) }); +var iFormat = createFormat({ prefix: "I", decimals: (unit == MM ? 3 : 4) }); +var jFormat = createFormat({ prefix: "J", decimals: (unit == MM ? 3 : 4) }); +var kFormat = createFormat({ prefix: "K", decimals: (unit == MM ? 3 : 4) }); + +var speedFormat = createFormat({ decimals: 0 }); +var sFormat = createFormat({ prefix: "S", decimals: 0 }); + +var pFormat = createFormat({ prefix: "P", decimals: 0 }); +var oFormat = createFormat({ prefix: "O", decimals: 0 }); + +var feedFormat = createFormat({ decimals: (unit == MM ? 0 : 2) }); +var fFormat = createFormat({ prefix: "F", decimals: (unit == MM ? 0 : 2) }); + +var toolFormat = createFormat({ decimals: 0 }); +var tFormat = createFormat({ prefix: "T", decimals: 0 }); + +var taperFormat = createFormat({ decimals: 1, scale: DEG }); +var secFormat = createFormat({ decimals: 3, forceDecimal: true }); // seconds - range 0.001-1000 + +// Linear outputs +var xOutput = createVariable({}, xFormat); +var yOutput = createVariable({}, yFormat); +var zOutput = createVariable({}, zFormat); +var fOutput = createVariable({ force: false }, fFormat); +var sOutput = createVariable({ force: true }, sFormat); + +// Circular outputs +var iOutput = createReferenceVariable({}, iFormat); +var jOutput = createReferenceVariable({}, jFormat); +var kOutput = createReferenceVariable({}, kFormat); + +// Modals +var gMotionModal = createModal({}, gFormat); // modal group 1 // G0-G3, ... +var gPlaneModal = createModal({ onchange: function () { gMotionModal.reset(); } }, gFormat); // modal group 2 // G17-19 +var gAbsIncModal = createModal({}, gFormat); // modal group 3 // G90-91 +var gFeedModeModal = createModal({}, gFormat); // modal group 5 // G93-94 +var gUnitModal = createModal({}, gFormat); // modal group 6 // G20-21 + +// Arc support variables +minimumChordLength = spatial(0.01, MM); +minimumCircularRadius = spatial(0.01, MM); +maximumCircularRadius = spatial(1000, MM); +minimumCircularSweep = toRad(0.01); +maximumCircularSweep = toRad(180); +allowHelicalMoves = false; +allowedCircularPlanes = undefined; + +// Writes the specified block. +function writeBlock() { + if (properties.jobSequenceNumbers) { + writeWords2("N" + sequenceNumber, arguments); + sequenceNumber += properties.jobSequenceNumberIncrement; + } else { + writeWords(arguments); + } +} + +var currentFirmware; + +// Called in every new gcode file +function onOpen() { + let fw = properties.jobSelectedFirmware; + + if (fw == eFirmware.GRBL) { + gMotionModal = createModal({}, gFormat); // modal group 1 // G0-G3, ... + writeln("%"); + } + else { + gMotionModal = createModal({ force: true }, gFormat); // modal group 1 // G0-G3, ... + + if (properties.jobMarlinEnforceFeedrate) { + fOutput = createVariable({ force: true }, fFormat); + } + } + + sequenceNumber = properties.jobSequenceNumberStart; + if (!properties.jobSeparateWordsWithSpace) { + setWordSeparator(""); + } +} + +// Called at end of gcode file +function onClose() { + let fw = properties.jobSelectedFirmware; + + writeActivityComment(" *** STOP begin ***"); + + flushMotions(); + + if (properties.gcodeStopFile == "") { + onCommand(COMMAND_COOLANT_OFF); + if (properties.jobGoOriginOnFinish) { + rapidMovementsXY(0, 0); + } + onCommand(COMMAND_STOP_SPINDLE); + + end(true); + + writeActivityComment(" *** STOP end ***"); + } else { + loadFile(properties.gcodeStopFile); + } + + if (fw == eFirmware.GRBL) { + writeln("%"); + } + else { + } +} + +var cutterOnCurrentPower; +var forceSectionToStartWithRapid = false; + +function onSection() { + let fw = properties.jobSelectedFirmware; + + // Every section needs to start with a Rapid to get to the initial location. + // In the hobby version Rapids have been elliminated and the first command is + // a onLinear not a onRapid command. This results in not current position being + // that same as the cut to position which means wecan't determine the direction + // of the move. Without a direction vector we can't scale the feedrate or convert + // onLinear moves back into onRapids. By ensuring the first onLinear is treated as + // a onRapid we have a currentPosition that is correct. + + forceSectionToStartWithRapid = true; + + // Write Start gcode of the documment (after the "onParameters" with the global info) + if (isFirstSection()) { + writeFirstSection(); + } + + writeActivityComment(" *** SECTION begin ***"); + + // Tool change + if (properties.toolChangeEnabled && !isFirstSection() && tool.number != getPreviousSection().getTool().number) { + if (properties.gcodeToolFile == "") { + // Builtin tool change gcode + writeActivityComment(" --- CHANGE TOOL begin ---"); + + toolChange(); + + writeActivityComment(" --- CHANGE TOOL end ---"); + } else { + // Custom tool change gcode + loadFile(properties.gcodeToolFile); + } + } + + if (properties.commentSections) { + // Machining type + if (currentSection.type == TYPE_MILLING) { + // Specific milling code + writeComment(" " + sectionComment + " - Milling - Tool: " + tool.number + " - " + tool.comment + " " + getToolTypeName(tool.type)); + } + + if (currentSection.type == TYPE_JET) { + // Cutter mode used for different cutting power in PWM laser + switch (currentSection.jetMode) { + case JET_MODE_THROUGH: + cutterOnCurrentPower = properties.cutterOnThrough; + break; + case JET_MODE_ETCHING: + cutterOnCurrentPower = properties.cutterOnEtch; + break; + case JET_MODE_VAPORIZE: + cutterOnCurrentPower = properties.cutterOnVaporize; + break; + default: + error("Cutting mode is not supported."); + } + writeComment(" " + sectionComment + " - Laser/Plasma - Cutting mode: " + getParameter("operation:cuttingMode")); + } + + // Print min/max boundaries for each section + vectorX = new Vector(1, 0, 0); + vectorY = new Vector(0, 1, 0); + writeComment(" X Min: " + xyzFormat.format(currentSection.getGlobalRange(vectorX).getMinimum()) + " - X Max: " + xyzFormat.format(currentSection.getGlobalRange(vectorX).getMaximum())); + writeComment(" Y Min: " + xyzFormat.format(currentSection.getGlobalRange(vectorY).getMinimum()) + " - Y Max: " + xyzFormat.format(currentSection.getGlobalRange(vectorY).getMaximum())); + writeComment(" Z Min: " + xyzFormat.format(currentSection.getGlobalZRange().getMinimum()) + " - Z Max: " + xyzFormat.format(currentSection.getGlobalZRange().getMaximum())); + } + + // Adjust the mode + if (fw == eFirmware.REPRAP) { + if (machineMode != currentSection.type) { + switch (currentSection.type) { + case TYPE_MILLING: + writeBlock(properties.DuetMillingMode); + break; + case TYPE_JET: + writeBlock(properties.DuetLaserMode); + break; + } + } + } + + machineMode = currentSection.type; + + onCommand(COMMAND_START_SPINDLE); + onCommand(COMMAND_COOLANT_ON); + + // Display section name in LCD + display_text(" " + sectionComment); +} + +function resetAll() { + xOutput.reset(); + yOutput.reset(); + zOutput.reset(); + fOutput.reset(); +} + +// Called in every section end +function onSectionEnd() { + resetAll(); + writeActivityComment(" *** SECTION end ***"); + writeln(""); +} + +function onComment(message) { + writeComment(message); +} + +var pendingRadiusCompensation = RADIUS_COMPENSATION_OFF; + +function onRadiusCompensation() { + pendingRadiusCompensation = radiusCompensation; +} + +// Rapid movements +function onRapid(x, y, z) { + forceSectionToStartWithRapid = false; + + rapidMovements(x, y, z); +} + +function safeToRapid(x, y, z) { + if (properties.mapE_RestoreRapids) { + let zSafe = (z >= properties.mapF_SafeZ); + + // Destination z must be in safe zone. + if (zSafe) { + let cur = getCurrentPosition(); + let zConstant = (z == cur.z); + let zUp = (z > cur.z); + let xyConstant = ((x == cur.x) && (y == cur.y)); + let curZSafe = (cur.z >= properties.mapF_SafeZ); + + // Restore Rapids only when the target Z is safe and + // Case 1: Z is not changing, but XY are + // Case 2: Z is increasing, but XY constant + + // Z is not changing and we know we are in the safe zone + if (zConstant) { + return true; + } + + // We include moves of Z up as long as xy are constant + else if (properties.mapG_AllowRapidZ && zUp && xyConstant) { + return true; + } + + // We include moves of Z down as long as xy are constant and z always remains safe + else if (properties.mapG_AllowRapidZ && (!zUp) && xyConstant && curZSafe) { + return true; + } + } + } + + return false; +} + +// Feed movements +function onLinear(x, y, z, feed) { + // If we are allowing Rapids to be recovered from Linear (cut) moves, which is + // only required when F360 Personal edition is used, then if this Linear (cut) + // move is the first operationin a Section (milling operation) then convert it + // to a Rapid. This is OK because Sections normally begin with a Rapid to move + // to the first cutting location but these Rapids were changed to Linears by + // the personal edition. If this Rapid is not recovered and feedrate scaling + // is enabled then the first move to the start of a section will be at the + // slowest cutting feedrate, generally Z's feedrate. + + if (properties.mapD_RestoreFirstRapids && (forceSectionToStartWithRapid == true)) { + writeComment(" First G1 --> G0"); + + forceSectionToStartWithRapid = false; + onRapid(x, y, z); + } + else if (safeToRapid(x, y, z)) { + writeComment(" Safe G1 --> G0"); + + onRapid(x, y, z); + } + else { + linearMovements(x, y, z, feed, true); + } +} + +function onRapid5D(_x, _y, _z, _a, _b, _c) { + forceSectionToStartWithRapid = false; + + error(localize("Multi-axis motion is not supported.")); +} + +function onLinear5D(_x, _y, _z, _a, _b, _c, feed) { + forceSectionToStartWithRapid = false; + + error(localize("Multi-axis motion is not supported.")); +} + +function onCircular(clockwise, cx, cy, cz, x, y, z, feed) { + forceSectionToStartWithRapid = false; + + if (pendingRadiusCompensation != RADIUS_COMPENSATION_OFF) { + error(localize("Radius compensation cannot be activated/deactivated for a circular move.")); + return; + } + circular(clockwise, cx, cy, cz, x, y, z, feed) +} + +// Called on waterjet/plasma/laser cuts +var powerState = false; + +function onPower(power) { + if (power != powerState) { + if (power) { + writeActivityComment(" >>> LASER Power ON"); + + laserOn(cutterOnCurrentPower); + } else { + writeActivityComment(" >>> LASER Power OFF"); + + laserOff(); + } + powerState = power; + } +} + +// Called on Dwell Manual NC invocation +function onDwell(seconds) { + let fw = properties.jobSelectedFirmware; + + writeActivityComment(" >>> Dwell"); + if (seconds > 99999.999) { + warning(localize("Dwelling time is out of range.")); + } + + seconds = clamp(0.001, seconds, 99999.999); + + // Firmware is Grbl + if (fw == eFirmware.GRBL) { + writeBlock(gFormat.format(4), "P" + secFormat.format(seconds)); + } + + // Default + else { + writeBlock(gFormat.format(4), "S" + secFormat.format(seconds)); + } +} + +// Called with every parameter in the documment/section +function onParameter(name, value) { + + // Write gcode initial info + // Product version + if (name == "generated-by") { + writeComment(value); + writeComment(" Posts processor: " + FileSystem.getFilename(getConfigurationPath())); + } + // Date + if (name == "generated-at") writeComment(" Gcode generated: " + value + " GMT"); + // Document + if (name == "document-path") writeComment(" Document: " + value); + // Setup + if (name == "job-description") writeComment(" Setup: " + value); + + // Get section comment + if (name == "operation-comment") sectionComment = value; +} + +function onMovement(movement) { + if (properties.commentMovements) { + var jet = tool.isJetTool && tool.isJetTool(); + var id; + switch (movement) { + case MOVEMENT_RAPID: + id = "MOVEMENT_RAPID"; + break; + case MOVEMENT_LEAD_IN: + id = "MOVEMENT_LEAD_IN"; + break; + case MOVEMENT_CUTTING: + id = "MOVEMENT_CUTTING"; + break; + case MOVEMENT_LEAD_OUT: + id = "MOVEMENT_LEAD_OUT"; + break; + case MOVEMENT_LINK_TRANSITION: + id = jet ? "MOVEMENT_BRIDGING" : "MOVEMENT_LINK_TRANSITION"; + break; + case MOVEMENT_LINK_DIRECT: + id = "MOVEMENT_LINK_DIRECT"; + break; + case MOVEMENT_RAMP_HELIX: + id = jet ? "MOVEMENT_PIERCE_CIRCULAR" : "MOVEMENT_RAMP_HELIX"; + break; + case MOVEMENT_RAMP_PROFILE: + id = jet ? "MOVEMENT_PIERCE_PROFILE" : "MOVEMENT_RAMP_PROFILE"; + break; + case MOVEMENT_RAMP_ZIG_ZAG: + id = jet ? "MOVEMENT_PIERCE_LINEAR" : "MOVEMENT_RAMP_ZIG_ZAG"; + break; + case MOVEMENT_RAMP: + id = "MOVEMENT_RAMP"; + break; + case MOVEMENT_PLUNGE: + id = jet ? "MOVEMENT_PIERCE" : "MOVEMENT_PLUNGE"; + break; + case MOVEMENT_PREDRILL: + id = "MOVEMENT_PREDRILL"; + break; + case MOVEMENT_EXTENDED: + id = "MOVEMENT_EXTENDED"; + break; + case MOVEMENT_REDUCED: + id = "MOVEMENT_REDUCED"; + break; + case MOVEMENT_HIGH_FEED: + id = "MOVEMENT_HIGH_FEED"; + break; + case MOVEMENT_FINISH_CUTTING: + id = "MOVEMENT_FINISH_CUTTING"; + break; + } + if (id == undefined) { + id = String(movement); + } + writeComment(" " + id); + } +} + +var currentSpindleSpeed = 0; + +function setSpindeSpeed(_spindleSpeed, _clockwise) { + if (currentSpindleSpeed != _spindleSpeed) { + if (_spindleSpeed > 0) { + spindleOn(_spindleSpeed, _clockwise); + } else { + spindleOff(); + } + currentSpindleSpeed = _spindleSpeed; + } +} + +function onSpindleSpeed(spindleSpeed) { + setSpindeSpeed(spindleSpeed, tool.clockwise); +} + +function onCommand(command) { + if (properties.commentActivities) { + var stringId = getCommandStringId(command); + writeComment(" " + stringId); + } + switch (command) { + case COMMAND_START_SPINDLE: + onCommand(tool.clockwise ? COMMAND_SPINDLE_CLOCKWISE : COMMAND_SPINDLE_COUNTERCLOCKWISE); + return; + case COMMAND_SPINDLE_CLOCKWISE: + if (tool.jetTool) + return; + setSpindeSpeed(spindleSpeed, true); + return; + case COMMAND_SPINDLE_COUNTERCLOCKWISE: + if (tool.jetTool) + return; + setSpindeSpeed(spindleSpeed, false); + return; + case COMMAND_STOP_SPINDLE: + if (tool.jetTool) + return; + setSpindeSpeed(0, true); + return; + case COMMAND_COOLANT_ON: + setCoolant(tool.coolant); + return; + case COMMAND_COOLANT_OFF: + setCoolant(0); //COOLANT_DISABLED + return; + case COMMAND_LOCK_MULTI_AXIS: + return; + case COMMAND_UNLOCK_MULTI_AXIS: + return; + case COMMAND_BREAK_CONTROL: + return; + case COMMAND_TOOL_MEASURE: + if (tool.jetTool) + return; + probeTool(); + return; + case COMMAND_STOP: + writeBlock(mFormat.format(0)); + return; + } +} + +function writeFirstSection() { + // dump tool information + var toolZRanges = {}; + var vectorX = new Vector(1, 0, 0); + var vectorY = new Vector(0, 1, 0); + var ranges = { + x: { min: undefined, max: undefined }, + y: { min: undefined, max: undefined }, + z: { min: undefined, max: undefined }, + }; + var handleMinMax = function (pair, range) { + var rmin = range.getMinimum(); + var rmax = range.getMaximum(); + if (pair.min == undefined || pair.min > rmin) { + pair.min = rmin; + } + if (pair.max == undefined || pair.max < rmin) { // was pair.min - changed by DG 1/4/2021 + pair.max = rmax; + } + } + + var numberOfSections = getNumberOfSections(); + for (var i = 0; i < numberOfSections; ++i) { + var section = getSection(i); + var tool = section.getTool(); + var zRange = section.getGlobalZRange(); + var xRange = section.getGlobalRange(vectorX); + var yRange = section.getGlobalRange(vectorY); + handleMinMax(ranges.x, xRange); + handleMinMax(ranges.y, yRange); + handleMinMax(ranges.z, zRange); + if (is3D() && properties.commentWriteTools) { + if (toolZRanges[tool.number]) { + toolZRanges[tool.number].expandToRange(zRange); + } else { + toolZRanges[tool.number] = zRange; + } + } + } + + writeComment(" "); + writeComment(" Ranges table:"); + writeComment(" X: Min=" + xyzFormat.format(ranges.x.min) + " Max=" + xyzFormat.format(ranges.x.max) + " Size=" + xyzFormat.format(ranges.x.max - ranges.x.min)); + writeComment(" Y: Min=" + xyzFormat.format(ranges.y.min) + " Max=" + xyzFormat.format(ranges.y.max) + " Size=" + xyzFormat.format(ranges.y.max - ranges.y.min)); + writeComment(" Z: Min=" + xyzFormat.format(ranges.z.min) + " Max=" + xyzFormat.format(ranges.z.max) + " Size=" + xyzFormat.format(ranges.z.max - ranges.z.min)); + + if (properties.commentWriteTools) { + writeComment(" "); + writeComment(" Tools table:"); + var tools = getToolTable(); + if (tools.getNumberOfTools() > 0) { + for (var i = 0; i < tools.getNumberOfTools(); ++i) { + var tool = tools.getTool(i); + var comment = " T" + toolFormat.format(tool.number) + " D=" + xyzFormat.format(tool.diameter) + " CR=" + xyzFormat.format(tool.cornerRadius); + if ((tool.taperAngle > 0) && (tool.taperAngle < Math.PI)) { + comment += " TAPER=" + taperFormat.format(tool.taperAngle) + "deg"; + } + if (toolZRanges[tool.number]) { + comment += " - ZMIN=" + xyzFormat.format(toolZRanges[tool.number].getMinimum()); + } + comment += " - " + getToolTypeName(tool.type) + " " + tool.comment; + writeComment(comment); + } + } + } + writeln(""); + + writeActivityComment(" *** START begin ***"); + + if (properties.gcodeStartFile == "") { + Start(); + } else { + loadFile(properties.gcodeStartFile); + } + writeActivityComment(" *** START end ***"); + writeln(""); +} + +// Output a comment +function writeComment(text) { + let fw = properties.jobSelectedFirmware; + + if (fw == eFirmware.GRBL) { + writeln("(" + String(text).replace(/[\(\)]/g, "") + ")"); + } + else { + writeln(";" + String(text).replace(/[\(\)]/g, "")); + } +} + +// Rapid movements with G1 and differentiated travel speeds for XY +// Changes F360 current XY. +// No longer called for general Rapid only for probing, homing, etc. +function rapidMovementsXY(_x, _y) { + let x = xOutput.format(_x); + let y = yOutput.format(_y); + + if (x || y) { + if (pendingRadiusCompensation != RADIUS_COMPENSATION_OFF) { + error(localize("Radius compensation mode cannot be changed at rapid traversal.")); + } + else { + let f = fOutput.format(propertyMmToUnit(properties.fr0_TravelSpeedXY)); + writeBlock(gMotionModal.format(0), x, y, f); + } + } +} + +// Rapid movements with G1 and differentiated travel speeds for Z +// Changes F360 current Z +// No longer called for general Rapid only for probing, homing, etc. +function rapidMovementsZ(_z) { + let z = zOutput.format(_z); + + if (z) { + if (pendingRadiusCompensation != RADIUS_COMPENSATION_OFF) { + error(localize("Radius compensation mode cannot be changed at rapid traversal.")); + } + else { + let f = fOutput.format(propertyMmToUnit(properties.fr1_TravelSpeedZ)); + writeBlock(gMotionModal.format(0), z, f); + } + } +} + +// Rapid movements with G1 uses the max travel rate (xy or z) and then relies on feedrate scaling +function rapidMovements(_x, _y, _z) { + + rapidMovementsZ(_z); + rapidMovementsXY(_x, _y); +} + +// Calculate the feedX, feedY and feedZ components + +function limitFeedByXYZComponents(curPos, destPos, feed) { + if (!properties.frA_ScaleFeedrate) + return feed; + + var xyz = Vector.diff(destPos, curPos); // Translate the cut so curPos is at 0,0,0 + var dir = xyz.getNormalized(); // Normalize vector to get a direction vector + var xyzFeed = Vector.product(dir.abs, feed); // Determine the effective x,y,z speed on each axis + + // Get the max speed for each axis + let xyLimit = propertyMmToUnit(properties.frB_MaxCutSpeedXY); + let zLimit = propertyMmToUnit(properties.frC_MaxCutSpeedZ); + + // Normally F360 begins a Section (a milling operation) with a Rapid to move to the beginning of the cut. + // Rapids use the defined Travel speed and the Post Processor does not depend on the current location. + // This function must know the current location in order to calculate the actual vector traveled. Without + // the first Rapid the current location is the same as the desination location, which creates a 0 length + // vector. A zero length vector is unusable and so a instead the slowest of the xyLimit or zLimit is used. + // + // Note: if Map: G1 -> Rapid is enabled in the Properties then if the first operation in a Section is a + // cut (which it should always be) then it will be converted to a Rapid. This prevents ever getting a zero + // length vector. + if (xyz.length == 0) { + var lesserFeed = (xyLimit < zLimit) ? xyLimit : zLimit; + + return lesserFeed; + } + + // Force the speed of each axis to be within limits + if (xyzFeed.z > zLimit) { + xyzFeed.multiply(zLimit / xyzFeed.z); + } + + if (xyzFeed.x > xyLimit) { + xyzFeed.multiply(xyLimit / xyzFeed.x); + } + + if (xyzFeed.y > xyLimit) { + xyzFeed.multiply(xyLimit / xyzFeed.y); + } + + // Calculate the new feedrate based on the speed allowed on each axis: feedrate = sqrt(x^2 + y^2 + z^2) + // xyzFeed.length is the same as Math.sqrt((xyzFeed.x * xyzFeed.x) + (xyzFeed.y * xyzFeed.y) + (xyzFeed.z * xyzFeed.z)) + + // Limit the new feedrate by the maximum allowable cut speed + + let xyzLimit = propertyMmToUnit(properties.frD_MaxCutSpeedXYZ); + let newFeed = (xyzFeed.length > xyzLimit) ? xyzLimit : xyzFeed.length; + + if (Math.abs(newFeed - feed) > 0.01) { + return newFeed; + } + else { + return feed; + } +} + +// Linear movements +function linearMovements(_x, _y, _z, _feed) { + if (pendingRadiusCompensation != RADIUS_COMPENSATION_OFF) { + // ensure that we end at desired position when compensation is turned off + xOutput.reset(); + yOutput.reset(); + } + + // Force the feedrate to be scaled (if enabled). The feedrate is projected into the + // x, y, and z axis and each axis is tested to see if it exceeds its defined max. If + // it does then the speed in all 3 axis is scaled proportionately. The resulting feedrate + // is then capped at the maximum defined cutrate. + + let feed = limitFeedByXYZComponents(getCurrentPosition(), new Vector(_x, _y, _z), _feed); + + let x = xOutput.format(_x); + let y = yOutput.format(_y); + let z = zOutput.format(_z); + let f = fOutput.format(feed); + + if (x || y || z) { + if (pendingRadiusCompensation != RADIUS_COMPENSATION_OFF) { + error(localize("Radius compensation mode is not supported.")); + } else { + writeBlock(gMotionModal.format(1), x, y, z, f); + } + } else if (f) { + if (getNextRecord().isMotion()) { // try not to output feed without motion + fOutput.reset(); // force feed on next line + } else { + writeBlock(gMotionModal.format(1), f); + } + } +} + +// Test if file exist/can read and load it +function loadFile(_file) { + var folder = FileSystem.getFolderPath(getOutputPath()) + PATH_SEPARATOR; + if (FileSystem.isFile(folder + _file)) { + var txt = loadText(folder + _file, "utf-8"); + if (txt.length > 0) { + writeActivityComment(" --- Start custom gcode " + folder + _file); + write(txt); + writeActivityComment(" --- End custom gcode " + folder + _file); + writeln(""); + } + } else { + writeComment(" Can't open file " + folder + _file); + error("Can't open file " + folder + _file); + } +} + +// Manage coolant state + +var currentCoolantMode = 0; + +function setCoolant(coolant) { + let fw = properties.jobSelectedFirmware; + + if (currentCoolantMode == coolant) { + return; + } + + if (properties.coolantA_Mode != 0) { + if (currentCoolantMode == properties.coolantA_Mode) { + writeActivityComment(" >>> Coolant A OFF"); + + CoolantA(true); + + } else if (coolant == properties.coolantA_Mode) { + writeActivityComment(" >>> Coolant A ON"); + + CoolantA(false); + } + } + + if (properties.coolantB_Mode != 0) { + if (currentCoolantMode == properties.coolantB_Mode) { + writeActivityComment(" >>> Coolant B OFF"); + + CoolantB(true); + + } else if (coolant == properties.coolantB_Mode) { + writeActivityComment(" >>> Coolant B ON"); + + CoolantB(false); + } + } + + currentCoolantMode = coolant; +} + +function propertyMmToUnit(_v) { + return (_v / (unit == IN ? 25.4 : 1)); +} + +function writeActivityComment(_comment) { + if (properties.commentActivities) { + writeComment(_comment); + } +} + +/* +function mergeProperties(to, from) { + for (var attrname in from) { + to[attrname] = from[attrname]; + } +} + +function Firmware3dPrinterLike() { + FirmwareBase.apply(this, arguments); + this.spindleEnabled = false; +} + +Firmware3dPrinterLike.prototype = Object.create(FirmwareBase.prototype); +Firmware3dPrinterLike.prototype.constructor = Firmware3dPrinterLike; +*/ + +function Start() { + let fw = properties.jobSelectedFirmware; + + // Is Grbl? + if (fw == eFirmware.GRBL) { + writeBlock(gAbsIncModal.format(90)); // Set to Absolute Positioning + writeBlock(gFeedModeModal.format(94)); + writeBlock(gPlaneModal.format(17)); + writeBlock(gUnitModal.format(unit == IN ? 20 : 21)); + } + + // Default + else { + writeComment(" Set Absolute Positioning"); + writeComment(" Units = " + (unit == IN ? "inch" : "mm")); + writeComment(" Disable stepper timeout"); + if (properties.jobSetOriginOnStart) { + writeComment(" Set current position = 0,0,0"); + } + + writeBlock(gAbsIncModal.format(90)); // Set to Absolute Positioning + writeBlock(gUnitModal.format(unit == IN ? 20 : 21)); // Set the units + writeBlock(mFormat.format(84), sFormat.format(0)); // Disable steppers timeout + + if (properties.jobSetOriginOnStart) { + writeBlock(gFormat.format(92), xFormat.format(0), yFormat.format(0), zFormat.format(0)); // Set origin to initial position + } + + if (properties.probeOnStart && tool.number != 0 && !tool.jetTool) { + onCommand(COMMAND_TOOL_MEASURE); + } + } +} +function end() { + let fw = properties.jobSelectedFirmware; + + // Is Grbl? + if (fw == eFirmware.GRBL) { + writeBlock(mFormat.format(30)); + } + + // Default + else { + display_text("Job end"); + } +} + + +function spindleOn(_spindleSpeed, _clockwise) { + let fw = properties.jobSelectedFirmware; + + // Is Grbl? + if (fw == eFirmware.GRBL) { + writeActivityComment(" >>> Spindle Speed " + speedFormat.format(_spindleSpeed)); + writeBlock(mFormat.format(_clockwise ? 3 : 4), sOutput.format(spindleSpeed)); + } + + // Default + else { + if (properties.jobManualSpindlePowerControl) { + // for manual any positive input speed assumed as enabled. so it's just a flag + if (!this.spindleEnabled) { + askUser("Turn ON " + speedFormat.format(_spindleSpeed) + "RPM", "Spindle", false); + } + } else { + writeActivityComment(" >>> Spindle Speed " + speedFormat.format(_spindleSpeed)); + writeBlock(mFormat.format(_clockwise ? 3 : 4), sOutput.format(spindleSpeed)); + } + this.spindleEnabled = true; + } +} +function spindleOff() { + let fw = properties.jobSelectedFirmware; + + // Is Grbl? + if (fw == eFirmware.GRBL) { + writeBlock(mFormat.format(5)); + } + + //Default + else { + if (properties.jobManualSpindlePowerControl) { + writeBlock(mFormat.format(300), sFormat.format(300), pFormat.format(3000)); + askUser("Turn OFF spindle", "Spindle", false); + } else { + writeBlock(mFormat.format(5)); + } + this.spindleEnabled = false; + } +} + +function laserOn(power) { + let fw = properties.jobSelectedFirmware; + var laser_pwm = power / 100 * 255; + + // Firmware is Grbl + if (fw == eFirmware.GRBL) { + writeBlock(mFormat.format(properties.GrblCutterMode), sFormat.format(laser_pwm)); + } + + // Default firmware + else { + switch (properties.cutterMarlinMode) { + case 106: + writeBlock(mFormat.format(106), sFormat.format(laser_pwm)); + break; + case 3: + if (fw = eFirmware.REPRAP) { + writeBlock(mFormat.format(3), sFormat.format(laser_pwm)); + } else { + writeBlock(mFormat.format(3), oFormat.format(laser_pwm)); + } + break; + case 42: + writeBlock(mFormat.format(42), pFormat.format(properties.cutterMarlinPin), sFormat.format(laser_pwm)); + break; + } + } +} + +function laserOff() { + let fw = properties.jobSelectedFirmware; + + // Firmware is Grbl + if (fw == eFirmware.GRBL) { + writeBlock(mFormat.format(5)); + } + + // Default + else { + switch (properties.cutterMarlinMode) { + case 106: + writeBlock(mFormat.format(107)); + break; + case 3: + writeBlock(mFormat.format(5)); + break; + case 42: + writeBlock(mFormat.format(42), pFormat.format(properties.cutterMarlinPin), sFormat.format(0)); + break; + } + } +} + +function display_text(txt) { + let fw = properties.jobSelectedFirmware; + + // Firmware is Grbl + if (fw == eFirmware.GRBL) { + // Don't display text + } + + // Default + else { + writeBlock(mFormat.format(117), (properties.jobSeparateWordsWithSpace ? "" : " ") + txt); + } +} + +function circular(clockwise, cx, cy, cz, x, y, z, feed) { + if (!properties.jobUseArcs) { + linearize(tolerance); + return; + } + + var start = getCurrentPosition(); + let fw = properties.jobSelectedFirmware; + + // Firmware is Grbl + if (fw == eFirmware.GRBL) { + if (isFullCircle()) { + if (isHelical()) { + linearize(tolerance); + return; + } + switch (getCircularPlane()) { + case PLANE_XY: + writeBlock(gPlaneModal.format(17), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), iOutput.format(cx - start.x, 0), jOutput.format(cy - start.y, 0), fOutput.format(feed)); + break; + case PLANE_ZX: + writeBlock(gPlaneModal.format(18), gMotionModal.format(clockwise ? 2 : 3), zOutput.format(z), iOutput.format(cx - start.x, 0), kOutput.format(cz - start.z, 0), fOutput.format(feed)); + break; + case PLANE_YZ: + writeBlock(gPlaneModal.format(19), gMotionModal.format(clockwise ? 2 : 3), yOutput.format(y), jOutput.format(cy - start.y, 0), kOutput.format(cz - start.z, 0), fOutput.format(feed)); + break; + default: + linearize(tolerance); + } + } else { + switch (getCircularPlane()) { + case PLANE_XY: + writeBlock(gPlaneModal.format(17), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), iOutput.format(cx - start.x, 0), jOutput.format(cy - start.y, 0), fOutput.format(feed)); + break; + case PLANE_ZX: + writeBlock(gPlaneModal.format(18), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), iOutput.format(cx - start.x, 0), kOutput.format(cz - start.z, 0), fOutput.format(feed)); + break; + case PLANE_YZ: + writeBlock(gPlaneModal.format(19), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), jOutput.format(cy - start.y, 0), kOutput.format(cz - start.z, 0), fOutput.format(feed)); + break; + default: + linearize(tolerance); + } + } + } + + // Default + else { + // Marlin supports arcs only on XY plane + if (isFullCircle()) { + if (isHelical()) { + linearize(tolerance); + return; + } + switch (getCircularPlane()) { + case PLANE_XY: + writeBlock(gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), iOutput.format(cx - start.x, 0), jOutput.format(cy - start.y, 0), fOutput.format(feed)); + break; + default: + linearize(tolerance); + } + } else { + switch (getCircularPlane()) { + case PLANE_XY: + writeBlock(gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), iOutput.format(cx - start.x, 0), jOutput.format(cy - start.y, 0), fOutput.format(feed)); + break; + default: + linearize(tolerance); + } + } + } +} + +function askUser(text, title, allowJog) { + let fw = properties.jobSelectedFirmware; + + // Firmware is RepRap? + if (fw != eFirmware.REPRAP) { + var v1 = " P\"" + text + "\" R\"" + title + "\" S3"; + var v2 = allowJog ? " X1 Y1 Z1" : ""; + writeBlock(mFormat.format(291), (properties.jobSeparateWordsWithSpace ? "" : " ") + v1 + v2); + } + + // Default + else { + writeBlock(mFormat.format(0), (properties.jobSeparateWordsWithSpace ? "" : " ") + text); + } +} + +function toolChange() { + let fw = properties.jobSelectedFirmware; + + // Grbl tool change? + if (fw != eFirmware.GRBL) { + + writeBlock(mFormat.format(6), tFormat.format(tool.number)); + writeBlock(gFormat.format(54)); + } + + // Default tool change + else + { + flushMotions(); + + // Go to tool change position + onRapid(propertyMmToUnit(properties.toolChangeX), propertyMmToUnit(properties.toolChangeY), propertyMmToUnit(properties.toolChangeZ)); + + flushMotions(); + + // turn off spindle and coolant + onCommand(COMMAND_COOLANT_OFF); + onCommand(COMMAND_STOP_SPINDLE); + if (!properties.jobManualSpindlePowerControl) { + // Beep + writeBlock(mFormat.format(300), sFormat.format(400), pFormat.format(2000)); + } + + // Disable Z stepper + if (properties.toolChangeDisableZStepper) { + askUser("Z Stepper will disabled. Wait for STOP!!", "Tool change", false); + writeBlock(mFormat.format(17), 'Z'); // Disable steppers timeout + } + // Ask tool change and wait user to touch lcd button + askUser("Tool " + tool.number + " " + tool.comment, "Tool change", true); + + // Run Z probe gcode + if (properties.toolChangeZProbe && tool.number != 0) { + onCommand(COMMAND_TOOL_MEASURE); + } + } +} + +function probeTool() { + let fw = properties.jobSelectedFirmware; + + // Is Grbl? + if (fw != eFirmware.GRBL) { + } + + // Default + else { + writeComment(" Ask User to Attach the Z Probe"); + writeComment(" Probe"); + writeComment(" Set Z to probe thickness: " + zFormat.format(propertyMmToUnit(properties.probeThickness))) + if (properties.toolChangeZ != "") { + writeComment(" Retract the tool to " + propertyMmToUnit(properties.toolChangeZ)); + } + writeComment(" Ask User to Remove the Z Probe"); + + askUser("Attach ZProbe", "Probe", false); + // refer http://marlinfw.org/docs/gcode/G038.html + if (properties.probeUseHomeZ) { + writeBlock(gFormat.format(28), 'Z'); + } else { + writeBlock(gMotionModal.format(38.3), fFormat.format(propertyMmToUnit(properties.probeG38Speed)), zFormat.format(propertyMmToUnit(properties.probeG38Target))); + } + + let z = zFormat.format(propertyMmToUnit(properties.probeThickness)); + writeBlock(gFormat.format(92), z); // Set origin to initial position + + resetAll(); + if (properties.toolChangeZ != "") { // move up tool to safe height again after probing + rapidMovementsZ(propertyMmToUnit(properties.toolChangeZ), false); + } + + flushMotions(); + + askUser("Detach ZProbe", "Probe", false); + } +} + +properties3dPrinter = { + jobMarlinEnforceFeedrate: false, // Add feedrate to each movement line + + cutterMarlinMode: 106, // Marlin mode laser/plasma cutter + cutterMarlinPin: 4, // Marlin laser/plasma cutter pin for M42 + + coolantAMarlinOn: "M42 P11 S255", // GCode command to turn on Coolant channel A + coolantAMarlinOff: "M42 P11 S0", // Gcode command to turn off Coolant channel A + coolantBMarlinOn: "M42 P6 S255", // GCode command to turn on Coolant channel B + coolantBMarlinOff: "M42 P6 S0", // Gcode command to turn off Coolant channel B +}; + +propertyDefinitions3dPrinter = { + jobMarlinEnforceFeedrate: { + title: "Job: Enforce Feedrate", description: "Add feedrate to each movement g-code", group: 1, + type: "boolean", default_mm: false, default_in: false + }, + cutterMarlinMode: { + title: "Laser: Marlin/Reprap mode", description: "Marlin/Reprar mode of the laser/plasma cutter", group: 5, + type: "integer", default_mm: 106, default_in: 106, + values: [ + { title: "M106 S{PWM}/M107", id: 106 }, + { title: "M3 O{PWM}/M5", id: 3 }, + { title: "M42 P{pin} S{PWM}", id: 42 }, + ] + }, + cutterMarlinPin: { + title: "Laser: Marlin M42 pin", description: "Marlin custom pin number for the laser/plasma cutter", group: 5, + type: "integer", default_mm: 4, default_in: 4 + }, + + coolantAMarlinOn: { title: "Coolant: A On command", description: "GCode command to turn on Coolant channel A", group: 7, type: "string", default_mm: "M42 P11 S255" }, + coolantAMarlinOff: { + title: "Coolant: A Off command", description: "Gcode command to turn off Coolant A", group: 7, type: "string", + default_mm: "M42 P11 S0", default_in: "M42 P11 S0" + }, + + coolantBMarlinOn: { + title: "Coolant: B On command", description: "GCode command to turn on Coolant channel B", group: 7, type: "string", + default_mm: "M42 P6 S255", default_in: "M42 P6 S255" + }, + coolantBMarlinOff: { + title: "Coolant: B Off command", description: "Gcode command to turn off Coolant channel B", group: 7, type: "string", + default_mm: "M42 P6 S0", default_in: "M42 P6 S0" + }, +}; From b4086be4949c72467f675a46d1194682da9db4df Mon Sep 17 00:00:00 2001 From: flyfisher604 Date: Mon, 1 Feb 2021 23:11:29 -0800 Subject: [PATCH 02/24] Passes - creates same file --- MPCNC.cps | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/MPCNC.cps b/MPCNC.cps index 6cc00f1..5379711 100644 --- a/MPCNC.cps +++ b/MPCNC.cps @@ -33,7 +33,11 @@ mergeProperties(propertyDefinitions, propertyDefinitions3dPrinter); function flushMotions() { let fw = properties.jobSelectedFirmware; - if (fw != eFirmware.GRBL) { + if (fw == eFirmware.GRBL) { + } + + // Default + else { writeBlock(mFormat.format(400)); } } @@ -91,7 +95,9 @@ vendorUrl = "https://github.com/flyfisher604/mpcnc_post_processor"; // user-defined properties properties = { - jobSelectedFirmware : firmware, // Firmware to use in special cases + jobSelectedFirmware : firmware, // Firmware to use in special cases + + jobMarlinEnforceFeedrate: false, // Add feedrate to each movement line jobManualSpindlePowerControl: true, // Spindle motor is controlled by manual switch @@ -138,9 +144,15 @@ properties = { cutterOnVaporize: 100, // Persent of power to turn on the laser/plasma cutter in vaporize mode cutterOnThrough: 80, // Persent of power to turn on the laser/plasma cutter in through mode cutterOnEtch: 40, // Persent of power to turn on the laser/plasma cutter in etch mode + cutterMarlinMode: 106, // Marlin mode laser/plasma cutter + cutterMarlinPin: 4, // Marlin laser/plasma cutter pin for M42 coolantA_Mode: 0, // Enable issuing g-codes for control Coolant channel A - coolantB_Mode: 0, // Use issuing g-codes for control Coolant channel B + coolantAMarlinOn: "M42 P11 S255", // GCode command to turn on Coolant channel A + coolantAMarlinOff: "M42 P11 S0", // Gcode command to turn off Coolant channel A + coolantB_Mode: 0, // Use issuing g-codes for control Coolant channel B + coolantBMarlinOn: "M42 P6 S255", // GCode command to turn on Coolant channel B + coolantBMarlinOff: "M42 P6 S0", // Gcode command to turn off Coolant channel B commentWriteTools: true, commentActivities: true, @@ -553,7 +565,7 @@ function onOpen() { // Called at end of gcode file function onClose() { let fw = properties.jobSelectedFirmware; - + writeActivityComment(" *** STOP begin ***"); flushMotions(); @@ -1517,7 +1529,7 @@ function askUser(text, title, allowJog) { let fw = properties.jobSelectedFirmware; // Firmware is RepRap? - if (fw != eFirmware.REPRAP) { + if (fw == eFirmware.REPRAP) { var v1 = " P\"" + text + "\" R\"" + title + "\" S3"; var v2 = allowJog ? " X1 Y1 Z1" : ""; writeBlock(mFormat.format(291), (properties.jobSeparateWordsWithSpace ? "" : " ") + v1 + v2); @@ -1533,7 +1545,7 @@ function toolChange() { let fw = properties.jobSelectedFirmware; // Grbl tool change? - if (fw != eFirmware.GRBL) { + if (fw == eFirmware.GRBL) { writeBlock(mFormat.format(6), tFormat.format(tool.number)); writeBlock(gFormat.format(54)); @@ -1576,7 +1588,7 @@ function probeTool() { let fw = properties.jobSelectedFirmware; // Is Grbl? - if (fw != eFirmware.GRBL) { + if (fw == eFirmware.GRBL) { } // Default @@ -1611,6 +1623,7 @@ function probeTool() { } } +/* properties3dPrinter = { jobMarlinEnforceFeedrate: false, // Add feedrate to each movement line @@ -1657,3 +1670,4 @@ propertyDefinitions3dPrinter = { default_mm: "M42 P6 S0", default_in: "M42 P6 S0" }, }; +*/ From d147c7b69558bfae36fbbd053bbddb4deb8975c5 Mon Sep 17 00:00:00 2001 From: flyfisher604 Date: Mon, 1 Feb 2021 23:11:29 -0800 Subject: [PATCH 03/24] fixed Guffy missing p in properties --- MPCNC.cps | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MPCNC.cps b/MPCNC.cps index 5379711..aa531dd 100644 --- a/MPCNC.cps +++ b/MPCNC.cps @@ -67,7 +67,7 @@ function CoolantB(on) { // Default else { - writeBlock(on ? properties.coolantBMarlinOn : roperties.coolantBMarlinOff); + writeBlock(on ? properties.coolantBMarlinOn : properties.coolantBMarlinOff); } } From 99bb0a18a16daeec5e97c71ccb537a7a873ed902 Mon Sep 17 00:00:00 2001 From: flyfisher604 Date: Tue, 2 Feb 2021 00:41:25 -0800 Subject: [PATCH 04/24] commit#1 --- MPCNC.cps | 71 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 27 deletions(-) diff --git a/MPCNC.cps b/MPCNC.cps index aa531dd..ab2cf1f 100644 --- a/MPCNC.cps +++ b/MPCNC.cps @@ -414,7 +414,13 @@ propertyDefinitions = { }, coolantAMarlinOn: { title: "Coolant: A On command", description: "GCode command to turn on Coolant channel A", group: 8, - type: "string", default_mm: "M42 P11 S255" + type: "enum", default_mm: "M42 P11 S255", + values: [ + { title: "Marlin: M42 P11 S255", id: "M42 P11 S255" }, + { title: "Marlin: M42 P6 S255", id: "M42 P6 S255" }, + { title: "Grbl: M7 (mist)", id: "M7" }, + { title: "Grbl: M8 (flood)", id: "M8" } + ] }, coolantAMarlinOff: { title: "Coolant: A Off command", description: "Gcode command to turn off Coolant A", group: 8, @@ -422,8 +428,8 @@ propertyDefinitions = { }, coolantB_Mode: { - title: "Coolant: B Mode", description: "Enable issuing g-codes for control Coolant channel B", group: 8, type: "integer", - default_mm: 0, default_in: 0, + title: "Coolant: B Mode", description: "Enable issuing g-codes for control Coolant channel B", group: 8, + type: "integer", default_mm: 0, default_in: 0, values: [ { title: "off", id: 0 }, { title: "flood", id: 1 }, @@ -1228,44 +1234,55 @@ function loadFile(_file) { } } -// Manage coolant state +// Manage two channels of coolant by tracking which coolant is being using for +// a channel (0 = disabled). SetCoolant called with desired coolant to use or 0 to disable -var currentCoolantMode = 0; +var coolantChannelA = 0; +var coolantChannelB = 0; function setCoolant(coolant) { let fw = properties.jobSelectedFirmware; - if (currentCoolantMode == coolant) { + // As long as we are not disabling coolant, then if either of the coolant + // channels are already operating in the mode requested then there is + // nothing to do + if ((coolant != 0) && + ((coolantChannelA == coolant) || (coolantChannelB == coolant))) { return; } - if (properties.coolantA_Mode != 0) { - if (currentCoolantMode == properties.coolantA_Mode) { - writeActivityComment(" >>> Coolant A OFF"); - - CoolantA(true); - - } else if (coolant == properties.coolantA_Mode) { - writeActivityComment(" >>> Coolant A ON"); - - CoolantA(false); - } + // F360 allows only 1 coolant to be defined on an operation. If a coolant channel + // is active then disable it before we switch to the other + if (coolantChannelA != 0) { + writeActivityComment(" >>> Coolant A OFF"); + coolantChannelA = 0; + CoolantA(false); } - if (properties.coolantB_Mode != 0) { - if (currentCoolantMode == properties.coolantB_Mode) { - writeActivityComment(" >>> Coolant B OFF"); + if (coolantChannelB != 0) { + writeActivityComment(" >>> Coolant B OFF"); + coolantChannelB = 0; + CoolantB(false); + } + // As long as we are not disabling coolant (coolant = 0), then check the coolant channels + // and enable the one that provides the coolant requested. If neither do then + // issue an warning + if (coolant != 0) { + if (properties.coolantA_Mode == coolant) { + writeActivityComment(" >>> Coolant A ON: " + propertyDefinitions.coolantA_Mode.values[coolant].title); + coolantChannelA = coolant; + CoolantA(true); + } + else if (properties.coolantB_Mode == coolant) { + writeActivityComment(" >>> Coolant B ON: " + propertyDefinitions.coolantB_Mode.values[coolant].title); + coolantChannelB = coolant; CoolantB(true); - - } else if (coolant == properties.coolantB_Mode) { - writeActivityComment(" >>> Coolant B ON"); - - CoolantB(false); + } + else { + writeActivityComment(" >>> Coolant Channel not Configured" + coolant); } } - - currentCoolantMode = coolant; } function propertyMmToUnit(_v) { From b1a521686b1d35877fbc478a4930fbd721e8b248 Mon Sep 17 00:00:00 2001 From: flyfisher604 Date: Tue, 2 Feb 2021 22:21:24 -0800 Subject: [PATCH 05/24] Coolant redone --- MPCNC.cps | 145 ++++++++++++++++++++++-------------------------------- 1 file changed, 60 insertions(+), 85 deletions(-) diff --git a/MPCNC.cps b/MPCNC.cps index ab2cf1f..9205f6e 100644 --- a/MPCNC.cps +++ b/MPCNC.cps @@ -15,7 +15,7 @@ var eFirmware = { GRBL: 1, REPRAP: 2, prop: { - 0: {name: "Marlin 2.0", value: 0, code: "S"}, + 0: {name: "Marlin 2.x", value: 0, code: "S"}, 1: {name: "Grbl 1.1", value: 1, code: "M"}, 2: {name: "RepRap", value: 2, code: "L"} } @@ -44,31 +44,11 @@ function flushMotions() { // Coolant function CoolantA(on) { - let fw = properties.jobSelectedFirmware; - - // Firmware is Grbl? - if (fw == eFirmware.GRBL) { - writeBlock(mFormat.format(on ? properties.GrblCoolantA : 9)); - } - - // Default - else { - writeBlock(on ? properties.coolantAMarlinOn : properties.coolantAMarlinOff); - } + writeBlock(on ? properties.cl2_coolantAOn : properties.cl3_coolantAOff); } function CoolantB(on) { - let fw = properties.jobSelectedFirmware; - - // Firmware is Grbl? - if (fw == eFirmware.GRBL) { - writeBlock(mFormat.format(on ? properties.GrblCoolantB : 9)); - } - - // Default - else { - writeBlock(on ? properties.coolantBMarlinOn : properties.coolantBMarlinOff); - } + writeBlock(on ? properties.cl4_coolantBOn : properties.cl5_coolantBOff); } @@ -97,8 +77,6 @@ vendorUrl = "https://github.com/flyfisher604/mpcnc_post_processor"; properties = { jobSelectedFirmware : firmware, // Firmware to use in special cases - jobMarlinEnforceFeedrate: false, // Add feedrate to each movement line - jobManualSpindlePowerControl: true, // Spindle motor is controlled by manual switch jobUseArcs: true, // Produce G2/G3 for arcs @@ -113,6 +91,7 @@ properties = { fr0_TravelSpeedXY: 2500, // High speed for travel movements X & Y (mm/min) fr1_TravelSpeedZ: 300, // High speed for travel movements Z (mm/min) + fr2_EnforceFeedrate: false, // Add feedrate to each movement line frA_ScaleFeedrate: false, // Will feedrated be scaled frB_MaxCutSpeedXY: 900, // Max speed for cut movements X & Y (mm/min) frC_MaxCutSpeedZ: 180, // Max speed for cut movements Z (mm/min) @@ -147,12 +126,12 @@ properties = { cutterMarlinMode: 106, // Marlin mode laser/plasma cutter cutterMarlinPin: 4, // Marlin laser/plasma cutter pin for M42 - coolantA_Mode: 0, // Enable issuing g-codes for control Coolant channel A - coolantAMarlinOn: "M42 P11 S255", // GCode command to turn on Coolant channel A - coolantAMarlinOff: "M42 P11 S0", // Gcode command to turn off Coolant channel A - coolantB_Mode: 0, // Use issuing g-codes for control Coolant channel B - coolantBMarlinOn: "M42 P6 S255", // GCode command to turn on Coolant channel B - coolantBMarlinOff: "M42 P6 S0", // Gcode command to turn off Coolant channel B + cl0_coolantA_Mode: 0, // Enable issuing g-codes for control Coolant channel A + cl1_coolantB_Mode: 0, // Use issuing g-codes for control Coolant channel B + cl2_coolantAOn: "M42 P6 S255", // GCode command to turn on Coolant channel A + cl3_coolantAOff: "M42 P6 S0", // Gcode command to turn off Coolant channel A + cl4_coolantBOn: "M42 P11 S255", // GCode command to turn on Coolant channel B + cl5_coolantBOff: "M42 P11 S0", // Gcode command to turn off Coolant channel B commentWriteTools: true, commentActivities: true, @@ -164,8 +143,6 @@ properties = { DuetLaserMode: "M452 P2 I0 R255 F200", // GCode command to setup Duet3d laser mode GrblCutterMode: 4, // GRBL mode laser/plasma cutter - GrblCoolantA: 7, // GCode command to turn on Coolant channel A - GrblCoolantB: 8, // GCode command to turn on Coolant channel A }; propertyDefinitions = { @@ -229,6 +206,10 @@ propertyDefinitions = { title: "Feed: Travel Speed Z", description: "High speed for Rapid movements z (mm/min; in/min)", group: 2, type: "spatial", default_mm: 300, default_in: 12 }, + fr2_EnforceFeedrate: { + title: "Feed: Enforce Feedrate", description: "Add feedrate to each movement g-code", group: 2, + type: "boolean", default_mm: false, default_in: false + }, frA_ScaleFeedrate: { title: "Feed: Scale feedrate", description: "Scale feedrate based on X, Y, Z axis maximums", group: 2, type: "boolean", default_mm: false, default_in: false @@ -397,8 +378,8 @@ propertyDefinitions = { // Coolant - coolantA_Mode: { - title: "Coolant: A Mode", description: "Enable issuing g-codes for control Coolant channel A", group: 8, + cl0_coolantA_Mode: { + title: "Coolant: A Mode", description: "Enable channel A when tool is set this coolant", group: 8, type: "integer", default_mm: 0, default_in: 0, values: [ { title: "off", id: 0 }, @@ -412,23 +393,8 @@ propertyDefinitions = { { title: "floodThroughTool", id: 8 } ] }, - coolantAMarlinOn: { - title: "Coolant: A On command", description: "GCode command to turn on Coolant channel A", group: 8, - type: "enum", default_mm: "M42 P11 S255", - values: [ - { title: "Marlin: M42 P11 S255", id: "M42 P11 S255" }, - { title: "Marlin: M42 P6 S255", id: "M42 P6 S255" }, - { title: "Grbl: M7 (mist)", id: "M7" }, - { title: "Grbl: M8 (flood)", id: "M8" } - ] - }, - coolantAMarlinOff: { - title: "Coolant: A Off command", description: "Gcode command to turn off Coolant A", group: 8, - type: "string", default_mm: "M42 P11 S0", default_in: "M42 P11 S0" - }, - - coolantB_Mode: { - title: "Coolant: B Mode", description: "Enable issuing g-codes for control Coolant channel B", group: 8, + cl1_coolantB_Mode: { + title: "Coolant: B Mode", description: "Enable channel B when tool is set this coolant", group: 8, type: "integer", default_mm: 0, default_in: 0, values: [ { title: "off", id: 0 }, @@ -442,29 +408,42 @@ propertyDefinitions = { { title: "floodThroughTool", id: 8 } ] }, - coolantBMarlinOn: { - title: "Coolant: B On command", description: "GCode command to turn on Coolant channel B", group: 8, - type: "string", default_mm: "M42 P6 S255", default_in: "M42 P6 S255" + cl2_coolantAOn: { + title: "Coolant: A Enable", description: "GCode to turn On coolant channel A", group: 8, + type: "enum", default_mm: "M42 P6 S255", default_in: "M42 P6 S255", + values: [ + { title: "Mrln: M42 P6 S255", id: "M42 P6 S255" }, + { title: "Mrln: M42 P11 S255", id: "M42 P11 S255" }, + { title: "Grbl: M7 (mist)", id: "M7" }, + { title: "Grbl: M8 (flood)", id: "M8" } + ] }, - coolantBMarlinOff: { - title: "Coolant: B Off command", description: "Gcode command to turn off Coolant channel B", group: 8, - type: "string", default_mm: "M42 P6 S0", default_in: "M42 P6 S0" + cl3_coolantAOff: { + title: "Coolant: A Disable", description: "Gcode to turn Off coolant A", group: 8, + type: "enum", default_mm: "M42 P6 S0", default_in: "M42 P6 S0", + values: [ + { title: "Mrln: M42 P6 S0", id: "M42 P6 S0" }, + { title: "Mrln: M42 P11 S0", id: "M42 P11 S0" }, + { title: "Grbl: M9 (off)", id: "M9" } + ] }, - - GrblCoolantA: { - title: "Grbl: Coolant A code", description: "GRBL g-codes for control Coolant channel A", group: 11, - type: "integer", default_mm: 7, default_in: 7, + cl4_coolantBOn: { + title: "Coolant: B Enable", description: "GCode to turn On coolant channel B", group: 8, + type: "enum", default_mm: "M42 P11 S255", default_in: "M42 P11 S255", values: [ - { title: "M7 flood", id: 7 }, - { title: "M8 mist", id: 8 }, + { title: "Mrln: M42 P11 S255", id: "M42 P11 S255" }, + { title: "Mrln: M42 P6 S255", id: "M42 P6 S255" }, + { title: "Grbl: M7 (mist)", id: "M7" }, + { title: "Grbl: M8 (flood)", id: "M8" } ] }, - GrblCoolantB: { - title: "Grbl: Coolant B code", description: "GRBL g-codes for control Coolant channel B", group: 11, - type: "integer", default_mm: 8, default_in: 8, + cl5_coolantBOff: { + title: "Coolant: B Disable", description: "Gcode to turn Off coolant B", group: 8, + type: "enum", default_mm: "M42 P11 S0", default_in: "M42 P11 S0", values: [ - { title: "M7 flood", id: 7 }, - { title: "M8 mist", id: 8 }, + { title: "Mrln: M42 P11 S0", id: "M42 P11 S0" }, + { title: "Mrln: M42 P6 S0", id: "M42 P6 S0" }, + { title: "Grbl: M9 (off)", id: "M9" } ] }, }; @@ -556,10 +535,10 @@ function onOpen() { } else { gMotionModal = createModal({ force: true }, gFormat); // modal group 1 // G0-G3, ... + } - if (properties.jobMarlinEnforceFeedrate) { - fOutput = createVariable({ force: true }, fFormat); - } + if (properties.fr2_EnforceFeedrate) { + fOutput = createVariable({ force: true }, fFormat); } sequenceNumber = properties.jobSequenceNumberStart; @@ -1243,7 +1222,7 @@ var coolantChannelB = 0; function setCoolant(coolant) { let fw = properties.jobSelectedFirmware; - // As long as we are not disabling coolant, then if either of the coolant + // As long as we are not disabling coolant (= 0), then if either of the coolant // channels are already operating in the mode requested then there is // nothing to do if ((coolant != 0) && @@ -1254,13 +1233,13 @@ function setCoolant(coolant) { // F360 allows only 1 coolant to be defined on an operation. If a coolant channel // is active then disable it before we switch to the other if (coolantChannelA != 0) { - writeActivityComment(" >>> Coolant A OFF"); + writeActivityComment(" >>> Coolant Channel A: off"); coolantChannelA = 0; CoolantA(false); } if (coolantChannelB != 0) { - writeActivityComment(" >>> Coolant B OFF"); + writeActivityComment(" >>> Coolant Channel B: off"); coolantChannelB = 0; CoolantB(false); } @@ -1269,18 +1248,18 @@ function setCoolant(coolant) { // and enable the one that provides the coolant requested. If neither do then // issue an warning if (coolant != 0) { - if (properties.coolantA_Mode == coolant) { - writeActivityComment(" >>> Coolant A ON: " + propertyDefinitions.coolantA_Mode.values[coolant].title); + if (properties.cl0_coolantA_Mode == coolant) { + writeActivityComment(" >>> Coolant Channel A: " + propertyDefinitions.cl0_coolantA_Mode.values[coolant].title); coolantChannelA = coolant; CoolantA(true); } - else if (properties.coolantB_Mode == coolant) { - writeActivityComment(" >>> Coolant B ON: " + propertyDefinitions.coolantB_Mode.values[coolant].title); + else if (properties.cl1_coolantB_Mode == coolant) { + writeActivityComment(" >>> Coolant Channel B: " + propertyDefinitions.cl1_coolantB_Mode.values[coolant].title); coolantChannelB = coolant; CoolantB(true); } else { - writeActivityComment(" >>> Coolant Channel not Configured" + coolant); + writeActivityComment(" >>> Coolant Channels, none set for: " + coolant); } } } @@ -1642,7 +1621,7 @@ function probeTool() { /* properties3dPrinter = { - jobMarlinEnforceFeedrate: false, // Add feedrate to each movement line + fr2_EnforceFeedrate: false, // Add feedrate to each movement line cutterMarlinMode: 106, // Marlin mode laser/plasma cutter cutterMarlinPin: 4, // Marlin laser/plasma cutter pin for M42 @@ -1654,10 +1633,6 @@ properties3dPrinter = { }; propertyDefinitions3dPrinter = { - jobMarlinEnforceFeedrate: { - title: "Job: Enforce Feedrate", description: "Add feedrate to each movement g-code", group: 1, - type: "boolean", default_mm: false, default_in: false - }, cutterMarlinMode: { title: "Laser: Marlin/Reprap mode", description: "Marlin/Reprar mode of the laser/plasma cutter", group: 5, type: "integer", default_mm: 106, default_in: 106, From c29c694628e9b2b24e76cb49b273efee052dea63 Mon Sep 17 00:00:00 2001 From: flyfisher604 Date: Tue, 2 Feb 2021 22:23:01 -0800 Subject: [PATCH 06/24] Removed dead code --- MPCNC.cps | 47 +---------------------------------------------- 1 file changed, 1 insertion(+), 46 deletions(-) diff --git a/MPCNC.cps b/MPCNC.cps index 9205f6e..5d3b9ef 100644 --- a/MPCNC.cps +++ b/MPCNC.cps @@ -1617,49 +1617,4 @@ function probeTool() { askUser("Detach ZProbe", "Probe", false); } -} - -/* -properties3dPrinter = { - fr2_EnforceFeedrate: false, // Add feedrate to each movement line - - cutterMarlinMode: 106, // Marlin mode laser/plasma cutter - cutterMarlinPin: 4, // Marlin laser/plasma cutter pin for M42 - - coolantAMarlinOn: "M42 P11 S255", // GCode command to turn on Coolant channel A - coolantAMarlinOff: "M42 P11 S0", // Gcode command to turn off Coolant channel A - coolantBMarlinOn: "M42 P6 S255", // GCode command to turn on Coolant channel B - coolantBMarlinOff: "M42 P6 S0", // Gcode command to turn off Coolant channel B -}; - -propertyDefinitions3dPrinter = { - cutterMarlinMode: { - title: "Laser: Marlin/Reprap mode", description: "Marlin/Reprar mode of the laser/plasma cutter", group: 5, - type: "integer", default_mm: 106, default_in: 106, - values: [ - { title: "M106 S{PWM}/M107", id: 106 }, - { title: "M3 O{PWM}/M5", id: 3 }, - { title: "M42 P{pin} S{PWM}", id: 42 }, - ] - }, - cutterMarlinPin: { - title: "Laser: Marlin M42 pin", description: "Marlin custom pin number for the laser/plasma cutter", group: 5, - type: "integer", default_mm: 4, default_in: 4 - }, - - coolantAMarlinOn: { title: "Coolant: A On command", description: "GCode command to turn on Coolant channel A", group: 7, type: "string", default_mm: "M42 P11 S255" }, - coolantAMarlinOff: { - title: "Coolant: A Off command", description: "Gcode command to turn off Coolant A", group: 7, type: "string", - default_mm: "M42 P11 S0", default_in: "M42 P11 S0" - }, - - coolantBMarlinOn: { - title: "Coolant: B On command", description: "GCode command to turn on Coolant channel B", group: 7, type: "string", - default_mm: "M42 P6 S255", default_in: "M42 P6 S255" - }, - coolantBMarlinOff: { - title: "Coolant: B Off command", description: "Gcode command to turn off Coolant channel B", group: 7, type: "string", - default_mm: "M42 P6 S0", default_in: "M42 P6 S0" - }, -}; -*/ +} \ No newline at end of file From 710e9b0bd037cbccff6c95c96bb0920bede31e10 Mon Sep 17 00:00:00 2001 From: flyfisher604 Date: Wed, 3 Feb 2021 00:44:14 -0800 Subject: [PATCH 07/24] Comment now work by level --- MPCNC.cps | 402 ++++++++++++++++++++++++++---------------------------- 1 file changed, 196 insertions(+), 206 deletions(-) diff --git a/MPCNC.cps b/MPCNC.cps index 5d3b9ef..2ad00c6 100644 --- a/MPCNC.cps +++ b/MPCNC.cps @@ -15,14 +15,27 @@ var eFirmware = { GRBL: 1, REPRAP: 2, prop: { - 0: {name: "Marlin 2.x", value: 0, code: "S"}, - 1: {name: "Grbl 1.1", value: 1, code: "M"}, - 2: {name: "RepRap", value: 2, code: "L"} + 0: {name: "Marlin 2.x", value: 0}, + 1: {name: "Grbl 1.1", value: 1}, + 2: {name: "RepRap", value: 2} } }; var firmware = eFirmware.MARLIN; +var eComment = { + Off: 0, + Important: 1, + Info: 2, + Debug: 3, + prop: { + 0: {name: "Off", value: 0}, + 1: {name: "Important", value: 1}, + 2: {name: "Info", value: 2}, + 3: {name: "Debug", value: 3} + } +}; + machineMode = undefined; //TYPE_MILLING, TYPE_JET /* @@ -87,7 +100,8 @@ properties = { jobSequenceNumbers: false, // show sequence numbers jobSequenceNumberStart: 10, // first sequence number jobSequenceNumberIncrement: 1, // increment for sequence numbers - jobSeparateWordsWithSpace: true, // specifies that the words should be separated with a white space + jobSeparateWordsWithSpace: true, // specifies that the words should be separated with a white space + jobCommentLevel: eComment.Info, // The level of comments included fr0_TravelSpeedXY: 2500, // High speed for travel movements X & Y (mm/min) fr1_TravelSpeedZ: 300, // High speed for travel movements Z (mm/min) @@ -133,12 +147,6 @@ properties = { cl4_coolantBOn: "M42 P11 S255", // GCode command to turn on Coolant channel B cl5_coolantBOff: "M42 P11 S0", // Gcode command to turn off Coolant channel B - commentWriteTools: true, - commentActivities: true, - commentSections: true, - commentCommands: true, - commentMovements: true, - DuetMillingMode: "M453 P2 I0 R30000 F200", // GCode command to setup Duet3d milling mode DuetLaserMode: "M452 P2 I0 R255 F200", // GCode command to setup Duet3d laser mode @@ -196,8 +204,17 @@ propertyDefinitions = { title: "Job: Separate words", description: "Specifies that the words should be separated with a white space", group: 1, type: "boolean", default_mm: true, default_in: true }, - - + jobCommentLevel: { + title: "Job: Comment Level", description: "Controls the comments include", group: 1, + type: "integer", default_mm: 3, default_in: 3, + values: [ + { title: eComment.prop[eComment.Off].name, id: eComment.Off }, + { title: eComment.prop[eComment.Important].name, id: eComment.Important }, + { title: eComment.prop[eComment.Info].name, id: eComment.Info }, + { title: eComment.prop[eComment.Debug].name, id: eComment.Debug }, + ] + }, + fr0_TravelSpeedXY: { title: "Feed: Travel speed X/Y", description: "High speed for Rapid movements X & Y (mm/min; in/min)", group: 2, type: "spatial", default_mm: 2500, default_in: 100 @@ -336,27 +353,6 @@ propertyDefinitions = { }, - commentWriteTools: { - title: "Comment: Write Tools", description: "Write table of used tools in job header", group: 9, - type: "boolean", default_mm: true, default_in: true - }, - commentActivities: { - title: "Comment: Activities", description: "Write comments which somehow helps to understand current piece of g-code", group: 9, - type: "boolean", default_mm: true, default_in: true - }, - commentSections: { - title: "Comment: Sections", description: "Write header of every section", group: 9, - type: "boolean", default_mm: true, default_in: true - }, - commentCommands: { - title: "Comment: Trace Commands", description: "Write stringified commands called by CAM", group: 9, - type: "boolean", default_mm: true, default_in: true - }, - commentMovements: { - title: "Comment: Trace Movements", description: "Write stringified movements called by CAM", group: 9, - type: "boolean", default_mm: true, default_in: true - }, - DuetMillingMode: { title: "Duet: Milling mode", description: "GCode command to setup Duet3d milling mode", group: 10, type: "string", default_mm: "M453 P2 I0 R30000 F200", default_in: "M453 P2 I0 R30000 F200" @@ -551,7 +547,7 @@ function onOpen() { function onClose() { let fw = properties.jobSelectedFirmware; - writeActivityComment(" *** STOP begin ***"); + writeComment(eComment.Important, " *** STOP begin ***"); flushMotions(); @@ -564,7 +560,7 @@ function onClose() { end(true); - writeActivityComment(" *** STOP end ***"); + writeComment(eComment.Important, " *** STOP end ***"); } else { loadFile(properties.gcodeStopFile); } @@ -572,8 +568,6 @@ function onClose() { if (fw == eFirmware.GRBL) { writeln("%"); } - else { - } } var cutterOnCurrentPower; @@ -592,61 +586,59 @@ function onSection() { forceSectionToStartWithRapid = true; - // Write Start gcode of the documment (after the "onParameters" with the global info) + // Write Start gcode of the documment (after the "onParameters" with the global info) if (isFirstSection()) { writeFirstSection(); } - writeActivityComment(" *** SECTION begin ***"); + writeComment(eComment.Important, " *** SECTION begin ***"); - // Tool change + // Do a tool change if tool changes are enabled and its not the first section and this section uses + // a different tool then the previous section if (properties.toolChangeEnabled && !isFirstSection() && tool.number != getPreviousSection().getTool().number) { if (properties.gcodeToolFile == "") { - // Builtin tool change gcode - writeActivityComment(" --- CHANGE TOOL begin ---"); - - toolChange(); + // Post Processor does the tool change - writeActivityComment(" --- CHANGE TOOL end ---"); + writeComment(eComment.Important, " --- Tool Change Start") + toolChange(); + writeComment(eComment.Important, " --- Tool Change End") } else { - // Custom tool change gcode + // Users custom tool change gcode is used loadFile(properties.gcodeToolFile); } } - if (properties.commentSections) { - // Machining type - if (currentSection.type == TYPE_MILLING) { - // Specific milling code - writeComment(" " + sectionComment + " - Milling - Tool: " + tool.number + " - " + tool.comment + " " + getToolTypeName(tool.type)); - } + // Machining type + if (currentSection.type == TYPE_MILLING) { + // Specific milling code + writeComment(eComment.Info, " " + sectionComment + " - Milling - Tool: " + tool.number + " - " + tool.comment + " " + getToolTypeName(tool.type)); + } - if (currentSection.type == TYPE_JET) { - // Cutter mode used for different cutting power in PWM laser - switch (currentSection.jetMode) { - case JET_MODE_THROUGH: - cutterOnCurrentPower = properties.cutterOnThrough; - break; - case JET_MODE_ETCHING: - cutterOnCurrentPower = properties.cutterOnEtch; - break; - case JET_MODE_VAPORIZE: - cutterOnCurrentPower = properties.cutterOnVaporize; - break; - default: - error("Cutting mode is not supported."); - } - writeComment(" " + sectionComment + " - Laser/Plasma - Cutting mode: " + getParameter("operation:cuttingMode")); + if (currentSection.type == TYPE_JET) { + // Cutter mode used for different cutting power in PWM laser + switch (currentSection.jetMode) { + case JET_MODE_THROUGH: + cutterOnCurrentPower = properties.cutterOnThrough; + break; + case JET_MODE_ETCHING: + cutterOnCurrentPower = properties.cutterOnEtch; + break; + case JET_MODE_VAPORIZE: + cutterOnCurrentPower = properties.cutterOnVaporize; + break; + default: + error("Cutting mode is not supported."); } - - // Print min/max boundaries for each section - vectorX = new Vector(1, 0, 0); - vectorY = new Vector(0, 1, 0); - writeComment(" X Min: " + xyzFormat.format(currentSection.getGlobalRange(vectorX).getMinimum()) + " - X Max: " + xyzFormat.format(currentSection.getGlobalRange(vectorX).getMaximum())); - writeComment(" Y Min: " + xyzFormat.format(currentSection.getGlobalRange(vectorY).getMinimum()) + " - Y Max: " + xyzFormat.format(currentSection.getGlobalRange(vectorY).getMaximum())); - writeComment(" Z Min: " + xyzFormat.format(currentSection.getGlobalZRange().getMinimum()) + " - Z Max: " + xyzFormat.format(currentSection.getGlobalZRange().getMaximum())); + writeComment(eComment.Info, " " + sectionComment + " - Laser/Plasma - Cutting mode: " + getParameter("operation:cuttingMode")); } + // Print min/max boundaries for each section + vectorX = new Vector(1, 0, 0); + vectorY = new Vector(0, 1, 0); + writeComment(eComment.Info, " X Min: " + xyzFormat.format(currentSection.getGlobalRange(vectorX).getMinimum()) + " - X Max: " + xyzFormat.format(currentSection.getGlobalRange(vectorX).getMaximum())); + writeComment(eComment.Info, " Y Min: " + xyzFormat.format(currentSection.getGlobalRange(vectorY).getMinimum()) + " - Y Max: " + xyzFormat.format(currentSection.getGlobalRange(vectorY).getMaximum())); + writeComment(eComment.Info, " Z Min: " + xyzFormat.format(currentSection.getGlobalZRange().getMinimum()) + " - Z Max: " + xyzFormat.format(currentSection.getGlobalZRange().getMaximum())); + // Adjust the mode if (fw == eFirmware.REPRAP) { if (machineMode != currentSection.type) { @@ -680,12 +672,12 @@ function resetAll() { // Called in every section end function onSectionEnd() { resetAll(); - writeActivityComment(" *** SECTION end ***"); + writeComment(eComment.Important, " *** SECTION end ***"); writeln(""); } function onComment(message) { - writeComment(message); + writeComment(eComment.Important, message); } var pendingRadiusCompensation = RADIUS_COMPENSATION_OFF; @@ -749,13 +741,13 @@ function onLinear(x, y, z, feed) { // slowest cutting feedrate, generally Z's feedrate. if (properties.mapD_RestoreFirstRapids && (forceSectionToStartWithRapid == true)) { - writeComment(" First G1 --> G0"); + writeComment(eComment.Important, " First G1 --> G0"); forceSectionToStartWithRapid = false; onRapid(x, y, z); } else if (safeToRapid(x, y, z)) { - writeComment(" Safe G1 --> G0"); + writeComment(eComment.Important, " Safe G1 --> G0"); onRapid(x, y, z); } @@ -792,11 +784,11 @@ var powerState = false; function onPower(power) { if (power != powerState) { if (power) { - writeActivityComment(" >>> LASER Power ON"); + writeComment(eComment.Important, " >>> LASER Power ON"); laserOn(cutterOnCurrentPower); } else { - writeActivityComment(" >>> LASER Power OFF"); + writeComment(eComment.Important, " >>> LASER Power OFF"); laserOff(); } @@ -808,7 +800,7 @@ function onPower(power) { function onDwell(seconds) { let fw = properties.jobSelectedFirmware; - writeActivityComment(" >>> Dwell"); + writeComment(eComment.Important, " >>> Dwell"); if (seconds > 99999.999) { warning(localize("Dwelling time is out of range.")); } @@ -832,79 +824,80 @@ function onParameter(name, value) { // Write gcode initial info // Product version if (name == "generated-by") { - writeComment(value); - writeComment(" Posts processor: " + FileSystem.getFilename(getConfigurationPath())); + writeComment(eComment.Important, value); + writeComment(eComment.Important, " Posts processor: " + FileSystem.getFilename(getConfigurationPath())); } // Date - if (name == "generated-at") writeComment(" Gcode generated: " + value + " GMT"); + if (name == "generated-at") writeComment(eComment.Important, " Gcode generated: " + value + " GMT"); // Document - if (name == "document-path") writeComment(" Document: " + value); + if (name == "document-path") writeComment(eComment.Important, " Document: " + value); // Setup - if (name == "job-description") writeComment(" Setup: " + value); + if (name == "job-description") writeComment(eComment.Important, " Setup: " + value); // Get section comment if (name == "operation-comment") sectionComment = value; } function onMovement(movement) { - if (properties.commentMovements) { - var jet = tool.isJetTool && tool.isJetTool(); - var id; - switch (movement) { - case MOVEMENT_RAPID: - id = "MOVEMENT_RAPID"; - break; - case MOVEMENT_LEAD_IN: - id = "MOVEMENT_LEAD_IN"; - break; - case MOVEMENT_CUTTING: - id = "MOVEMENT_CUTTING"; - break; - case MOVEMENT_LEAD_OUT: - id = "MOVEMENT_LEAD_OUT"; - break; - case MOVEMENT_LINK_TRANSITION: - id = jet ? "MOVEMENT_BRIDGING" : "MOVEMENT_LINK_TRANSITION"; - break; - case MOVEMENT_LINK_DIRECT: - id = "MOVEMENT_LINK_DIRECT"; - break; - case MOVEMENT_RAMP_HELIX: - id = jet ? "MOVEMENT_PIERCE_CIRCULAR" : "MOVEMENT_RAMP_HELIX"; - break; - case MOVEMENT_RAMP_PROFILE: - id = jet ? "MOVEMENT_PIERCE_PROFILE" : "MOVEMENT_RAMP_PROFILE"; - break; - case MOVEMENT_RAMP_ZIG_ZAG: - id = jet ? "MOVEMENT_PIERCE_LINEAR" : "MOVEMENT_RAMP_ZIG_ZAG"; - break; - case MOVEMENT_RAMP: - id = "MOVEMENT_RAMP"; - break; - case MOVEMENT_PLUNGE: - id = jet ? "MOVEMENT_PIERCE" : "MOVEMENT_PLUNGE"; - break; - case MOVEMENT_PREDRILL: - id = "MOVEMENT_PREDRILL"; - break; - case MOVEMENT_EXTENDED: - id = "MOVEMENT_EXTENDED"; - break; - case MOVEMENT_REDUCED: - id = "MOVEMENT_REDUCED"; - break; - case MOVEMENT_HIGH_FEED: - id = "MOVEMENT_HIGH_FEED"; - break; - case MOVEMENT_FINISH_CUTTING: - id = "MOVEMENT_FINISH_CUTTING"; - break; - } - if (id == undefined) { - id = String(movement); - } - writeComment(" " + id); - } + var jet = tool.isJetTool && tool.isJetTool(); + var id; + + switch (movement) { + case MOVEMENT_RAPID: + id = "MOVEMENT_RAPID"; + break; + case MOVEMENT_LEAD_IN: + id = "MOVEMENT_LEAD_IN"; + break; + case MOVEMENT_CUTTING: + id = "MOVEMENT_CUTTING"; + break; + case MOVEMENT_LEAD_OUT: + id = "MOVEMENT_LEAD_OUT"; + break; + case MOVEMENT_LINK_TRANSITION: + id = jet ? "MOVEMENT_BRIDGING" : "MOVEMENT_LINK_TRANSITION"; + break; + case MOVEMENT_LINK_DIRECT: + id = "MOVEMENT_LINK_DIRECT"; + break; + case MOVEMENT_RAMP_HELIX: + id = jet ? "MOVEMENT_PIERCE_CIRCULAR" : "MOVEMENT_RAMP_HELIX"; + break; + case MOVEMENT_RAMP_PROFILE: + id = jet ? "MOVEMENT_PIERCE_PROFILE" : "MOVEMENT_RAMP_PROFILE"; + break; + case MOVEMENT_RAMP_ZIG_ZAG: + id = jet ? "MOVEMENT_PIERCE_LINEAR" : "MOVEMENT_RAMP_ZIG_ZAG"; + break; + case MOVEMENT_RAMP: + id = "MOVEMENT_RAMP"; + break; + case MOVEMENT_PLUNGE: + id = jet ? "MOVEMENT_PIERCE" : "MOVEMENT_PLUNGE"; + break; + case MOVEMENT_PREDRILL: + id = "MOVEMENT_PREDRILL"; + break; + case MOVEMENT_EXTENDED: + id = "MOVEMENT_EXTENDED"; + break; + case MOVEMENT_REDUCED: + id = "MOVEMENT_REDUCED"; + break; + case MOVEMENT_HIGH_FEED: + id = "MOVEMENT_HIGH_FEED"; + break; + case MOVEMENT_FINISH_CUTTING: + id = "MOVEMENT_FINISH_CUTTING"; + break; + } + + if (id == undefined) { + id = String(movement); + } + + writeComment(eComment.Info, " " + id); } var currentSpindleSpeed = 0; @@ -927,7 +920,7 @@ function onSpindleSpeed(spindleSpeed) { function onCommand(command) { if (properties.commentActivities) { var stringId = getCommandStringId(command); - writeComment(" " + stringId); + writeComment(eComment.Info, " " + stringId); } switch (command) { case COMMAND_START_SPINDLE: @@ -1002,7 +995,7 @@ function writeFirstSection() { handleMinMax(ranges.x, xRange); handleMinMax(ranges.y, yRange); handleMinMax(ranges.z, zRange); - if (is3D() && properties.commentWriteTools) { + if (is3D()) { if (toolZRanges[tool.number]) { toolZRanges[tool.number].expandToRange(zRange); } else { @@ -1011,53 +1004,55 @@ function writeFirstSection() { } } - writeComment(" "); - writeComment(" Ranges table:"); - writeComment(" X: Min=" + xyzFormat.format(ranges.x.min) + " Max=" + xyzFormat.format(ranges.x.max) + " Size=" + xyzFormat.format(ranges.x.max - ranges.x.min)); - writeComment(" Y: Min=" + xyzFormat.format(ranges.y.min) + " Max=" + xyzFormat.format(ranges.y.max) + " Size=" + xyzFormat.format(ranges.y.max - ranges.y.min)); - writeComment(" Z: Min=" + xyzFormat.format(ranges.z.min) + " Max=" + xyzFormat.format(ranges.z.max) + " Size=" + xyzFormat.format(ranges.z.max - ranges.z.min)); - - if (properties.commentWriteTools) { - writeComment(" "); - writeComment(" Tools table:"); - var tools = getToolTable(); - if (tools.getNumberOfTools() > 0) { - for (var i = 0; i < tools.getNumberOfTools(); ++i) { - var tool = tools.getTool(i); - var comment = " T" + toolFormat.format(tool.number) + " D=" + xyzFormat.format(tool.diameter) + " CR=" + xyzFormat.format(tool.cornerRadius); - if ((tool.taperAngle > 0) && (tool.taperAngle < Math.PI)) { - comment += " TAPER=" + taperFormat.format(tool.taperAngle) + "deg"; - } - if (toolZRanges[tool.number]) { - comment += " - ZMIN=" + xyzFormat.format(toolZRanges[tool.number].getMinimum()); - } - comment += " - " + getToolTypeName(tool.type) + " " + tool.comment; - writeComment(comment); + writeComment(eComment.Info, " "); + writeComment(eComment.Info, " Ranges table:"); + writeComment(eComment.Info, " X: Min=" + xyzFormat.format(ranges.x.min) + " Max=" + xyzFormat.format(ranges.x.max) + " Size=" + xyzFormat.format(ranges.x.max - ranges.x.min)); + writeComment(eComment.Info, " Y: Min=" + xyzFormat.format(ranges.y.min) + " Max=" + xyzFormat.format(ranges.y.max) + " Size=" + xyzFormat.format(ranges.y.max - ranges.y.min)); + writeComment(eComment.Info, " Z: Min=" + xyzFormat.format(ranges.z.min) + " Max=" + xyzFormat.format(ranges.z.max) + " Size=" + xyzFormat.format(ranges.z.max - ranges.z.min)); + + writeComment(eComment.Info, " "); + writeComment(eComment.Info, " Tools table:"); + var tools = getToolTable(); + if (tools.getNumberOfTools() > 0) { + for (var i = 0; i < tools.getNumberOfTools(); ++i) { + var tool = tools.getTool(i); + var comment = " T" + toolFormat.format(tool.number) + " D=" + xyzFormat.format(tool.diameter) + " CR=" + xyzFormat.format(tool.cornerRadius); + if ((tool.taperAngle > 0) && (tool.taperAngle < Math.PI)) { + comment += " TAPER=" + taperFormat.format(tool.taperAngle) + "deg"; + } + if (toolZRanges[tool.number]) { + comment += " - ZMIN=" + xyzFormat.format(toolZRanges[tool.number].getMinimum()); } + comment += " - " + getToolTypeName(tool.type) + " " + tool.comment; + writeComment(eComment.Info, comment); } } - writeln(""); - writeActivityComment(" *** START begin ***"); + writeComment(eComment.Info, " "); + + writeComment(eComment.Important, " *** START begin ***"); if (properties.gcodeStartFile == "") { Start(); } else { loadFile(properties.gcodeStartFile); } - writeActivityComment(" *** START end ***"); - writeln(""); + + writeComment(eComment.Important, " *** START end ***"); + writeComment(eComment.Important, " "); } // Output a comment -function writeComment(text) { - let fw = properties.jobSelectedFirmware; +function writeComment(level, text) { + if (level <= properties.jobCommentLevel) { + let fw = properties.jobSelectedFirmware; - if (fw == eFirmware.GRBL) { - writeln("(" + String(text).replace(/[\(\)]/g, "") + ")"); - } - else { - writeln(";" + String(text).replace(/[\(\)]/g, "")); + if (fw == eFirmware.GRBL) { + writeln("(" + String(text).replace(/[\(\)]/g, "") + ")"); + } + else { + writeln(";" + String(text).replace(/[\(\)]/g, "")); + } } } @@ -1202,13 +1197,12 @@ function loadFile(_file) { if (FileSystem.isFile(folder + _file)) { var txt = loadText(folder + _file, "utf-8"); if (txt.length > 0) { - writeActivityComment(" --- Start custom gcode " + folder + _file); + writeComment(eComment.Info, " --- Start custom gcode " + folder + _file); write(txt); - writeActivityComment(" --- End custom gcode " + folder + _file); - writeln(""); + writeComment("eComment.Info, --- End custom gcode " + folder + _file); } } else { - writeComment(" Can't open file " + folder + _file); + writeComment(eComment.Important, " Can't open file " + folder + _file); error("Can't open file " + folder + _file); } } @@ -1233,13 +1227,13 @@ function setCoolant(coolant) { // F360 allows only 1 coolant to be defined on an operation. If a coolant channel // is active then disable it before we switch to the other if (coolantChannelA != 0) { - writeActivityComment(" >>> Coolant Channel A: off"); + writeComment((coolant == 0) ? eComment.Important: eComment.Info, " >>> Coolant Channel A: off"); coolantChannelA = 0; CoolantA(false); } if (coolantChannelB != 0) { - writeActivityComment(" >>> Coolant Channel B: off"); + writeComment((coolant == 0) ? eComment.Important: eComment.Info, " >>> Coolant Channel B: off"); coolantChannelB = 0; CoolantB(false); } @@ -1249,17 +1243,17 @@ function setCoolant(coolant) { // issue an warning if (coolant != 0) { if (properties.cl0_coolantA_Mode == coolant) { - writeActivityComment(" >>> Coolant Channel A: " + propertyDefinitions.cl0_coolantA_Mode.values[coolant].title); + writeComment(eComment.Important, " >>> Coolant Channel A: " + propertyDefinitions.cl0_coolantA_Mode.values[coolant].title); coolantChannelA = coolant; CoolantA(true); } else if (properties.cl1_coolantB_Mode == coolant) { - writeActivityComment(" >>> Coolant Channel B: " + propertyDefinitions.cl1_coolantB_Mode.values[coolant].title); + writeComment(eComment.Important, " >>> Coolant Channel B: " + propertyDefinitions.cl1_coolantB_Mode.values[coolant].title); coolantChannelB = coolant; CoolantB(true); } else { - writeActivityComment(" >>> Coolant Channels, none set for: " + coolant); + writeComment(eComment.Important, " >>> WARNING: Coolant Channels, none set for: " + coolant); } } } @@ -1268,12 +1262,6 @@ function propertyMmToUnit(_v) { return (_v / (unit == IN ? 25.4 : 1)); } -function writeActivityComment(_comment) { - if (properties.commentActivities) { - writeComment(_comment); - } -} - /* function mergeProperties(to, from) { for (var attrname in from) { @@ -1303,11 +1291,11 @@ function Start() { // Default else { - writeComment(" Set Absolute Positioning"); - writeComment(" Units = " + (unit == IN ? "inch" : "mm")); - writeComment(" Disable stepper timeout"); + writeComment(eComment.Info, " Set Absolute Positioning"); + writeComment(eComment.Info, " Units = " + (unit == IN ? "inch" : "mm")); + writeComment(eComment.Info, " Disable stepper timeout"); if (properties.jobSetOriginOnStart) { - writeComment(" Set current position = 0,0,0"); + writeComment(eComment.Info, " Set current position = 0,0,0"); } writeBlock(gAbsIncModal.format(90)); // Set to Absolute Positioning @@ -1343,7 +1331,7 @@ function spindleOn(_spindleSpeed, _clockwise) { // Is Grbl? if (fw == eFirmware.GRBL) { - writeActivityComment(" >>> Spindle Speed " + speedFormat.format(_spindleSpeed)); + writeComment(eComment.Important, " >>> Spindle Speed " + speedFormat.format(_spindleSpeed)); writeBlock(mFormat.format(_clockwise ? 3 : 4), sOutput.format(spindleSpeed)); } @@ -1352,10 +1340,11 @@ function spindleOn(_spindleSpeed, _clockwise) { if (properties.jobManualSpindlePowerControl) { // for manual any positive input speed assumed as enabled. so it's just a flag if (!this.spindleEnabled) { + writeComment(eComment.Important, " >>> Spindle Speed: Manual"); askUser("Turn ON " + speedFormat.format(_spindleSpeed) + "RPM", "Spindle", false); } } else { - writeActivityComment(" >>> Spindle Speed " + speedFormat.format(_spindleSpeed)); + writeComment(eComment.Important, " >>> Spindle Speed " + speedFormat.format(_spindleSpeed)); writeBlock(mFormat.format(_clockwise ? 3 : 4), sOutput.format(spindleSpeed)); } this.spindleEnabled = true; @@ -1589,13 +1578,14 @@ function probeTool() { // Default else { - writeComment(" Ask User to Attach the Z Probe"); - writeComment(" Probe"); - writeComment(" Set Z to probe thickness: " + zFormat.format(propertyMmToUnit(properties.probeThickness))) + writeComment(eComment.Important, " Probe to Zero Z"); + writeComment(eComment.Info, " Ask User to Attach the Z Probe"); + writeComment(eComment.Info, " Do Probing"); + writeComment(eComment.Info, " Set Z to probe thickness: " + zFormat.format(propertyMmToUnit(properties.probeThickness))) if (properties.toolChangeZ != "") { - writeComment(" Retract the tool to " + propertyMmToUnit(properties.toolChangeZ)); + writeComment(eComment.Info, " Retract the tool to " + propertyMmToUnit(properties.toolChangeZ)); } - writeComment(" Ask User to Remove the Z Probe"); + writeComment(eComment.Info, " Ask User to Remove the Z Probe"); askUser("Attach ZProbe", "Probe", false); // refer http://marlinfw.org/docs/gcode/G038.html From e892791368e35e78ef4a09e6069f3e404f921db2 Mon Sep 17 00:00:00 2001 From: flyfisher604 Date: Fri, 5 Feb 2021 11:45:46 -0800 Subject: [PATCH 08/24] closes #4 --- MPCNC.cps | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MPCNC.cps b/MPCNC.cps index 5d3b9ef..2c43c64 100644 --- a/MPCNC.cps +++ b/MPCNC.cps @@ -42,7 +42,7 @@ function flushMotions() { } } -// Coolant +// Output the On or Off property that corresponds to either channel A or B function CoolantA(on) { writeBlock(on ? properties.cl2_coolantAOn : properties.cl3_coolantAOff); } From e6174a5b7da04865176dc2afe4184dad1e6ead50 Mon Sep 17 00:00:00 2001 From: flyfisher604 Date: Fri, 5 Feb 2021 12:53:09 -0800 Subject: [PATCH 09/24] reorg --- MPCNC.cps | 138 ++++++++++++++++++++---------------------------------- 1 file changed, 52 insertions(+), 86 deletions(-) diff --git a/MPCNC.cps b/MPCNC.cps index 91deb29..144099e 100644 --- a/MPCNC.cps +++ b/MPCNC.cps @@ -6,9 +6,17 @@ MPCNC posts processor for milling and laser/plasma cutting. */ -//--------------------- Refactored Firmware ---------------------- - description = "MPCNC Milling/Laser - Marlin 2.0, Grbl 1.1, RepRap"; +vendor = "flyfisher604"; +vendorUrl = "https://github.com/flyfisher604/mpcnc_post_processor"; + +// Internal properties +certificationLevel = 2; +extension = "gcode"; +setCodePage("ascii"); +capabilities = CAPABILITY_MILLING | CAPABILITY_JET; + +machineMode = undefined; //TYPE_MILLING, TYPE_JET var eFirmware = { MARLIN: 0, @@ -36,56 +44,6 @@ var eComment = { } }; -machineMode = undefined; //TYPE_MILLING, TYPE_JET - -/* -mergeProperties(properties, properties3dPrinter); -mergeProperties(propertyDefinitions, propertyDefinitions3dPrinter); -*/ - -function flushMotions() { - let fw = properties.jobSelectedFirmware; - - if (fw == eFirmware.GRBL) { - } - - // Default - else { - writeBlock(mFormat.format(400)); - } -} - -// Output the On or Off property that corresponds to either channel A or B -function CoolantA(on) { - writeBlock(on ? properties.cl2_coolantAOn : properties.cl3_coolantAOff); -} - -function CoolantB(on) { - writeBlock(on ? properties.cl4_coolantBOn : properties.cl5_coolantBOff); -} - - -//--------------------- Common ---------------------- - -/* - -https://github.com/flyfisher604/mpcnc_post_processor - -MPCNC posts processor for milling and laser/plasma cutting. - -*/ - -// Internal properties -certificationLevel = 2; -extension = "gcode"; -setCodePage("ascii"); -capabilities = CAPABILITY_MILLING | CAPABILITY_JET; - -// vendor of MPCNC -vendor = "flyfisher604"; -vendorUrl = "https://github.com/flyfisher604/mpcnc_post_processor"; - - // user-defined properties properties = { jobSelectedFirmware : firmware, // Firmware to use in special cases @@ -244,7 +202,6 @@ propertyDefinitions = { type: "spatial", default_mm: 1000, default_in: 39.37 }, - mapD_RestoreFirstRapids: { title: "Map: First G1 -> G0 Rapids", description: "Convert first G1 of a cut to G0 Rapids", group: 3, type: "boolean", default_mm: false, default_in: false @@ -262,7 +219,6 @@ propertyDefinitions = { type: "boolean", default_mm: true, default_in: true }, - toolChangeEnabled: { title: "Change: Enabled", description: "Enable tool change code (bultin tool change requires LCD display)", group: 4, type: "boolean", default_mm: true, default_in: true @@ -352,28 +308,7 @@ propertyDefinitions = { type: "file", default_mm: "", default_in: "" }, - - DuetMillingMode: { - title: "Duet: Milling mode", description: "GCode command to setup Duet3d milling mode", group: 10, - type: "string", default_mm: "M453 P2 I0 R30000 F200", default_in: "M453 P2 I0 R30000 F200" - }, - DuetLaserMode: { - title: "Duet: Laser mode", description: "GCode command to setup Duet3d laser mode", group: 10, - type: "string", default_mm: "M452 P2 I0 R255 F200", default_in: "M452 P2 I0 R255 F200" - }, - - - GrblCutterMode: { - title: "GRBL: Laser mode", description: "GRBL mode of the laser/plasma cutter", group: 11, - type: "integer", default_mm: 4, default_in: 4, - values: [ - { title: "M4 S{PWM}/M5 dynamic power", id: 4 }, - { title: "M3 S{PWM}/M5 static power", id: 3 }, - ] - }, - // Coolant - cl0_coolantA_Mode: { title: "Coolant: A Mode", description: "Enable channel A when tool is set this coolant", group: 8, type: "integer", default_mm: 0, default_in: 0, @@ -442,17 +377,27 @@ propertyDefinitions = { { title: "Grbl: M9 (off)", id: "M9" } ] }, -}; -/* - -https://github.com/guffy1234/mpcnc_posts_processor - -MPCNC posts processor for milling and laser/plasma cutting. - -*/ + DuetMillingMode: { + title: "Duet: Milling mode", description: "GCode command to setup Duet3d milling mode", group: 9, + type: "string", default_mm: "M453 P2 I0 R30000 F200", default_in: "M453 P2 I0 R30000 F200" + }, + DuetLaserMode: { + title: "Duet: Laser mode", description: "GCode command to setup Duet3d laser mode", group: 9, + type: "string", default_mm: "M452 P2 I0 R255 F200", default_in: "M452 P2 I0 R255 F200" + }, + GrblCutterMode: { + title: "GRBL: Laser mode", description: "GRBL mode of the laser/plasma cutter", group: 9, + type: "integer", default_mm: 4, default_in: 4, + values: [ + { title: "M4 S{PWM}/M5 dynamic power", id: 4 }, + { title: "M3 S{PWM}/M5 static power", id: 3 }, + ] + }, +}; var sequenceNumber; +var currentFirmware; // Formats var gFormat = createFormat({ prefix: "G", decimals: 1 }); @@ -519,7 +464,26 @@ function writeBlock() { } } -var currentFirmware; +function flushMotions() { + let fw = properties.jobSelectedFirmware; + + if (fw == eFirmware.GRBL) { + } + + // Default + else { + writeBlock(mFormat.format(400)); + } +} + +// Coolant +function CoolantA(on) { + writeBlock(on ? properties.cl2_coolantAOn : properties.cl3_coolantAOff); +} + +function CoolantB(on) { + writeBlock(on ? properties.cl4_coolantBOn : properties.cl5_coolantBOff); +} // Called in every new gcode file function onOpen() { @@ -1028,7 +992,7 @@ function writeFirstSection() { } } - writeComment(eComment.Info, " "); + writeComment(eComment.Info, " "); writeComment(eComment.Important, " *** START begin ***"); @@ -1311,6 +1275,7 @@ function Start() { } } } + function end() { let fw = properties.jobSelectedFirmware; @@ -1325,7 +1290,6 @@ function end() { } } - function spindleOn(_spindleSpeed, _clockwise) { let fw = properties.jobSelectedFirmware; @@ -1350,6 +1314,7 @@ function spindleOn(_spindleSpeed, _clockwise) { this.spindleEnabled = true; } } + function spindleOff() { let fw = properties.jobSelectedFirmware; @@ -1574,6 +1539,7 @@ function probeTool() { // Is Grbl? if (fw == eFirmware.GRBL) { + writeComment(eComment.Important, " >>> WARNING: No probing implemented for GRBL"); } // Default From 98ce0a2c37ea15051b4ed8c2a30784339dd275c2 Mon Sep 17 00:00:00 2001 From: flyfisher604 Date: Fri, 5 Feb 2021 13:11:06 -0800 Subject: [PATCH 10/24] Created global fw variable --- MPCNC.cps | 41 ++++------------------------------------- 1 file changed, 4 insertions(+), 37 deletions(-) diff --git a/MPCNC.cps b/MPCNC.cps index 144099e..6aaa5dd 100644 --- a/MPCNC.cps +++ b/MPCNC.cps @@ -29,7 +29,7 @@ var eFirmware = { } }; -var firmware = eFirmware.MARLIN; +var fw = eFirmware.MARLIN; var eComment = { Off: 0, @@ -46,7 +46,7 @@ var eComment = { // user-defined properties properties = { - jobSelectedFirmware : firmware, // Firmware to use in special cases + jobSelectedFirmware : fw, // Firmware to use in special cases jobManualSpindlePowerControl: true, // Spindle motor is controlled by manual switch @@ -397,7 +397,6 @@ propertyDefinitions = { }; var sequenceNumber; -var currentFirmware; // Formats var gFormat = createFormat({ prefix: "G", decimals: 1 }); @@ -465,8 +464,6 @@ function writeBlock() { } function flushMotions() { - let fw = properties.jobSelectedFirmware; - if (fw == eFirmware.GRBL) { } @@ -487,7 +484,7 @@ function CoolantB(on) { // Called in every new gcode file function onOpen() { - let fw = properties.jobSelectedFirmware; + fw = properties.jobSelectedFirmware; if (fw == eFirmware.GRBL) { gMotionModal = createModal({}, gFormat); // modal group 1 // G0-G3, ... @@ -509,8 +506,6 @@ function onOpen() { // Called at end of gcode file function onClose() { - let fw = properties.jobSelectedFirmware; - writeComment(eComment.Important, " *** STOP begin ***"); flushMotions(); @@ -538,8 +533,6 @@ var cutterOnCurrentPower; var forceSectionToStartWithRapid = false; function onSection() { - let fw = properties.jobSelectedFirmware; - // Every section needs to start with a Rapid to get to the initial location. // In the hobby version Rapids have been elliminated and the first command is // a onLinear not a onRapid command. This results in not current position being @@ -762,8 +755,6 @@ function onPower(power) { // Called on Dwell Manual NC invocation function onDwell(seconds) { - let fw = properties.jobSelectedFirmware; - writeComment(eComment.Important, " >>> Dwell"); if (seconds > 99999.999) { warning(localize("Dwelling time is out of range.")); @@ -1009,8 +1000,6 @@ function writeFirstSection() { // Output a comment function writeComment(level, text) { if (level <= properties.jobCommentLevel) { - let fw = properties.jobSelectedFirmware; - if (fw == eFirmware.GRBL) { writeln("(" + String(text).replace(/[\(\)]/g, "") + ")"); } @@ -1178,8 +1167,6 @@ var coolantChannelA = 0; var coolantChannelB = 0; function setCoolant(coolant) { - let fw = properties.jobSelectedFirmware; - // As long as we are not disabling coolant (= 0), then if either of the coolant // channels are already operating in the mode requested then there is // nothing to do @@ -1243,8 +1230,6 @@ Firmware3dPrinterLike.prototype.constructor = Firmware3dPrinterLike; */ function Start() { - let fw = properties.jobSelectedFirmware; - // Is Grbl? if (fw == eFirmware.GRBL) { writeBlock(gAbsIncModal.format(90)); // Set to Absolute Positioning @@ -1277,8 +1262,6 @@ function Start() { } function end() { - let fw = properties.jobSelectedFirmware; - // Is Grbl? if (fw == eFirmware.GRBL) { writeBlock(mFormat.format(30)); @@ -1291,8 +1274,6 @@ function end() { } function spindleOn(_spindleSpeed, _clockwise) { - let fw = properties.jobSelectedFirmware; - // Is Grbl? if (fw == eFirmware.GRBL) { writeComment(eComment.Important, " >>> Spindle Speed " + speedFormat.format(_spindleSpeed)); @@ -1316,8 +1297,6 @@ function spindleOn(_spindleSpeed, _clockwise) { } function spindleOff() { - let fw = properties.jobSelectedFirmware; - // Is Grbl? if (fw == eFirmware.GRBL) { writeBlock(mFormat.format(5)); @@ -1336,7 +1315,6 @@ function spindleOff() { } function laserOn(power) { - let fw = properties.jobSelectedFirmware; var laser_pwm = power / 100 * 255; // Firmware is Grbl @@ -1351,7 +1329,7 @@ function laserOn(power) { writeBlock(mFormat.format(106), sFormat.format(laser_pwm)); break; case 3: - if (fw = eFirmware.REPRAP) { + if (fw == eFirmware.REPRAP) { writeBlock(mFormat.format(3), sFormat.format(laser_pwm)); } else { writeBlock(mFormat.format(3), oFormat.format(laser_pwm)); @@ -1365,8 +1343,6 @@ function laserOn(power) { } function laserOff() { - let fw = properties.jobSelectedFirmware; - // Firmware is Grbl if (fw == eFirmware.GRBL) { writeBlock(mFormat.format(5)); @@ -1389,8 +1365,6 @@ function laserOff() { } function display_text(txt) { - let fw = properties.jobSelectedFirmware; - // Firmware is Grbl if (fw == eFirmware.GRBL) { // Don't display text @@ -1409,7 +1383,6 @@ function circular(clockwise, cx, cy, cz, x, y, z, feed) { } var start = getCurrentPosition(); - let fw = properties.jobSelectedFirmware; // Firmware is Grbl if (fw == eFirmware.GRBL) { @@ -1476,8 +1449,6 @@ function circular(clockwise, cx, cy, cz, x, y, z, feed) { } function askUser(text, title, allowJog) { - let fw = properties.jobSelectedFirmware; - // Firmware is RepRap? if (fw == eFirmware.REPRAP) { var v1 = " P\"" + text + "\" R\"" + title + "\" S3"; @@ -1492,8 +1463,6 @@ function askUser(text, title, allowJog) { } function toolChange() { - let fw = properties.jobSelectedFirmware; - // Grbl tool change? if (fw == eFirmware.GRBL) { @@ -1535,8 +1504,6 @@ function toolChange() { } function probeTool() { - let fw = properties.jobSelectedFirmware; - // Is Grbl? if (fw == eFirmware.GRBL) { writeComment(eComment.Important, " >>> WARNING: No probing implemented for GRBL"); From 60c0c7958cdf2a7b0998a09bc5d9602a1bb778ce Mon Sep 17 00:00:00 2001 From: flyfisher604 Date: Fri, 5 Feb 2021 15:47:31 -0800 Subject: [PATCH 11/24] Parameter reordering --- MPCNC.cps | 319 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 168 insertions(+), 151 deletions(-) diff --git a/MPCNC.cps b/MPCNC.cps index 6aaa5dd..4322740 100644 --- a/MPCNC.cps +++ b/MPCNC.cps @@ -46,24 +46,20 @@ var eComment = { // user-defined properties properties = { - jobSelectedFirmware : fw, // Firmware to use in special cases - - jobManualSpindlePowerControl: true, // Spindle motor is controlled by manual switch - - jobUseArcs: true, // Produce G2/G3 for arcs - - jobSetOriginOnStart: true, // Set origin when gcode start (G92) - jobGoOriginOnFinish: true, // Go X0 Y0 Z0 at gcode end - - jobSequenceNumbers: false, // show sequence numbers - jobSequenceNumberStart: 10, // first sequence number - jobSequenceNumberIncrement: 1, // increment for sequence numbers - jobSeparateWordsWithSpace: true, // specifies that the words should be separated with a white space - jobCommentLevel: eComment.Info, // The level of comments included + job0_SelectedFirmware : fw, // Firmware to use in special cases + job1_SetOriginOnStart: true, // Set current position as 0,0,0 on start (G92) + job2_ManualSpindlePowerControl: true, // Spindle motor is controlled by manual switch + job3_CommentLevel: eComment.Info, // The level of comments included + job4_UseArcs: true, // Produce G2/G3 for arcs + job5_SequenceNumbers: false, // show sequence numbers + job6_SequenceNumberStart: 10, // first sequence number + job7_SequenceNumberIncrement: 1, // increment for sequence numbers + job8_SeparateWordsWithSpace: true, // specifies that the words should be separated with a white space + job9_GoOriginOnFinish: true, // Go X0 Y0 current Z at end fr0_TravelSpeedXY: 2500, // High speed for travel movements X & Y (mm/min) fr1_TravelSpeedZ: 300, // High speed for travel movements Z (mm/min) - fr2_EnforceFeedrate: false, // Add feedrate to each movement line + fr2_EnforceFeedrate: true, // Add feedrate to each movement line frA_ScaleFeedrate: false, // Will feedrated be scaled frB_MaxCutSpeedXY: 900, // Max speed for cut movements X & Y (mm/min) frC_MaxCutSpeedZ: 180, // Max speed for cut movements Z (mm/min) @@ -71,21 +67,21 @@ properties = { mapD_RestoreFirstRapids: false, // Map first G01 --> G00 mapE_RestoreRapids: false, // Map G01 --> G00 for SafeTravelsAboveZ - mapF_SafeZ: 10, // G01 mapped to G00 if Z is >= jobSafeZRapid - mapG_AllowRapidZ: true, // Allow G01 --> G00 for vertical retracts and Z descents above safe - - toolChangeEnabled: true, // Enable tool change code (bultin tool change requires LCD display) - toolChangeX: 0, // X position for builtin tool change - toolChangeY: 0, // Y position for builtin tool change - toolChangeZ: 40, // Z position for builtin tool change - toolChangeZProbe: true, // Z probe after tool change - toolChangeDisableZStepper: false, // disable Z stepper when change a tool - - probeOnStart: true, // Execute probe gcode to align tool - probeThickness: 0.8, // plate thickness - probeUseHomeZ: true, // use G28 or G38 for probing - probeG38Target: -10, // probing up to pos - probeG38Speed: 30, // probing with speed + mapF_SafeZ: 5, // G01 mapped to G00 if Z is >= jobSafeZRapid + mapG_AllowRapidZ: false, // Allow G01 --> G00 for vertical retracts and Z descents above safe + + toolChange0_Enabled: false, // Enable tool change code (bultin tool change requires LCD display) + toolChange1_X: 0, // X position for builtin tool change + toolChange2_Y: 0, // Y position for builtin tool change + toolChange3_Z: 40, // Z position for builtin tool change + toolChange4_DisableZStepper: false, // disable Z stepper when change a tool + + probe1_OnStart: false, // Execute probe gcode to align tool + probe2_OnToolChange: false, // Z probe after tool change + probe3_Thickness: 0.8, // plate thickness + probe4_UseHomeZ: true, // use G28 or G38 for probing + probe5_G38Target: -10, // probing up to pos + probe6_G38Speed: 30, // probing with speed gcodeStartFile: "", // File with custom Gcode for header/start (in nc folder) gcodeStopFile: "", // File with custom Gcode for footer/end (in nc folder) @@ -97,7 +93,8 @@ properties = { cutterOnEtch: 40, // Persent of power to turn on the laser/plasma cutter in etch mode cutterMarlinMode: 106, // Marlin mode laser/plasma cutter cutterMarlinPin: 4, // Marlin laser/plasma cutter pin for M42 - + cutterGrblMode: 4, // GRBL mode laser/plasma cutter + cl0_coolantA_Mode: 0, // Enable issuing g-codes for control Coolant channel A cl1_coolantB_Mode: 0, // Use issuing g-codes for control Coolant channel B cl2_coolantAOn: "M42 P6 S255", // GCode command to turn on Coolant channel A @@ -108,13 +105,12 @@ properties = { DuetMillingMode: "M453 P2 I0 R30000 F200", // GCode command to setup Duet3d milling mode DuetLaserMode: "M452 P2 I0 R255 F200", // GCode command to setup Duet3d laser mode - GrblCutterMode: 4, // GRBL mode laser/plasma cutter }; propertyDefinitions = { - jobSelectedFirmware: { - title: "Job: Select CNC Firmware", description: "Control GCode create for specific firmware", group: 1, + job0_SelectedFirmware: { + title: "Job: CNC Firmware", description: "Dialect of GCode to create", group: 1, type: "integer", default_mm: 0, default_in: 0, values: [ { title: eFirmware.prop[eFirmware.MARLIN].name, id: eFirmware.MARLIN }, @@ -123,54 +119,47 @@ propertyDefinitions = { ] }, - jobManualSpindlePowerControl: { - title: "Job: Manual Spindle On/Off", description: "Set Yes when your spindle motor is controlled by manual switch", group: 1, + job1_SetOriginOnStart: { + title: "Job: Zero Starting Location (G92)", description: "On start set the current location as 0,0,0 (G92)", group: 1, type: "boolean", default_mm: true, default_in: true }, - jobUseArcs: { - title: "Job: Use Arcs", description: "Use G2/G3 g-codes fo circular movements", group: 1, + job2_ManualSpindlePowerControl: { + title: "Job: Manual Spindle On/Off", description: "Enable to manually turn spindle motor on/off", group: 1, type: "boolean", default_mm: true, default_in: true }, - - jobMarlinEnforcFeFeedrate: { - title: "Job: Marlin Enforce Feedrate", description: "Add feedrate to each movement g-code", group: 1, - type: "boolean", default_mm: false, default_in: false - }, - - jobSetOriginOnStart: { - title: "Job: Reset on start (G92)", description: "Set origin when gcode start (G92)", group: 1, - type: "boolean", default_mm: true, default_in: true + job3_CommentLevel: { + title: "Job: Comment Level", description: "Controls the comments include", group: 1, + type: "integer", default_mm: 3, default_in: 3, + values: [ + { title: eComment.prop[eComment.Off].name, id: eComment.Off }, + { title: eComment.prop[eComment.Important].name, id: eComment.Important }, + { title: eComment.prop[eComment.Info].name, id: eComment.Info }, + { title: eComment.prop[eComment.Debug].name, id: eComment.Debug }, + ] }, - jobGoOriginOnFinish: { - title: "Job: Goto 0, 0 at end", description: "Go X0 Y0 at gcode end", group: 1, + job4_UseArcs: { + title: "Job: Use Arcs", description: "Use G2/G3 g-codes fo circular movements", group: 1, type: "boolean", default_mm: true, default_in: true }, - - jobSequenceNumbers: { - title: "Job: Line numbers", description: "Show sequence numbers", group: 1, + job5_SequenceNumbers: { + title: "Job: Enable Line #s", description: "Show sequence numbers", group: 1, type: "boolean", default_mm: false, default_in: false }, - jobSequenceNumberStart: { - title: "Job: Line # start", description: "First sequence number", group: 1, + job6_SequenceNumberStart: { + title: "Job: First Line #", description: "First sequence number", group: 1, type: "integer", default_mm: 10, default_in: 10 }, - jobSequenceNumberIncrement: { - title: "Job: Line # increment", description: "Increment for sequence numbers", group: 1, + job7_SequenceNumberIncrement: { + title: "Job: Line # Increment", description: "Sequence number increment", group: 1, type: "integer", default_mm: 1, default_in: 1 }, - jobSeparateWordsWithSpace: { - title: "Job: Separate words", description: "Specifies that the words should be separated with a white space", group: 1, + job8_SeparateWordsWithSpace: { + title: "Job: Include Whitespace", description: "Includes whitespace seperation between text", group: 1, type: "boolean", default_mm: true, default_in: true }, - jobCommentLevel: { - title: "Job: Comment Level", description: "Controls the comments include", group: 1, - type: "integer", default_mm: 3, default_in: 3, - values: [ - { title: eComment.prop[eComment.Off].name, id: eComment.Off }, - { title: eComment.prop[eComment.Important].name, id: eComment.Important }, - { title: eComment.prop[eComment.Info].name, id: eComment.Info }, - { title: eComment.prop[eComment.Debug].name, id: eComment.Debug }, - ] + job9_GoOriginOnFinish: { + title: "Job: At end go to 0,0", description: "Go to X0 Y0 at gcode end, Z unchanged", group: 1, + type: "boolean", default_mm: true, default_in: true }, fr0_TravelSpeedXY: { @@ -183,85 +172,85 @@ propertyDefinitions = { }, fr2_EnforceFeedrate: { title: "Feed: Enforce Feedrate", description: "Add feedrate to each movement g-code", group: 2, - type: "boolean", default_mm: false, default_in: false + type: "boolean", default_mm: true, default_in: true }, frA_ScaleFeedrate: { - title: "Feed: Scale feedrate", description: "Scale feedrate based on X, Y, Z axis maximums", group: 2, + title: "Feed: Scale Feedrate", description: "Scale feedrate based on X, Y, Z axis maximums", group: 2, type: "boolean", default_mm: false, default_in: false }, frB_MaxCutSpeedXY: { - title: "Feed: Max cut speed X or Y", description: "Max X or Y axis cut speed (mm/min; in/min)", group: 2, + title: "Feed: Max XY Cut Speed", description: "Maximum X or Y axis cut speed (mm/min; in/min)", group: 2, type: "spatial", default_mm: 900, default_in: 35.43 }, frC_MaxCutSpeedZ: { - title: "Feed: Max cut speed Z", description: "Max Z axis cut speed (mm/min; in/min)", group: 2, + title: "Feed: Max Z Cut Speed", description: "Maximum Z axis cut speed (mm/min; in/min)", group: 2, type: "spatial", default_mm: 180, default_in: 7.08 }, frD_MaxCutSpeedXYZ: { - title: "Feed: Max toolpath speed", description: "After scaling limit feedrate to this (mm/min; in/min)", group: 2, + title: "Feed: Max Toolpath Speed", description: "Maximum scaled feedrate (mm/min; in/min)", group: 2, type: "spatial", default_mm: 1000, default_in: 39.37 }, mapD_RestoreFirstRapids: { - title: "Map: First G1 -> G0 Rapids", description: "Convert first G1 of a cut to G0 Rapids", group: 3, + title: "Map: First G1 -> G0 Rapid", description: "Ensure move to start of a cut is with a G0 Rapid", group: 3, type: "boolean", default_mm: false, default_in: false }, mapE_RestoreRapids: { - title: "Map: G1 -> G0 Rapids", description: "When safe, convert G1s to G0 Rapids", group: 3, + title: "Map: G1s -> G0 Rapids", description: "Enable to convert G1s to G0 Rapids when safe", group: 3, type: "boolean", default_mm: false, default_in: false }, mapF_SafeZ: { - title: "Map: Safe Z for Rapids", description: "Z must be above or equal to this to map G01 --> G00", group: 3, + title: "Map: Safe Z to Rapid", description: "Must be above or equal to this value to map G1s --> G0s", group: 3, type: "integer", default_mm: 10, default_in: 0.590551 }, mapG_AllowRapidZ: { - title: "Map: Allow Rapid Z", description: "If G01 to Rapids allowed, then include vertical retracts and safe descents", group: 3, + title: "Map: Allow Rapid Z", description: "Enable to include vertical retracts and safe descents", group: 3, type: "boolean", default_mm: true, default_in: true }, - toolChangeEnabled: { - title: "Change: Enabled", description: "Enable tool change code (bultin tool change requires LCD display)", group: 4, - type: "boolean", default_mm: true, default_in: true + toolChange0_Enabled: { + title: "Tool Change: Enable", description: "Include tool change code when tool changes (bultin tool change requires LCD display)", group: 4, + type: "boolean", default_mm: false, default_in: false }, - toolChangeX: { - title: "Change: X", description: "X position for builtin tool change", group: 4, + toolChange1_X: { + title: "Tool Change: X", description: "X location for tool change", group: 4, type: "spatial", default_mm: 0, default_in: 0 }, - toolChangeY: { - title: "Change: Y", description: "Y position for builtin tool change", group: 4, + toolChange2_Y: { + title: "Tool Change: Y", description: "Y location for tool change", group: 4, type: "spatial", default_mm: 0, default_in: 0 }, - toolChangeZ: { - title: "Change: Z ", description: "Z position for builtin tool change", group: 4, + toolChange3_Z: { + title: "Tool Change: Z ", description: "Z location for tool change", group: 4, type: "spatial", default_mm: 40, default_in: 1.6 }, - toolChangeZProbe: { - title: "Change: Make Z Probe", description: "Z probe after tool change", group: 4, - type: "boolean", default_mm: true, default_in: true - }, - toolChangeDisableZStepper: { - title: "Change: Disable Z stepper", description: "Disable Z stepper when change a tool", group: 4, + toolChange4_DisableZStepper: { + title: "Tool Change: Disable Z stepper", description: "Disable Z stepper after reaching tool change location", group: 4, type: "boolean", default_mm: false, default_in: false }, - - probeOnStart: { + + probe1_OnStart: { title: "Probe: On job start", description: "Execute probe gcode on job start", group: 5, - type: "boolean", default_mm: true, default_in: true + type: "boolean", default_mm: false, default_in: false + }, + probe2_OnToolChange: { + title: "Probe: Afterward Tool Change", description: "After tool change, probe Z at the current location", group: 5, + type: "boolean", default_mm: false, default_in: false }, - probeThickness: { + probe3_Thickness: { title: "Probe: Plate thickness", description: "Plate thickness", group: 5, type: "spatial", default_mm: 0.8, default_in: 0.032 }, - probeUseHomeZ: { - title: "Probe: Use Home Z", description: "Use G28 or G38 for probing", group: 5, + probe4_UseHomeZ: { + title: "Probe: Use Home Z (G28)", description: "Probe with G28 (Yes) or G38 (No)", group: 5, type: "boolean", default_mm: true, default_in: true }, - probeG38Target: { - title: "Probe: G38 target", description: "Probing up to Z position", group: 5, + probe5_G38Target: { + title: "Probe: G38 target", description: "Probing's furthest Z position", group: 5, type: "spatial", default_mm: -10, default_in: -0.5 }, - probeG38Speed: { - title: "Probe: G38 speed", description: "Probing with speed (mm/min; in/min)", group: 5, + probe6_G38Speed: { + title: "Probe: G38 speed", description: "Probing's speed (mm/min; in/min)", group: 5, type: "spatial", default_mm: 30, default_in: 1.2 }, @@ -278,18 +267,27 @@ propertyDefinitions = { type: "number", default_mm: 40, default_in: 40 }, cutterMarlinMode: { - title: "Laser: Marlin/Reprap mode", description: "Marlin/Reprar mode of the laser/plasma cutter", group: 6, + title: "Laser: Marlin/Reprap mode", description: "Marlin/Reprap mode of the laser/plasma cutter", group: 6, type: "integer", default_mm: 106, default_in: 106, values: [ - { title: "M106 S{PWM}/M107", id: 106 }, - { title: "M3 O{PWM}/M5", id: 3 }, - { title: "M42 P{pin} S{PWM}", id: 42 }, + { title: "Fan - M106 S{PWM}/M107", id: 106 }, + { title: "Spindle - M3 O{PWM}/M5", id: 3 }, + { title: "Pin - M42 P{pin} S{PWM}", id: 42 }, ] }, cutterMarlinPin: { title: "Laser: Marlin M42 pin", description: "Marlin custom pin number for the laser/plasma cutter", group: 6, type: "integer", default_mm: 4, default_in: 4 }, + cutterGrblMode: { + title: "Laser: GRBL mode", description: "GRBL mode of the laser/plasma cutter", group: 6, + type: "integer", default_mm: 4, default_in: 4, + values: [ + { title: "M4 S{PWM}/M5 dynamic power", id: 4 }, + { title: "M3 S{PWM}/M5 static power", id: 3 }, + ] + }, + gcodeStartFile: { title: "Extern: Start File", description: "File with custom Gcode for header/start (in nc folder)", group: 7, @@ -386,14 +384,6 @@ propertyDefinitions = { title: "Duet: Laser mode", description: "GCode command to setup Duet3d laser mode", group: 9, type: "string", default_mm: "M452 P2 I0 R255 F200", default_in: "M452 P2 I0 R255 F200" }, - GrblCutterMode: { - title: "GRBL: Laser mode", description: "GRBL mode of the laser/plasma cutter", group: 9, - type: "integer", default_mm: 4, default_in: 4, - values: [ - { title: "M4 S{PWM}/M5 dynamic power", id: 4 }, - { title: "M3 S{PWM}/M5 static power", id: 3 }, - ] - }, }; var sequenceNumber; @@ -455,9 +445,9 @@ allowedCircularPlanes = undefined; // Writes the specified block. function writeBlock() { - if (properties.jobSequenceNumbers) { + if (properties.job5_SequenceNumbers) { writeWords2("N" + sequenceNumber, arguments); - sequenceNumber += properties.jobSequenceNumberIncrement; + sequenceNumber += properties.job7_SequenceNumberIncrement; } else { writeWords(arguments); } @@ -484,7 +474,7 @@ function CoolantB(on) { // Called in every new gcode file function onOpen() { - fw = properties.jobSelectedFirmware; + fw = properties.job0_SelectedFirmware; if (fw == eFirmware.GRBL) { gMotionModal = createModal({}, gFormat); // modal group 1 // G0-G3, ... @@ -498,8 +488,8 @@ function onOpen() { fOutput = createVariable({ force: true }, fFormat); } - sequenceNumber = properties.jobSequenceNumberStart; - if (!properties.jobSeparateWordsWithSpace) { + sequenceNumber = properties.job6_SequenceNumberStart; + if (!properties.job8_SeparateWordsWithSpace) { setWordSeparator(""); } } @@ -512,7 +502,7 @@ function onClose() { if (properties.gcodeStopFile == "") { onCommand(COMMAND_COOLANT_OFF); - if (properties.jobGoOriginOnFinish) { + if (properties.job9_GoOriginOnFinish) { rapidMovementsXY(0, 0); } onCommand(COMMAND_STOP_SPINDLE); @@ -552,7 +542,7 @@ function onSection() { // Do a tool change if tool changes are enabled and its not the first section and this section uses // a different tool then the previous section - if (properties.toolChangeEnabled && !isFirstSection() && tool.number != getPreviousSection().getTool().number) { + if (properties.toolChange0_Enabled && !isFirstSection() && tool.number != getPreviousSection().getTool().number) { if (properties.gcodeToolFile == "") { // Post Processor does the tool change @@ -630,7 +620,7 @@ function resetAll() { function onSectionEnd() { resetAll(); writeComment(eComment.Important, " *** SECTION end ***"); - writeln(""); + writeComment(eComment.Important, ""); } function onComment(message) { @@ -919,8 +909,8 @@ function onCommand(command) { } } -function writeFirstSection() { - // dump tool information +function writeInformation() { + // Calcualte the min/max ranges across all sections var toolZRanges = {}; var vectorX = new Vector(1, 0, 0); var vectorY = new Vector(0, 1, 0); @@ -959,14 +949,16 @@ function writeFirstSection() { } } + // Display the Range Table writeComment(eComment.Info, " "); - writeComment(eComment.Info, " Ranges table:"); + writeComment(eComment.Info, " Ranges Table:"); writeComment(eComment.Info, " X: Min=" + xyzFormat.format(ranges.x.min) + " Max=" + xyzFormat.format(ranges.x.max) + " Size=" + xyzFormat.format(ranges.x.max - ranges.x.min)); writeComment(eComment.Info, " Y: Min=" + xyzFormat.format(ranges.y.min) + " Max=" + xyzFormat.format(ranges.y.max) + " Size=" + xyzFormat.format(ranges.y.max - ranges.y.min)); writeComment(eComment.Info, " Z: Min=" + xyzFormat.format(ranges.z.min) + " Max=" + xyzFormat.format(ranges.z.max) + " Size=" + xyzFormat.format(ranges.z.max - ranges.z.min)); + // Display the Tools Table writeComment(eComment.Info, " "); - writeComment(eComment.Info, " Tools table:"); + writeComment(eComment.Info, " Tools Table:"); var tools = getToolTable(); if (tools.getNumberOfTools() > 0) { for (var i = 0; i < tools.getNumberOfTools(); ++i) { @@ -983,7 +975,31 @@ function writeFirstSection() { } } + // Display the Feedrate and Scaling Properties + writeComment(eComment.Info, " "); + writeComment(eComment.Info, " Feedrate and Scaling Properties:"); + writeComment(eComment.Info, " Feed: Travel speed X/Y = " + properties.fr0_TravelSpeedXY); + writeComment(eComment.Info, " Feed: Travel Speed Z = " + properties.fr1_TravelSpeedZ); + writeComment(eComment.Info, " Feed: Enforce Feedrate = " + properties.fr2_EnforceFeedrate); + writeComment(eComment.Info, " Feed: Scale Feedrate = " + properties.frA_ScaleFeedrate); + writeComment(eComment.Info, " Feed: Max XY Cut Speed = " + properties.frB_MaxCutSpeedXY); + writeComment(eComment.Info, " Feed: Max Z Cut Speed = " + properties.frC_MaxCutSpeedZ); + writeComment(eComment.Info, " Feed: Max Toolpath Speed = " + properties.frD_MaxCutSpeedXYZ); + + // Display the G1->G0 Mapping Properties + writeComment(eComment.Info, " "); + writeComment(eComment.Info, " G1->G0 Mapping Properties:"); + writeComment(eComment.Info, " Map: First G1 -> G0 Rapid = " + properties.mapD_RestoreFirstRapids); + writeComment(eComment.Info, " Map: G1s -> G0 Rapids = " + properties.mapE_RestoreRapids); + writeComment(eComment.Info, " Map: Safe Z to Rapid = " + properties.mapF_SafeZ); + writeComment(eComment.Info, " Map: Allow Rapid Z = " + properties.mapG_AllowRapidZ); + writeComment(eComment.Info, " "); +} + +function writeFirstSection() { + // Write out the information block at the beginning of the file + writeInformation(); writeComment(eComment.Important, " *** START begin ***"); @@ -999,7 +1015,7 @@ function writeFirstSection() { // Output a comment function writeComment(level, text) { - if (level <= properties.jobCommentLevel) { + if (level <= properties.job3_CommentLevel) { if (fw == eFirmware.GRBL) { writeln("(" + String(text).replace(/[\(\)]/g, "") + ")"); } @@ -1204,7 +1220,8 @@ function setCoolant(coolant) { CoolantB(true); } else { - writeComment(eComment.Important, " >>> WARNING: Coolant Channels, none set for: " + coolant); + writeComment(eComment.Important, " >>> WARNING: No Coolant Channels Enabled: " + ((coolant < propertyDefinitions.cl0_coolantA_Mode.values.length) ? + propertyDefinitions.cl0_coolantA_Mode.values[coolant].title : "unknown") + " requested"); } } } @@ -1243,19 +1260,19 @@ function Start() { writeComment(eComment.Info, " Set Absolute Positioning"); writeComment(eComment.Info, " Units = " + (unit == IN ? "inch" : "mm")); writeComment(eComment.Info, " Disable stepper timeout"); - if (properties.jobSetOriginOnStart) { - writeComment(eComment.Info, " Set current position = 0,0,0"); + if (properties.job1_SetOriginOnStart) { + writeComment(eComment.Info, " Set current position to 0,0,0"); } writeBlock(gAbsIncModal.format(90)); // Set to Absolute Positioning writeBlock(gUnitModal.format(unit == IN ? 20 : 21)); // Set the units writeBlock(mFormat.format(84), sFormat.format(0)); // Disable steppers timeout - if (properties.jobSetOriginOnStart) { + if (properties.job1_SetOriginOnStart) { writeBlock(gFormat.format(92), xFormat.format(0), yFormat.format(0), zFormat.format(0)); // Set origin to initial position } - if (properties.probeOnStart && tool.number != 0 && !tool.jetTool) { + if (properties.probe1_OnStart && tool.number != 0 && !tool.jetTool) { onCommand(COMMAND_TOOL_MEASURE); } } @@ -1282,8 +1299,8 @@ function spindleOn(_spindleSpeed, _clockwise) { // Default else { - if (properties.jobManualSpindlePowerControl) { - // for manual any positive input speed assumed as enabled. so it's just a flag + if (properties.job2_ManualSpindlePowerControl) { + // For manual any positive input speed assumed as enabled. so it's just a flag if (!this.spindleEnabled) { writeComment(eComment.Important, " >>> Spindle Speed: Manual"); askUser("Turn ON " + speedFormat.format(_spindleSpeed) + "RPM", "Spindle", false); @@ -1304,7 +1321,7 @@ function spindleOff() { //Default else { - if (properties.jobManualSpindlePowerControl) { + if (properties.job2_ManualSpindlePowerControl) { writeBlock(mFormat.format(300), sFormat.format(300), pFormat.format(3000)); askUser("Turn OFF spindle", "Spindle", false); } else { @@ -1319,7 +1336,7 @@ function laserOn(power) { // Firmware is Grbl if (fw == eFirmware.GRBL) { - writeBlock(mFormat.format(properties.GrblCutterMode), sFormat.format(laser_pwm)); + writeBlock(mFormat.format(properties.cutterGrblMode), sFormat.format(laser_pwm)); } // Default firmware @@ -1372,12 +1389,12 @@ function display_text(txt) { // Default else { - writeBlock(mFormat.format(117), (properties.jobSeparateWordsWithSpace ? "" : " ") + txt); + writeBlock(mFormat.format(117), (properties.job8_SeparateWordsWithSpace ? "" : " ") + txt); } } function circular(clockwise, cx, cy, cz, x, y, z, feed) { - if (!properties.jobUseArcs) { + if (!properties.job4_UseArcs) { linearize(tolerance); return; } @@ -1453,12 +1470,12 @@ function askUser(text, title, allowJog) { if (fw == eFirmware.REPRAP) { var v1 = " P\"" + text + "\" R\"" + title + "\" S3"; var v2 = allowJog ? " X1 Y1 Z1" : ""; - writeBlock(mFormat.format(291), (properties.jobSeparateWordsWithSpace ? "" : " ") + v1 + v2); + writeBlock(mFormat.format(291), (properties.job8_SeparateWordsWithSpace ? "" : " ") + v1 + v2); } // Default else { - writeBlock(mFormat.format(0), (properties.jobSeparateWordsWithSpace ? "" : " ") + text); + writeBlock(mFormat.format(0), (properties.job8_SeparateWordsWithSpace ? "" : " ") + text); } } @@ -1476,20 +1493,20 @@ function toolChange() { flushMotions(); // Go to tool change position - onRapid(propertyMmToUnit(properties.toolChangeX), propertyMmToUnit(properties.toolChangeY), propertyMmToUnit(properties.toolChangeZ)); + onRapid(propertyMmToUnit(properties.toolChange1_X), propertyMmToUnit(properties.toolChange2_Y), propertyMmToUnit(properties.toolChangeZ)); flushMotions(); // turn off spindle and coolant onCommand(COMMAND_COOLANT_OFF); onCommand(COMMAND_STOP_SPINDLE); - if (!properties.jobManualSpindlePowerControl) { + if (!properties.job2_ManualSpindlePowerControl) { // Beep writeBlock(mFormat.format(300), sFormat.format(400), pFormat.format(2000)); } // Disable Z stepper - if (properties.toolChangeDisableZStepper) { + if (properties.toolChange4_DisableZStepper) { askUser("Z Stepper will disabled. Wait for STOP!!", "Tool change", false); writeBlock(mFormat.format(17), 'Z'); // Disable steppers timeout } @@ -1497,7 +1514,7 @@ function toolChange() { askUser("Tool " + tool.number + " " + tool.comment, "Tool change", true); // Run Z probe gcode - if (properties.toolChangeZProbe && tool.number != 0) { + if (properties.probe2_OnToolChange && tool.number != 0) { onCommand(COMMAND_TOOL_MEASURE); } } @@ -1514,26 +1531,26 @@ function probeTool() { writeComment(eComment.Important, " Probe to Zero Z"); writeComment(eComment.Info, " Ask User to Attach the Z Probe"); writeComment(eComment.Info, " Do Probing"); - writeComment(eComment.Info, " Set Z to probe thickness: " + zFormat.format(propertyMmToUnit(properties.probeThickness))) - if (properties.toolChangeZ != "") { - writeComment(eComment.Info, " Retract the tool to " + propertyMmToUnit(properties.toolChangeZ)); + writeComment(eComment.Info, " Set Z to probe thickness: " + zFormat.format(propertyMmToUnit(properties.probe3_Thickness))) + if (properties.toolChange3_Z != "") { + writeComment(eComment.Info, " Retract the tool to " + propertyMmToUnit(properties.toolChange3_Z)); } writeComment(eComment.Info, " Ask User to Remove the Z Probe"); askUser("Attach ZProbe", "Probe", false); // refer http://marlinfw.org/docs/gcode/G038.html - if (properties.probeUseHomeZ) { + if (properties.probe4_UseHomeZ) { writeBlock(gFormat.format(28), 'Z'); } else { - writeBlock(gMotionModal.format(38.3), fFormat.format(propertyMmToUnit(properties.probeG38Speed)), zFormat.format(propertyMmToUnit(properties.probeG38Target))); + writeBlock(gMotionModal.format(38.3), fFormat.format(propertyMmToUnit(properties.probe6_G38Speed)), zFormat.format(propertyMmToUnit(properties.probe5_G38Target))); } - let z = zFormat.format(propertyMmToUnit(properties.probeThickness)); + let z = zFormat.format(propertyMmToUnit(properties.probe3_Thickness)); writeBlock(gFormat.format(92), z); // Set origin to initial position resetAll(); - if (properties.toolChangeZ != "") { // move up tool to safe height again after probing - rapidMovementsZ(propertyMmToUnit(properties.toolChangeZ), false); + if (properties.toolChange3_Z != "") { // move up tool to safe height again after probing + rapidMovementsZ(propertyMmToUnit(properties.toolChange3_Z), false); } flushMotions(); From a3ce69a198444e03aef3a901d8b9b7b92eb51d06 Mon Sep 17 00:00:00 2001 From: flyfisher604 Date: Fri, 5 Feb 2021 15:48:16 -0800 Subject: [PATCH 12/24] Merge branch 'Cleanup' --- MPCNC.cps | 472 ++++++++++++++++++++++++------------------------------ 1 file changed, 211 insertions(+), 261 deletions(-) diff --git a/MPCNC.cps b/MPCNC.cps index 91deb29..4322740 100644 --- a/MPCNC.cps +++ b/MPCNC.cps @@ -6,9 +6,17 @@ MPCNC posts processor for milling and laser/plasma cutting. */ -//--------------------- Refactored Firmware ---------------------- - description = "MPCNC Milling/Laser - Marlin 2.0, Grbl 1.1, RepRap"; +vendor = "flyfisher604"; +vendorUrl = "https://github.com/flyfisher604/mpcnc_post_processor"; + +// Internal properties +certificationLevel = 2; +extension = "gcode"; +setCodePage("ascii"); +capabilities = CAPABILITY_MILLING | CAPABILITY_JET; + +machineMode = undefined; //TYPE_MILLING, TYPE_JET var eFirmware = { MARLIN: 0, @@ -21,7 +29,7 @@ var eFirmware = { } }; -var firmware = eFirmware.MARLIN; +var fw = eFirmware.MARLIN; var eComment = { Off: 0, @@ -36,76 +44,22 @@ var eComment = { } }; -machineMode = undefined; //TYPE_MILLING, TYPE_JET - -/* -mergeProperties(properties, properties3dPrinter); -mergeProperties(propertyDefinitions, propertyDefinitions3dPrinter); -*/ - -function flushMotions() { - let fw = properties.jobSelectedFirmware; - - if (fw == eFirmware.GRBL) { - } - - // Default - else { - writeBlock(mFormat.format(400)); - } -} - -// Output the On or Off property that corresponds to either channel A or B -function CoolantA(on) { - writeBlock(on ? properties.cl2_coolantAOn : properties.cl3_coolantAOff); -} - -function CoolantB(on) { - writeBlock(on ? properties.cl4_coolantBOn : properties.cl5_coolantBOff); -} - - -//--------------------- Common ---------------------- - -/* - -https://github.com/flyfisher604/mpcnc_post_processor - -MPCNC posts processor for milling and laser/plasma cutting. - -*/ - -// Internal properties -certificationLevel = 2; -extension = "gcode"; -setCodePage("ascii"); -capabilities = CAPABILITY_MILLING | CAPABILITY_JET; - -// vendor of MPCNC -vendor = "flyfisher604"; -vendorUrl = "https://github.com/flyfisher604/mpcnc_post_processor"; - - // user-defined properties properties = { - jobSelectedFirmware : firmware, // Firmware to use in special cases - - jobManualSpindlePowerControl: true, // Spindle motor is controlled by manual switch - - jobUseArcs: true, // Produce G2/G3 for arcs - - jobSetOriginOnStart: true, // Set origin when gcode start (G92) - jobGoOriginOnFinish: true, // Go X0 Y0 Z0 at gcode end - - jobSequenceNumbers: false, // show sequence numbers - jobSequenceNumberStart: 10, // first sequence number - jobSequenceNumberIncrement: 1, // increment for sequence numbers - jobSeparateWordsWithSpace: true, // specifies that the words should be separated with a white space - jobCommentLevel: eComment.Info, // The level of comments included + job0_SelectedFirmware : fw, // Firmware to use in special cases + job1_SetOriginOnStart: true, // Set current position as 0,0,0 on start (G92) + job2_ManualSpindlePowerControl: true, // Spindle motor is controlled by manual switch + job3_CommentLevel: eComment.Info, // The level of comments included + job4_UseArcs: true, // Produce G2/G3 for arcs + job5_SequenceNumbers: false, // show sequence numbers + job6_SequenceNumberStart: 10, // first sequence number + job7_SequenceNumberIncrement: 1, // increment for sequence numbers + job8_SeparateWordsWithSpace: true, // specifies that the words should be separated with a white space + job9_GoOriginOnFinish: true, // Go X0 Y0 current Z at end fr0_TravelSpeedXY: 2500, // High speed for travel movements X & Y (mm/min) fr1_TravelSpeedZ: 300, // High speed for travel movements Z (mm/min) - fr2_EnforceFeedrate: false, // Add feedrate to each movement line + fr2_EnforceFeedrate: true, // Add feedrate to each movement line frA_ScaleFeedrate: false, // Will feedrated be scaled frB_MaxCutSpeedXY: 900, // Max speed for cut movements X & Y (mm/min) frC_MaxCutSpeedZ: 180, // Max speed for cut movements Z (mm/min) @@ -113,21 +67,21 @@ properties = { mapD_RestoreFirstRapids: false, // Map first G01 --> G00 mapE_RestoreRapids: false, // Map G01 --> G00 for SafeTravelsAboveZ - mapF_SafeZ: 10, // G01 mapped to G00 if Z is >= jobSafeZRapid - mapG_AllowRapidZ: true, // Allow G01 --> G00 for vertical retracts and Z descents above safe - - toolChangeEnabled: true, // Enable tool change code (bultin tool change requires LCD display) - toolChangeX: 0, // X position for builtin tool change - toolChangeY: 0, // Y position for builtin tool change - toolChangeZ: 40, // Z position for builtin tool change - toolChangeZProbe: true, // Z probe after tool change - toolChangeDisableZStepper: false, // disable Z stepper when change a tool - - probeOnStart: true, // Execute probe gcode to align tool - probeThickness: 0.8, // plate thickness - probeUseHomeZ: true, // use G28 or G38 for probing - probeG38Target: -10, // probing up to pos - probeG38Speed: 30, // probing with speed + mapF_SafeZ: 5, // G01 mapped to G00 if Z is >= jobSafeZRapid + mapG_AllowRapidZ: false, // Allow G01 --> G00 for vertical retracts and Z descents above safe + + toolChange0_Enabled: false, // Enable tool change code (bultin tool change requires LCD display) + toolChange1_X: 0, // X position for builtin tool change + toolChange2_Y: 0, // Y position for builtin tool change + toolChange3_Z: 40, // Z position for builtin tool change + toolChange4_DisableZStepper: false, // disable Z stepper when change a tool + + probe1_OnStart: false, // Execute probe gcode to align tool + probe2_OnToolChange: false, // Z probe after tool change + probe3_Thickness: 0.8, // plate thickness + probe4_UseHomeZ: true, // use G28 or G38 for probing + probe5_G38Target: -10, // probing up to pos + probe6_G38Speed: 30, // probing with speed gcodeStartFile: "", // File with custom Gcode for header/start (in nc folder) gcodeStopFile: "", // File with custom Gcode for footer/end (in nc folder) @@ -139,7 +93,8 @@ properties = { cutterOnEtch: 40, // Persent of power to turn on the laser/plasma cutter in etch mode cutterMarlinMode: 106, // Marlin mode laser/plasma cutter cutterMarlinPin: 4, // Marlin laser/plasma cutter pin for M42 - + cutterGrblMode: 4, // GRBL mode laser/plasma cutter + cl0_coolantA_Mode: 0, // Enable issuing g-codes for control Coolant channel A cl1_coolantB_Mode: 0, // Use issuing g-codes for control Coolant channel B cl2_coolantAOn: "M42 P6 S255", // GCode command to turn on Coolant channel A @@ -150,13 +105,12 @@ properties = { DuetMillingMode: "M453 P2 I0 R30000 F200", // GCode command to setup Duet3d milling mode DuetLaserMode: "M452 P2 I0 R255 F200", // GCode command to setup Duet3d laser mode - GrblCutterMode: 4, // GRBL mode laser/plasma cutter }; propertyDefinitions = { - jobSelectedFirmware: { - title: "Job: Select CNC Firmware", description: "Control GCode create for specific firmware", group: 1, + job0_SelectedFirmware: { + title: "Job: CNC Firmware", description: "Dialect of GCode to create", group: 1, type: "integer", default_mm: 0, default_in: 0, values: [ { title: eFirmware.prop[eFirmware.MARLIN].name, id: eFirmware.MARLIN }, @@ -165,54 +119,47 @@ propertyDefinitions = { ] }, - jobManualSpindlePowerControl: { - title: "Job: Manual Spindle On/Off", description: "Set Yes when your spindle motor is controlled by manual switch", group: 1, + job1_SetOriginOnStart: { + title: "Job: Zero Starting Location (G92)", description: "On start set the current location as 0,0,0 (G92)", group: 1, type: "boolean", default_mm: true, default_in: true }, - jobUseArcs: { - title: "Job: Use Arcs", description: "Use G2/G3 g-codes fo circular movements", group: 1, + job2_ManualSpindlePowerControl: { + title: "Job: Manual Spindle On/Off", description: "Enable to manually turn spindle motor on/off", group: 1, type: "boolean", default_mm: true, default_in: true }, - - jobMarlinEnforcFeFeedrate: { - title: "Job: Marlin Enforce Feedrate", description: "Add feedrate to each movement g-code", group: 1, - type: "boolean", default_mm: false, default_in: false - }, - - jobSetOriginOnStart: { - title: "Job: Reset on start (G92)", description: "Set origin when gcode start (G92)", group: 1, - type: "boolean", default_mm: true, default_in: true + job3_CommentLevel: { + title: "Job: Comment Level", description: "Controls the comments include", group: 1, + type: "integer", default_mm: 3, default_in: 3, + values: [ + { title: eComment.prop[eComment.Off].name, id: eComment.Off }, + { title: eComment.prop[eComment.Important].name, id: eComment.Important }, + { title: eComment.prop[eComment.Info].name, id: eComment.Info }, + { title: eComment.prop[eComment.Debug].name, id: eComment.Debug }, + ] }, - jobGoOriginOnFinish: { - title: "Job: Goto 0, 0 at end", description: "Go X0 Y0 at gcode end", group: 1, + job4_UseArcs: { + title: "Job: Use Arcs", description: "Use G2/G3 g-codes fo circular movements", group: 1, type: "boolean", default_mm: true, default_in: true }, - - jobSequenceNumbers: { - title: "Job: Line numbers", description: "Show sequence numbers", group: 1, + job5_SequenceNumbers: { + title: "Job: Enable Line #s", description: "Show sequence numbers", group: 1, type: "boolean", default_mm: false, default_in: false }, - jobSequenceNumberStart: { - title: "Job: Line # start", description: "First sequence number", group: 1, + job6_SequenceNumberStart: { + title: "Job: First Line #", description: "First sequence number", group: 1, type: "integer", default_mm: 10, default_in: 10 }, - jobSequenceNumberIncrement: { - title: "Job: Line # increment", description: "Increment for sequence numbers", group: 1, + job7_SequenceNumberIncrement: { + title: "Job: Line # Increment", description: "Sequence number increment", group: 1, type: "integer", default_mm: 1, default_in: 1 }, - jobSeparateWordsWithSpace: { - title: "Job: Separate words", description: "Specifies that the words should be separated with a white space", group: 1, + job8_SeparateWordsWithSpace: { + title: "Job: Include Whitespace", description: "Includes whitespace seperation between text", group: 1, type: "boolean", default_mm: true, default_in: true }, - jobCommentLevel: { - title: "Job: Comment Level", description: "Controls the comments include", group: 1, - type: "integer", default_mm: 3, default_in: 3, - values: [ - { title: eComment.prop[eComment.Off].name, id: eComment.Off }, - { title: eComment.prop[eComment.Important].name, id: eComment.Important }, - { title: eComment.prop[eComment.Info].name, id: eComment.Info }, - { title: eComment.prop[eComment.Debug].name, id: eComment.Debug }, - ] + job9_GoOriginOnFinish: { + title: "Job: At end go to 0,0", description: "Go to X0 Y0 at gcode end, Z unchanged", group: 1, + type: "boolean", default_mm: true, default_in: true }, fr0_TravelSpeedXY: { @@ -225,87 +172,85 @@ propertyDefinitions = { }, fr2_EnforceFeedrate: { title: "Feed: Enforce Feedrate", description: "Add feedrate to each movement g-code", group: 2, - type: "boolean", default_mm: false, default_in: false + type: "boolean", default_mm: true, default_in: true }, frA_ScaleFeedrate: { - title: "Feed: Scale feedrate", description: "Scale feedrate based on X, Y, Z axis maximums", group: 2, + title: "Feed: Scale Feedrate", description: "Scale feedrate based on X, Y, Z axis maximums", group: 2, type: "boolean", default_mm: false, default_in: false }, frB_MaxCutSpeedXY: { - title: "Feed: Max cut speed X or Y", description: "Max X or Y axis cut speed (mm/min; in/min)", group: 2, + title: "Feed: Max XY Cut Speed", description: "Maximum X or Y axis cut speed (mm/min; in/min)", group: 2, type: "spatial", default_mm: 900, default_in: 35.43 }, frC_MaxCutSpeedZ: { - title: "Feed: Max cut speed Z", description: "Max Z axis cut speed (mm/min; in/min)", group: 2, + title: "Feed: Max Z Cut Speed", description: "Maximum Z axis cut speed (mm/min; in/min)", group: 2, type: "spatial", default_mm: 180, default_in: 7.08 }, frD_MaxCutSpeedXYZ: { - title: "Feed: Max toolpath speed", description: "After scaling limit feedrate to this (mm/min; in/min)", group: 2, + title: "Feed: Max Toolpath Speed", description: "Maximum scaled feedrate (mm/min; in/min)", group: 2, type: "spatial", default_mm: 1000, default_in: 39.37 }, - mapD_RestoreFirstRapids: { - title: "Map: First G1 -> G0 Rapids", description: "Convert first G1 of a cut to G0 Rapids", group: 3, + title: "Map: First G1 -> G0 Rapid", description: "Ensure move to start of a cut is with a G0 Rapid", group: 3, type: "boolean", default_mm: false, default_in: false }, mapE_RestoreRapids: { - title: "Map: G1 -> G0 Rapids", description: "When safe, convert G1s to G0 Rapids", group: 3, + title: "Map: G1s -> G0 Rapids", description: "Enable to convert G1s to G0 Rapids when safe", group: 3, type: "boolean", default_mm: false, default_in: false }, mapF_SafeZ: { - title: "Map: Safe Z for Rapids", description: "Z must be above or equal to this to map G01 --> G00", group: 3, + title: "Map: Safe Z to Rapid", description: "Must be above or equal to this value to map G1s --> G0s", group: 3, type: "integer", default_mm: 10, default_in: 0.590551 }, mapG_AllowRapidZ: { - title: "Map: Allow Rapid Z", description: "If G01 to Rapids allowed, then include vertical retracts and safe descents", group: 3, + title: "Map: Allow Rapid Z", description: "Enable to include vertical retracts and safe descents", group: 3, type: "boolean", default_mm: true, default_in: true }, - - toolChangeEnabled: { - title: "Change: Enabled", description: "Enable tool change code (bultin tool change requires LCD display)", group: 4, - type: "boolean", default_mm: true, default_in: true + toolChange0_Enabled: { + title: "Tool Change: Enable", description: "Include tool change code when tool changes (bultin tool change requires LCD display)", group: 4, + type: "boolean", default_mm: false, default_in: false }, - toolChangeX: { - title: "Change: X", description: "X position for builtin tool change", group: 4, + toolChange1_X: { + title: "Tool Change: X", description: "X location for tool change", group: 4, type: "spatial", default_mm: 0, default_in: 0 }, - toolChangeY: { - title: "Change: Y", description: "Y position for builtin tool change", group: 4, + toolChange2_Y: { + title: "Tool Change: Y", description: "Y location for tool change", group: 4, type: "spatial", default_mm: 0, default_in: 0 }, - toolChangeZ: { - title: "Change: Z ", description: "Z position for builtin tool change", group: 4, + toolChange3_Z: { + title: "Tool Change: Z ", description: "Z location for tool change", group: 4, type: "spatial", default_mm: 40, default_in: 1.6 }, - toolChangeZProbe: { - title: "Change: Make Z Probe", description: "Z probe after tool change", group: 4, - type: "boolean", default_mm: true, default_in: true - }, - toolChangeDisableZStepper: { - title: "Change: Disable Z stepper", description: "Disable Z stepper when change a tool", group: 4, + toolChange4_DisableZStepper: { + title: "Tool Change: Disable Z stepper", description: "Disable Z stepper after reaching tool change location", group: 4, type: "boolean", default_mm: false, default_in: false }, - - probeOnStart: { + + probe1_OnStart: { title: "Probe: On job start", description: "Execute probe gcode on job start", group: 5, - type: "boolean", default_mm: true, default_in: true + type: "boolean", default_mm: false, default_in: false + }, + probe2_OnToolChange: { + title: "Probe: Afterward Tool Change", description: "After tool change, probe Z at the current location", group: 5, + type: "boolean", default_mm: false, default_in: false }, - probeThickness: { + probe3_Thickness: { title: "Probe: Plate thickness", description: "Plate thickness", group: 5, type: "spatial", default_mm: 0.8, default_in: 0.032 }, - probeUseHomeZ: { - title: "Probe: Use Home Z", description: "Use G28 or G38 for probing", group: 5, + probe4_UseHomeZ: { + title: "Probe: Use Home Z (G28)", description: "Probe with G28 (Yes) or G38 (No)", group: 5, type: "boolean", default_mm: true, default_in: true }, - probeG38Target: { - title: "Probe: G38 target", description: "Probing up to Z position", group: 5, + probe5_G38Target: { + title: "Probe: G38 target", description: "Probing's furthest Z position", group: 5, type: "spatial", default_mm: -10, default_in: -0.5 }, - probeG38Speed: { - title: "Probe: G38 speed", description: "Probing with speed (mm/min; in/min)", group: 5, + probe6_G38Speed: { + title: "Probe: G38 speed", description: "Probing's speed (mm/min; in/min)", group: 5, type: "spatial", default_mm: 30, default_in: 1.2 }, @@ -322,18 +267,27 @@ propertyDefinitions = { type: "number", default_mm: 40, default_in: 40 }, cutterMarlinMode: { - title: "Laser: Marlin/Reprap mode", description: "Marlin/Reprar mode of the laser/plasma cutter", group: 6, + title: "Laser: Marlin/Reprap mode", description: "Marlin/Reprap mode of the laser/plasma cutter", group: 6, type: "integer", default_mm: 106, default_in: 106, values: [ - { title: "M106 S{PWM}/M107", id: 106 }, - { title: "M3 O{PWM}/M5", id: 3 }, - { title: "M42 P{pin} S{PWM}", id: 42 }, + { title: "Fan - M106 S{PWM}/M107", id: 106 }, + { title: "Spindle - M3 O{PWM}/M5", id: 3 }, + { title: "Pin - M42 P{pin} S{PWM}", id: 42 }, ] }, cutterMarlinPin: { title: "Laser: Marlin M42 pin", description: "Marlin custom pin number for the laser/plasma cutter", group: 6, type: "integer", default_mm: 4, default_in: 4 }, + cutterGrblMode: { + title: "Laser: GRBL mode", description: "GRBL mode of the laser/plasma cutter", group: 6, + type: "integer", default_mm: 4, default_in: 4, + values: [ + { title: "M4 S{PWM}/M5 dynamic power", id: 4 }, + { title: "M3 S{PWM}/M5 static power", id: 3 }, + ] + }, + gcodeStartFile: { title: "Extern: Start File", description: "File with custom Gcode for header/start (in nc folder)", group: 7, @@ -352,28 +306,7 @@ propertyDefinitions = { type: "file", default_mm: "", default_in: "" }, - - DuetMillingMode: { - title: "Duet: Milling mode", description: "GCode command to setup Duet3d milling mode", group: 10, - type: "string", default_mm: "M453 P2 I0 R30000 F200", default_in: "M453 P2 I0 R30000 F200" - }, - DuetLaserMode: { - title: "Duet: Laser mode", description: "GCode command to setup Duet3d laser mode", group: 10, - type: "string", default_mm: "M452 P2 I0 R255 F200", default_in: "M452 P2 I0 R255 F200" - }, - - - GrblCutterMode: { - title: "GRBL: Laser mode", description: "GRBL mode of the laser/plasma cutter", group: 11, - type: "integer", default_mm: 4, default_in: 4, - values: [ - { title: "M4 S{PWM}/M5 dynamic power", id: 4 }, - { title: "M3 S{PWM}/M5 static power", id: 3 }, - ] - }, - // Coolant - cl0_coolantA_Mode: { title: "Coolant: A Mode", description: "Enable channel A when tool is set this coolant", group: 8, type: "integer", default_mm: 0, default_in: 0, @@ -442,15 +375,16 @@ propertyDefinitions = { { title: "Grbl: M9 (off)", id: "M9" } ] }, -}; -/* - -https://github.com/guffy1234/mpcnc_posts_processor - -MPCNC posts processor for milling and laser/plasma cutting. - -*/ + DuetMillingMode: { + title: "Duet: Milling mode", description: "GCode command to setup Duet3d milling mode", group: 9, + type: "string", default_mm: "M453 P2 I0 R30000 F200", default_in: "M453 P2 I0 R30000 F200" + }, + DuetLaserMode: { + title: "Duet: Laser mode", description: "GCode command to setup Duet3d laser mode", group: 9, + type: "string", default_mm: "M452 P2 I0 R255 F200", default_in: "M452 P2 I0 R255 F200" + }, +}; var sequenceNumber; @@ -511,19 +445,36 @@ allowedCircularPlanes = undefined; // Writes the specified block. function writeBlock() { - if (properties.jobSequenceNumbers) { + if (properties.job5_SequenceNumbers) { writeWords2("N" + sequenceNumber, arguments); - sequenceNumber += properties.jobSequenceNumberIncrement; + sequenceNumber += properties.job7_SequenceNumberIncrement; } else { writeWords(arguments); } } -var currentFirmware; +function flushMotions() { + if (fw == eFirmware.GRBL) { + } + + // Default + else { + writeBlock(mFormat.format(400)); + } +} + +// Coolant +function CoolantA(on) { + writeBlock(on ? properties.cl2_coolantAOn : properties.cl3_coolantAOff); +} + +function CoolantB(on) { + writeBlock(on ? properties.cl4_coolantBOn : properties.cl5_coolantBOff); +} // Called in every new gcode file function onOpen() { - let fw = properties.jobSelectedFirmware; + fw = properties.job0_SelectedFirmware; if (fw == eFirmware.GRBL) { gMotionModal = createModal({}, gFormat); // modal group 1 // G0-G3, ... @@ -537,23 +488,21 @@ function onOpen() { fOutput = createVariable({ force: true }, fFormat); } - sequenceNumber = properties.jobSequenceNumberStart; - if (!properties.jobSeparateWordsWithSpace) { + sequenceNumber = properties.job6_SequenceNumberStart; + if (!properties.job8_SeparateWordsWithSpace) { setWordSeparator(""); } } // Called at end of gcode file function onClose() { - let fw = properties.jobSelectedFirmware; - writeComment(eComment.Important, " *** STOP begin ***"); flushMotions(); if (properties.gcodeStopFile == "") { onCommand(COMMAND_COOLANT_OFF); - if (properties.jobGoOriginOnFinish) { + if (properties.job9_GoOriginOnFinish) { rapidMovementsXY(0, 0); } onCommand(COMMAND_STOP_SPINDLE); @@ -574,8 +523,6 @@ var cutterOnCurrentPower; var forceSectionToStartWithRapid = false; function onSection() { - let fw = properties.jobSelectedFirmware; - // Every section needs to start with a Rapid to get to the initial location. // In the hobby version Rapids have been elliminated and the first command is // a onLinear not a onRapid command. This results in not current position being @@ -595,7 +542,7 @@ function onSection() { // Do a tool change if tool changes are enabled and its not the first section and this section uses // a different tool then the previous section - if (properties.toolChangeEnabled && !isFirstSection() && tool.number != getPreviousSection().getTool().number) { + if (properties.toolChange0_Enabled && !isFirstSection() && tool.number != getPreviousSection().getTool().number) { if (properties.gcodeToolFile == "") { // Post Processor does the tool change @@ -673,7 +620,7 @@ function resetAll() { function onSectionEnd() { resetAll(); writeComment(eComment.Important, " *** SECTION end ***"); - writeln(""); + writeComment(eComment.Important, ""); } function onComment(message) { @@ -798,8 +745,6 @@ function onPower(power) { // Called on Dwell Manual NC invocation function onDwell(seconds) { - let fw = properties.jobSelectedFirmware; - writeComment(eComment.Important, " >>> Dwell"); if (seconds > 99999.999) { warning(localize("Dwelling time is out of range.")); @@ -964,8 +909,8 @@ function onCommand(command) { } } -function writeFirstSection() { - // dump tool information +function writeInformation() { + // Calcualte the min/max ranges across all sections var toolZRanges = {}; var vectorX = new Vector(1, 0, 0); var vectorY = new Vector(0, 1, 0); @@ -1004,14 +949,16 @@ function writeFirstSection() { } } + // Display the Range Table writeComment(eComment.Info, " "); - writeComment(eComment.Info, " Ranges table:"); + writeComment(eComment.Info, " Ranges Table:"); writeComment(eComment.Info, " X: Min=" + xyzFormat.format(ranges.x.min) + " Max=" + xyzFormat.format(ranges.x.max) + " Size=" + xyzFormat.format(ranges.x.max - ranges.x.min)); writeComment(eComment.Info, " Y: Min=" + xyzFormat.format(ranges.y.min) + " Max=" + xyzFormat.format(ranges.y.max) + " Size=" + xyzFormat.format(ranges.y.max - ranges.y.min)); writeComment(eComment.Info, " Z: Min=" + xyzFormat.format(ranges.z.min) + " Max=" + xyzFormat.format(ranges.z.max) + " Size=" + xyzFormat.format(ranges.z.max - ranges.z.min)); + // Display the Tools Table writeComment(eComment.Info, " "); - writeComment(eComment.Info, " Tools table:"); + writeComment(eComment.Info, " Tools Table:"); var tools = getToolTable(); if (tools.getNumberOfTools() > 0) { for (var i = 0; i < tools.getNumberOfTools(); ++i) { @@ -1028,7 +975,31 @@ function writeFirstSection() { } } - writeComment(eComment.Info, " "); + // Display the Feedrate and Scaling Properties + writeComment(eComment.Info, " "); + writeComment(eComment.Info, " Feedrate and Scaling Properties:"); + writeComment(eComment.Info, " Feed: Travel speed X/Y = " + properties.fr0_TravelSpeedXY); + writeComment(eComment.Info, " Feed: Travel Speed Z = " + properties.fr1_TravelSpeedZ); + writeComment(eComment.Info, " Feed: Enforce Feedrate = " + properties.fr2_EnforceFeedrate); + writeComment(eComment.Info, " Feed: Scale Feedrate = " + properties.frA_ScaleFeedrate); + writeComment(eComment.Info, " Feed: Max XY Cut Speed = " + properties.frB_MaxCutSpeedXY); + writeComment(eComment.Info, " Feed: Max Z Cut Speed = " + properties.frC_MaxCutSpeedZ); + writeComment(eComment.Info, " Feed: Max Toolpath Speed = " + properties.frD_MaxCutSpeedXYZ); + + // Display the G1->G0 Mapping Properties + writeComment(eComment.Info, " "); + writeComment(eComment.Info, " G1->G0 Mapping Properties:"); + writeComment(eComment.Info, " Map: First G1 -> G0 Rapid = " + properties.mapD_RestoreFirstRapids); + writeComment(eComment.Info, " Map: G1s -> G0 Rapids = " + properties.mapE_RestoreRapids); + writeComment(eComment.Info, " Map: Safe Z to Rapid = " + properties.mapF_SafeZ); + writeComment(eComment.Info, " Map: Allow Rapid Z = " + properties.mapG_AllowRapidZ); + + writeComment(eComment.Info, " "); +} + +function writeFirstSection() { + // Write out the information block at the beginning of the file + writeInformation(); writeComment(eComment.Important, " *** START begin ***"); @@ -1044,9 +1015,7 @@ function writeFirstSection() { // Output a comment function writeComment(level, text) { - if (level <= properties.jobCommentLevel) { - let fw = properties.jobSelectedFirmware; - + if (level <= properties.job3_CommentLevel) { if (fw == eFirmware.GRBL) { writeln("(" + String(text).replace(/[\(\)]/g, "") + ")"); } @@ -1214,8 +1183,6 @@ var coolantChannelA = 0; var coolantChannelB = 0; function setCoolant(coolant) { - let fw = properties.jobSelectedFirmware; - // As long as we are not disabling coolant (= 0), then if either of the coolant // channels are already operating in the mode requested then there is // nothing to do @@ -1253,7 +1220,8 @@ function setCoolant(coolant) { CoolantB(true); } else { - writeComment(eComment.Important, " >>> WARNING: Coolant Channels, none set for: " + coolant); + writeComment(eComment.Important, " >>> WARNING: No Coolant Channels Enabled: " + ((coolant < propertyDefinitions.cl0_coolantA_Mode.values.length) ? + propertyDefinitions.cl0_coolantA_Mode.values[coolant].title : "unknown") + " requested"); } } } @@ -1279,8 +1247,6 @@ Firmware3dPrinterLike.prototype.constructor = Firmware3dPrinterLike; */ function Start() { - let fw = properties.jobSelectedFirmware; - // Is Grbl? if (fw == eFirmware.GRBL) { writeBlock(gAbsIncModal.format(90)); // Set to Absolute Positioning @@ -1294,26 +1260,25 @@ function Start() { writeComment(eComment.Info, " Set Absolute Positioning"); writeComment(eComment.Info, " Units = " + (unit == IN ? "inch" : "mm")); writeComment(eComment.Info, " Disable stepper timeout"); - if (properties.jobSetOriginOnStart) { - writeComment(eComment.Info, " Set current position = 0,0,0"); + if (properties.job1_SetOriginOnStart) { + writeComment(eComment.Info, " Set current position to 0,0,0"); } writeBlock(gAbsIncModal.format(90)); // Set to Absolute Positioning writeBlock(gUnitModal.format(unit == IN ? 20 : 21)); // Set the units writeBlock(mFormat.format(84), sFormat.format(0)); // Disable steppers timeout - if (properties.jobSetOriginOnStart) { + if (properties.job1_SetOriginOnStart) { writeBlock(gFormat.format(92), xFormat.format(0), yFormat.format(0), zFormat.format(0)); // Set origin to initial position } - if (properties.probeOnStart && tool.number != 0 && !tool.jetTool) { + if (properties.probe1_OnStart && tool.number != 0 && !tool.jetTool) { onCommand(COMMAND_TOOL_MEASURE); } } } -function end() { - let fw = properties.jobSelectedFirmware; +function end() { // Is Grbl? if (fw == eFirmware.GRBL) { writeBlock(mFormat.format(30)); @@ -1325,10 +1290,7 @@ function end() { } } - function spindleOn(_spindleSpeed, _clockwise) { - let fw = properties.jobSelectedFirmware; - // Is Grbl? if (fw == eFirmware.GRBL) { writeComment(eComment.Important, " >>> Spindle Speed " + speedFormat.format(_spindleSpeed)); @@ -1337,8 +1299,8 @@ function spindleOn(_spindleSpeed, _clockwise) { // Default else { - if (properties.jobManualSpindlePowerControl) { - // for manual any positive input speed assumed as enabled. so it's just a flag + if (properties.job2_ManualSpindlePowerControl) { + // For manual any positive input speed assumed as enabled. so it's just a flag if (!this.spindleEnabled) { writeComment(eComment.Important, " >>> Spindle Speed: Manual"); askUser("Turn ON " + speedFormat.format(_spindleSpeed) + "RPM", "Spindle", false); @@ -1350,9 +1312,8 @@ function spindleOn(_spindleSpeed, _clockwise) { this.spindleEnabled = true; } } -function spindleOff() { - let fw = properties.jobSelectedFirmware; +function spindleOff() { // Is Grbl? if (fw == eFirmware.GRBL) { writeBlock(mFormat.format(5)); @@ -1360,7 +1321,7 @@ function spindleOff() { //Default else { - if (properties.jobManualSpindlePowerControl) { + if (properties.job2_ManualSpindlePowerControl) { writeBlock(mFormat.format(300), sFormat.format(300), pFormat.format(3000)); askUser("Turn OFF spindle", "Spindle", false); } else { @@ -1371,12 +1332,11 @@ function spindleOff() { } function laserOn(power) { - let fw = properties.jobSelectedFirmware; var laser_pwm = power / 100 * 255; // Firmware is Grbl if (fw == eFirmware.GRBL) { - writeBlock(mFormat.format(properties.GrblCutterMode), sFormat.format(laser_pwm)); + writeBlock(mFormat.format(properties.cutterGrblMode), sFormat.format(laser_pwm)); } // Default firmware @@ -1386,7 +1346,7 @@ function laserOn(power) { writeBlock(mFormat.format(106), sFormat.format(laser_pwm)); break; case 3: - if (fw = eFirmware.REPRAP) { + if (fw == eFirmware.REPRAP) { writeBlock(mFormat.format(3), sFormat.format(laser_pwm)); } else { writeBlock(mFormat.format(3), oFormat.format(laser_pwm)); @@ -1400,8 +1360,6 @@ function laserOn(power) { } function laserOff() { - let fw = properties.jobSelectedFirmware; - // Firmware is Grbl if (fw == eFirmware.GRBL) { writeBlock(mFormat.format(5)); @@ -1424,8 +1382,6 @@ function laserOff() { } function display_text(txt) { - let fw = properties.jobSelectedFirmware; - // Firmware is Grbl if (fw == eFirmware.GRBL) { // Don't display text @@ -1433,18 +1389,17 @@ function display_text(txt) { // Default else { - writeBlock(mFormat.format(117), (properties.jobSeparateWordsWithSpace ? "" : " ") + txt); + writeBlock(mFormat.format(117), (properties.job8_SeparateWordsWithSpace ? "" : " ") + txt); } } function circular(clockwise, cx, cy, cz, x, y, z, feed) { - if (!properties.jobUseArcs) { + if (!properties.job4_UseArcs) { linearize(tolerance); return; } var start = getCurrentPosition(); - let fw = properties.jobSelectedFirmware; // Firmware is Grbl if (fw == eFirmware.GRBL) { @@ -1511,24 +1466,20 @@ function circular(clockwise, cx, cy, cz, x, y, z, feed) { } function askUser(text, title, allowJog) { - let fw = properties.jobSelectedFirmware; - // Firmware is RepRap? if (fw == eFirmware.REPRAP) { var v1 = " P\"" + text + "\" R\"" + title + "\" S3"; var v2 = allowJog ? " X1 Y1 Z1" : ""; - writeBlock(mFormat.format(291), (properties.jobSeparateWordsWithSpace ? "" : " ") + v1 + v2); + writeBlock(mFormat.format(291), (properties.job8_SeparateWordsWithSpace ? "" : " ") + v1 + v2); } // Default else { - writeBlock(mFormat.format(0), (properties.jobSeparateWordsWithSpace ? "" : " ") + text); + writeBlock(mFormat.format(0), (properties.job8_SeparateWordsWithSpace ? "" : " ") + text); } } function toolChange() { - let fw = properties.jobSelectedFirmware; - // Grbl tool change? if (fw == eFirmware.GRBL) { @@ -1542,20 +1493,20 @@ function toolChange() { flushMotions(); // Go to tool change position - onRapid(propertyMmToUnit(properties.toolChangeX), propertyMmToUnit(properties.toolChangeY), propertyMmToUnit(properties.toolChangeZ)); + onRapid(propertyMmToUnit(properties.toolChange1_X), propertyMmToUnit(properties.toolChange2_Y), propertyMmToUnit(properties.toolChangeZ)); flushMotions(); // turn off spindle and coolant onCommand(COMMAND_COOLANT_OFF); onCommand(COMMAND_STOP_SPINDLE); - if (!properties.jobManualSpindlePowerControl) { + if (!properties.job2_ManualSpindlePowerControl) { // Beep writeBlock(mFormat.format(300), sFormat.format(400), pFormat.format(2000)); } // Disable Z stepper - if (properties.toolChangeDisableZStepper) { + if (properties.toolChange4_DisableZStepper) { askUser("Z Stepper will disabled. Wait for STOP!!", "Tool change", false); writeBlock(mFormat.format(17), 'Z'); // Disable steppers timeout } @@ -1563,17 +1514,16 @@ function toolChange() { askUser("Tool " + tool.number + " " + tool.comment, "Tool change", true); // Run Z probe gcode - if (properties.toolChangeZProbe && tool.number != 0) { + if (properties.probe2_OnToolChange && tool.number != 0) { onCommand(COMMAND_TOOL_MEASURE); } } } function probeTool() { - let fw = properties.jobSelectedFirmware; - // Is Grbl? if (fw == eFirmware.GRBL) { + writeComment(eComment.Important, " >>> WARNING: No probing implemented for GRBL"); } // Default @@ -1581,26 +1531,26 @@ function probeTool() { writeComment(eComment.Important, " Probe to Zero Z"); writeComment(eComment.Info, " Ask User to Attach the Z Probe"); writeComment(eComment.Info, " Do Probing"); - writeComment(eComment.Info, " Set Z to probe thickness: " + zFormat.format(propertyMmToUnit(properties.probeThickness))) - if (properties.toolChangeZ != "") { - writeComment(eComment.Info, " Retract the tool to " + propertyMmToUnit(properties.toolChangeZ)); + writeComment(eComment.Info, " Set Z to probe thickness: " + zFormat.format(propertyMmToUnit(properties.probe3_Thickness))) + if (properties.toolChange3_Z != "") { + writeComment(eComment.Info, " Retract the tool to " + propertyMmToUnit(properties.toolChange3_Z)); } writeComment(eComment.Info, " Ask User to Remove the Z Probe"); askUser("Attach ZProbe", "Probe", false); // refer http://marlinfw.org/docs/gcode/G038.html - if (properties.probeUseHomeZ) { + if (properties.probe4_UseHomeZ) { writeBlock(gFormat.format(28), 'Z'); } else { - writeBlock(gMotionModal.format(38.3), fFormat.format(propertyMmToUnit(properties.probeG38Speed)), zFormat.format(propertyMmToUnit(properties.probeG38Target))); + writeBlock(gMotionModal.format(38.3), fFormat.format(propertyMmToUnit(properties.probe6_G38Speed)), zFormat.format(propertyMmToUnit(properties.probe5_G38Target))); } - let z = zFormat.format(propertyMmToUnit(properties.probeThickness)); + let z = zFormat.format(propertyMmToUnit(properties.probe3_Thickness)); writeBlock(gFormat.format(92), z); // Set origin to initial position resetAll(); - if (properties.toolChangeZ != "") { // move up tool to safe height again after probing - rapidMovementsZ(propertyMmToUnit(properties.toolChangeZ), false); + if (properties.toolChange3_Z != "") { // move up tool to safe height again after probing + rapidMovementsZ(propertyMmToUnit(properties.toolChange3_Z), false); } flushMotions(); From 04ccf74dca5eedd79f280b83d62dd9caf1a1dba3 Mon Sep 17 00:00:00 2001 From: flyfisher604 Date: Fri, 5 Feb 2021 17:31:45 -0800 Subject: [PATCH 13/24] Readme properties updated; property typos --- MPCNC.cps | 22 +- README.md | 673 ++++++------------------------------------------------ 2 files changed, 82 insertions(+), 613 deletions(-) diff --git a/MPCNC.cps b/MPCNC.cps index 4322740..9350777 100644 --- a/MPCNC.cps +++ b/MPCNC.cps @@ -111,7 +111,7 @@ propertyDefinitions = { job0_SelectedFirmware: { title: "Job: CNC Firmware", description: "Dialect of GCode to create", group: 1, - type: "integer", default_mm: 0, default_in: 0, + type: "integer", default_mm: eFirmware.MARLIN, default_in: eFirmware.MARLIN, values: [ { title: eFirmware.prop[eFirmware.MARLIN].name, id: eFirmware.MARLIN }, { title: eFirmware.prop[eFirmware.GRBL].name, id: eFirmware.GRBL }, @@ -129,7 +129,7 @@ propertyDefinitions = { }, job3_CommentLevel: { title: "Job: Comment Level", description: "Controls the comments include", group: 1, - type: "integer", default_mm: 3, default_in: 3, + type: "integer", default_mm: eComment.Info, default_in: eComment.Info, values: [ { title: eComment.prop[eComment.Off].name, id: eComment.Off }, { title: eComment.prop[eComment.Important].name, id: eComment.Important }, @@ -158,7 +158,7 @@ propertyDefinitions = { type: "boolean", default_mm: true, default_in: true }, job9_GoOriginOnFinish: { - title: "Job: At end go to 0,0", description: "Go to X0 Y0 at gcode end, Z unchanged", group: 1, + title: "Job: At end go to 0,0", description: "Go to X0 Y0 at gcode end, Z remains unchanged", group: 1, type: "boolean", default_mm: true, default_in: true }, @@ -187,7 +187,7 @@ propertyDefinitions = { type: "spatial", default_mm: 180, default_in: 7.08 }, frD_MaxCutSpeedXYZ: { - title: "Feed: Max Toolpath Speed", description: "Maximum scaled feedrate (mm/min; in/min)", group: 2, + title: "Feed: Max Toolpath Speed", description: "Maximum scaled feedrate for toolpath (mm/min; in/min)", group: 2, type: "spatial", default_mm: 1000, default_in: 39.37 }, @@ -205,7 +205,7 @@ propertyDefinitions = { }, mapG_AllowRapidZ: { title: "Map: Allow Rapid Z", description: "Enable to include vertical retracts and safe descents", group: 3, - type: "boolean", default_mm: true, default_in: true + type: "boolean", default_mm: false, default_in: false }, toolChange0_Enabled: { @@ -234,7 +234,7 @@ propertyDefinitions = { type: "boolean", default_mm: false, default_in: false }, probe2_OnToolChange: { - title: "Probe: Afterward Tool Change", description: "After tool change, probe Z at the current location", group: 5, + title: "Probe: After Tool Change", description: "After tool change, probe Z at the current location", group: 5, type: "boolean", default_mm: false, default_in: false }, probe3_Thickness: { @@ -246,11 +246,11 @@ propertyDefinitions = { type: "boolean", default_mm: true, default_in: true }, probe5_G38Target: { - title: "Probe: G38 target", description: "Probing's furthest Z position", group: 5, + title: "Probe: G38 target", description: "G38 Probing's furthest Z position", group: 5, type: "spatial", default_mm: -10, default_in: -0.5 }, probe6_G38Speed: { - title: "Probe: G38 speed", description: "Probing's speed (mm/min; in/min)", group: 5, + title: "Probe: G38 speed", description: "G38 Probing's speed (mm/min; in/min)", group: 5, type: "spatial", default_mm: 30, default_in: 1.2 }, @@ -267,7 +267,7 @@ propertyDefinitions = { type: "number", default_mm: 40, default_in: 40 }, cutterMarlinMode: { - title: "Laser: Marlin/Reprap mode", description: "Marlin/Reprap mode of the laser/plasma cutter", group: 6, + title: "Laser: Marlin/Reprap Mode", description: "Marlin/Reprap mode of the laser/plasma cutter", group: 6, type: "integer", default_mm: 106, default_in: 106, values: [ { title: "Fan - M106 S{PWM}/M107", id: 106 }, @@ -276,11 +276,11 @@ propertyDefinitions = { ] }, cutterMarlinPin: { - title: "Laser: Marlin M42 pin", description: "Marlin custom pin number for the laser/plasma cutter", group: 6, + title: "Laser: Marlin M42 Pin", description: "Marlin custom pin number for the laser/plasma cutter", group: 6, type: "integer", default_mm: 4, default_in: 4 }, cutterGrblMode: { - title: "Laser: GRBL mode", description: "GRBL mode of the laser/plasma cutter", group: 6, + title: "Laser: GRBL Mode", description: "GRBL mode of the laser/plasma cutter", group: 6, type: "integer", default_mm: 4, default_in: 4, values: [ { title: "M4 S{PWM}/M5 dynamic power", id: 4 }, diff --git a/README.md b/README.md index 764028e..4a85d42 100644 --- a/README.md +++ b/README.md @@ -13,26 +13,22 @@ Supported firmwares: - RepRap firmware (Duet3d) Installation: -- The post processor has three .cps files. -- Each .csp file is considered by F360 to be a seperate Post Processor. -- Currently each .cps file depends on DIYCNC_common.js. -- Can not use F360 Manage->Post Library menu to install the post processor -as the DIYCNC_common.js will not be installed. -- Instead copy the .cps file and DIYCNC_common.js -to the F360 install director or use the ... to select to the post processor's directory when -running the post processor. +- The post processor consists of a single file, mpcnc.cps. +- It can be simply installed by selecting Manage->Post Library from the Fusion 360 menubar; alternatively the mpcnc.cps can be copied into a directory and selecting each time prior to a post operation. If there is an existing mpcnc.cps installed select it prior to installing and use the trash can icon to delete it +- The desired post processor can be selected during a post using the Setup button and selecting Use Personal Post Library +- Use the Job: CNC Firmware property to select between Marlin 2.x, Grbl 1.1 and RepRap firmware Some design points: - Setup operation types: Milling, Water/Laser/Plasma - Support mm and Inches units (**but all properties MUST be set in MM**) -- Rapids movements use seperate G0 moves, first to move in Z and then to move in XY. Moves use independent travel speeds for XY and Z. +- Rapids movements use two G0 moves. The first moves Z and the second moves XY. Moves are seperate to allow retraction from the work surface prior to horizontal travel. Moves use independent travel speeds for Z and XY. - Arcs support on XY plane (Marlin/Repetier/RepRap) or all panes (Grbl) - Tested with LCD display and SD card (built in tool change require printing from SD and LCD to restart) - Support for 3 different laser power using "cutting modes" (through, etch, vaporize) - Support 2 coolant channels. You may attach relays to control external devices - as example air jet valve. - Customizable level of verbosity of comments - Support line numbers -- Support GRBL laser mode (**be noted that you probably to have enabled laser mode [$32=1](https://github.com/gnea/grbl/wiki/Grbl-v1.1-Laser-Mode)**) +- Support GRBL laser mode (**note: you probably have to enabled laser mode [$32=1](https://github.com/gnea/grbl/wiki/Grbl-v1.1-Laser-Mode)**) ![screenshot](/screenshot.jpg "screenshot") @@ -43,19 +39,16 @@ Use these properties to control overall aspects of the job. |Title|Description|Default| |---|---|---| -Job: Duet: Milling Mode|GCode command to setup Duet3d milling mode.|**"M453 P2 I0 R30000 F200"**| -Job: Duet: Laser Mode|GCode command to setup Duet3d laser mode.|**"M452 P2 I0 R255 F200"**| -Job: Goto 0 at end|Go X0 Y0 at gcode end. Useful to find if your machine loss steeps or have any other mechanic issue (like loose pulleys). Also useful for repetitive jobs. Only apply if not using gcodeStopFile.|**true**| -Job: Marlin: Manual Spindle On/Off|Set it to true when the motor of your spindle is controlled by manual switch. So the preprocessor will issue additional pauses for TURN ON/TURN OFF the motor.|**true**| -Job: Marlin: Enforce feedrate|Add feedrate to each movement g-code.|**false**| -Job: Separate words|Specifies that the words should be separated with a white space.|**true**| -Job: Line increment|Increment for sequence numbers.|**1**| -Job: Line start|First sequence number.|**10**| -Job: Line numbers|Show sequence numbers.|**false**| -Job: Reset on start (G92)|Set origin when gcode start (G92 X0 Y0 Z0). Only apply if not using -GcodeStartFile.|**true**| +Job: CNC Firmware|Dialect of GCode to create|**Marlin 2.x**| +Job: Job: Zero Starting Location (G92)|On start set the current location as 0,0,0 (G92).|**true**| +Job: Manual Spindle On/Off|Enable to manually turn spindle motor on/off. Post processor will issue additional pauses for TURN ON/TURN OFF the motor.|**true**| +Job: Comment Level|Controls a increasing level of comments to be included: Off, Important, Info, Debug|**Info**| Job: Use Arcs|Use G2/G3 g-codes for circular movements.|**true**| -Job: Firmware|Target firmware (marlin 2.0 or Repetir 1.0.3 / GRBL 1.1) / RepRap Firmware.|**Marlin**| +Job: Enable Line #s|Show sequence numbers.|**false**| +Job: First Line #|First sequence number.|**1**| +Job: Line # Increment|Sequence number increment.|**10**| +Job: Include Whitespace|Includes whitespace seperation between text.|**true**| +Job: At end go to 0,0|Go to X0 Y0 at gcode end, Z remains unchanged.|**true**| ## Group 2: Travel Speed and Feedrate Scaling Properties Use these properties to set the speed used for G0 Rapids and to scale the feedrate used @@ -63,77 +56,76 @@ for G1 cuts. [Feed: Travel Speed X/Y] and [Feed: Travel Speed Z] are always used for G0 Rapids. -Scaling of the G1 cut feedrates will only occur if [Feed:Scaled feedrate] is true. +Scaling of the G1 cut feedrates will only occur if [Feed:Scaled Feedrate] is true. Scaling ensures that no G1 cut exceeds the speed capablities of the X, Y, or Z axes. The cut's toolpath feedrate is projected onto the X, Y and Z axes. In turn each axis is tested to see if its cut speed is within the limits of that axis. If not, then all axes feedrates are scaled proportionatly to bring it within limits. This is repeated for all axes. The three axis feedrates are then merged to create a new toolpath feedrate which is then limited to ensure it -doesn't exceed [Feed: Max toolpath speed]. +doesn't exceed [Feed: Max Toolpath Speed]. Note: Because scaling considered 3 dimensional movement a resulting toolpath's feedrate may be greater then one or all of the X, Y or Z limits. For example, a small movement in Z compared to a much larger movement in XY may result in a feedrate that appears to exceed the capability of -Z but in reality since Z is move a much smaller distance for the same time period its actual feedrate is within the established limits. +Z but in reality since Z is moving a much smaller distance for the same time period its actual +feedrate is within the established limits. |Title|Description|Default| |---|---|---| Feed: Travel Speed X/Y|High speed for travel movements X & Y (mm/min).|**2500 mm/min**| Feed: Travel Speed Z|High speed for travel movements Z (mm/min).|**300 mm/min**| -Feed: Scaled feedrate|Scale cut feedrates to respect XY and Z max cut speeds.|**false**| -Feed: Max cut speed X or Y|Maximum cut speed along the X or Y axes (mm/min).|**900 mm/min**| -Feed: Max cut speed Z|Maximum cut speed along the Z axis (mm/min).|**180 mm/min**| -Feed: Max toolpath speed|Maximum cut speed along the toolpath (mm/min).|**1000 mm/min**| - - - +Feed: Enforce Feedrate|Forces the Fxxx to be include even if hasn't changed, useful for Marlin.|**true**| +Feed: Scaled Feedrate|Scale feedrate based on X, Y, Z axis maximums.|**false**| +Feed: Max Cut Speed X or Y|Maximum X or Y axis cut speed (mm/min).|**900 mm/min**| +Feed: Max Cut Speed Z|Maximum Z axis cut speed (mm/min).|**180 mm/min**| +Feed: Max Toolpath Speed|Maximum scaled feedrate for toolpath (mm/min).|**1000 mm/min**| ## Group 3: Map G1->G0 Properties -Performs three actions by allowing G1 cuts to be mapped to G0 Rapid movements. +Allows G1 cuts to be converted to G0 Rapid movements in specific cases: -1. If [Map: First G1 -> G0 Rapids] is true the post processor resolves the loss of the +If [Map: First G1 -> G0 Rapid] is true the post processor resolves the lost initial positioning movement at the beginning of a cut toolpath. This problem is often identified in forums as the tool being initially dragged across the work surface. -2. If [Map: G1 -> G0] is true then allows G1 XY cut movements (i.e. no change in Z) that occur -at a height greater or equal to [Map: Safe Z for Rapids] to be converted to G0 Rapids. +If [Map: G1s -> G0s] is true then allows G1 XY cut movements (i.e. no change in Z) that occur +at a height greater or equal to [Map: Safe Z to Rapid] to be converted to G0 Rapids. Note: this assumes that the top of material is 0 in F360 and that any Z above -[Map: Safe Z for Rapids] is a movement in the air. If top of material is not 0, then adjust -[Map: Safe Z for Rapids] appropriately. +[Map: Safe Z to Rapid] is a movement in the air and clear of obstacles. If top of material is not 0 +or there are holddown clamp then adjust [Map: Safe Z to Rapid] appropriately. -3. If [Map: Allow Rapid Z] is true then includes G1 Z cut movements that either move straight up -and end above [Map: Safe Z for Rapids], or straight down with the start and end positions both -above [Map: Safe Z for Rapids]. Only occurs if [Map: G1 -> G0] is also true. +If [Map: Allow Rapid Z] is true then G1 Z cut movements that either move straight up +and end above [Map: Safe Z to Rapid], or straight down with the start and end positions both +above [Map: Safe Z to Rapid] are included. Only occurs if [Map: G1s -> G0s] is also true. |Title|Description|Default| |---|---|---| -Map: First G1 -> G0 Rapids|Convert first G1 of a cut to G0 Rapid|**false**| -Map: G1 -> G0|Allow G1 cuts to be converted to Rapid G0 moves when safe and appropriate.|**false**| +Map: First G1 -> G0 Rapid|Converts the first G1 of a cut to G0 Rapid|**false**| +Map: G1s -> G0s|Allow G1 cuts to be converted to Rapid G0 moves when safe and appropriate.|**false**| Map: Safe Z for Rapids|A G1 cut's Z must be >= to this to be mapped to a Rapid G0.|**10**| -Map: Allow Rapid Z|Include vertical cut if they are safe.|**true**| +Map: Allow Rapid Z|Include vertical cut if they are safe.|**false**| ## Group 4: Tool change Properties |Title|Description|Default| |---|---|---| -Change: Disable Z stepper|Disable Z stepper when change a tool|**false**| -Change: Enabled|Enable tool change code (bultin tool change requires LCD display)|**true**| -Change: X|X position for builtin tool change|**0**| -Change: Y|Y position for builtin tool change|**0**| -Change: Z|Z position for builtin tool change|**40**| -Change: Make Z Probe|Z probe after tool change|**true**| +Tool Change: Enable|Include tool change code when tool changes (bultin tool change requires LCD display|**false**| +Tool Change: X|X position for builtin tool change|**0**| +Tool Change: Y|Y position for builtin tool change|**0**| +Tool Change: Z|Z position for builtin tool change|**40**| +Tool Change: Disable Z stepper|Disable Z stepper after reaching tool change location|**false**| ## Group 5: Z Probe Properties |Title|Description|Default| |---|---|---| -Probe: On job start|Execute probe gcode on job start|**true**| +Probe: On job start|Execute probe gcode on job start|**false**| +Probe: After Tool Change|Z probe after tool change|**false**| Probe: Plate thickness|Plate thickness|**0.8**| -Probe: Use Home Z|Use G28 or G38 for probing|**true**| -Probe: G38 target|Probing up to Z position|**-10**| -Probe: G38 speed|Probing with speed|**30**| +Probe: Use Home Z (G28)|Probe with G28 (Yes) or G38 (No)|**true**| +Probe: G38 target|G38 Probing's furthest Z position|**-10**| +Probe: G38 speed|G38 Probing's speed|**30**| ## Group 6: Laser/Plasma Properties @@ -142,24 +134,11 @@ Probe: G38 speed|Probing with speed|**30**| Laser: On - Vaporize|Persent of power to turn on the laser/plasma cutter in vaporize mode|**100**|| Laser: On - Through|Persent of power to turn on the laser/plasma cutter in through mode|**80**|| Laser: On - Etch|Persent of power to turn on the laser/plasma cutter in etch mode|**40**|| -Laser: Marlin mode|Marlin mode of the laser/plasma cutter ()|**M106**|M106 S{PWM}/M107 = 0; M3 O{PWM}/M5 = 1; M42 P{pin} S{PWM} = 2;| -Laser: Marlin pin|Marlin custom pin number for the laser/plasma cutter|**4**|| -Laser: GRBL mode|GRBL mode of the laser/plasma cutter|**M4**|M4 S{PWM}/M5 dynamic power = 4; M3 S{PWM}/M5 static power = 3;| - -## Group 7: Coolant Control Pin Properties - -|Title|Description|Default|Values| -|---|---|---|---| -Coolant: A Mode|Enable issuing g-codes for control Coolant channel A|**0**|off=0; flood=1; mist=2; throughTool=3; air=4; airThroughTool=5; suction=6; floodMist=7; floodThroughTool=8| -Coolant: A Marlin On command|GCode command to turn on Coolant channel A|**M42 P11 S255**|| -Coolant: A Marlin Off command|Gcode command to turn off Coolant A|**M42 P11 S0**|| -Coolant: A GRBL|GRBL g-codes for control Coolant channel A|**M7**|M7 flood = 7; M8 mist = 8| -Coolant: B Mode|Enable issuing g-codes for control Coolant channel B|**0**|off=0; flood=1; mist=2; throughTool=3; air=4; airThroughTool=5; suction=6; floodMist=7; floodThroughTool=8| -Coolant: B Marlin On command|GCode command to turn on Coolant channel B|**M42 P6 S255**|| -Coolant: B Marlin Off command|Gcode command to turn off Coolant channel B|**M42 P6 S0**|| -Coolant: B GRBL|GRBL g-codes for control Coolant channel B|**M8**|M7 flood = 7; M8 mist = 8| +Laser: Marlin/Reprap Mode|Marlin/Reprap mode of the laser/plasma cutter|**Fan - M106 S{PWM}/M107**|"Fan - M106 S{PWM}/M107", "Spindle - M3 O{PWM}/M5", "Pin - M42 P{pin} S{PWM}"| +Laser: Marlin M42 Pin|Marlin custom pin number for the laser/plasma cutter|**4**|| +Laser: GRBL Mode|GRBL mode of the laser/plasma cutter|**M4 S{PWM}/M5 dynamic power**|"M4 S{PWM}/M5 dynamic power", "M3 S{PWM}/M5 static power"| -## Group 8: Override Behaviour by External File Properties +## Group 7: Override Behaviour by External File Properties |Title|Description|Default| |---|---|---| @@ -168,547 +147,37 @@ Extern: Stop File|File with custom Gcode for footer/end (in nc folder)|| Extern: Tool File|File with custom Gcode for tool change (in nc folder)|| Extern: Probe File|File with custom Gcode for tool probe (in nc folder)|| -## Group 9: Write Comments Properties - -|Title|Description|Default| -|---|---|---| -Comment: Write Tools|Write table of used tools in job header|true| -Comment: Sections|Write header of every section|true| -Comment: Activities|Write comments which somehow helps to understand current piece of g-code|true| -Comment: Trace Commands|Write stringified commands called by CAM|true| -Comment: Trace Movements|Write stringified movements called by CAM|true| +## Group 7: Coolant Control Pin Properties +Coolant has two channels, A and B. Each channel can be configured to be off or set to 1 of the 8 coolant modes that Fusion 360 allows on operation. If a tool's collant requirements match a channel's setting then that channel is enabled, Channel A has priority. Setting both channels' mode to off disables coolant but will produce a warning if a tool askes +for coolant. -# Sample of issued code blocks +If a channel becomes Enabled by matching the coolant requested by the tool then the channel is physically enabled by the post processor by including the text associated with the corresponding property [Coolant \ Enable]. Note, Marlin and Grbl values are included as options, you must select based on your actual configuration. The firmware selected in property [Job: CNC Firmware] will not override your selection. -## Gcode of milling with manually control spindel +If a channel needs to be Disabled because it no longer matchs the coolant requested then the channel is physically disabled by the post processor by including the text associated with the corresponding property [Coolant \ Disable]. Note, Marlin and Grbl values are included as options, you must select based on your actual configuration. The firmware selected in the propery [Job: CNC Firmware] will not override your selection. -```G-code -;Fusion 360 CAM 2.0.4860 -; Posts processor: MPCNC_Mill_Laser.cps -; Gcode generated: Sunday, December 2, 2018 1:57:21 PM GMT -; Document: cam_testpp v5 -; Setup: Setup1 -; -; Ranges table: -; X: Min=2.588 Max=36 Size=33.412 -; Y: Min=2.588 Max=36 Size=33.412 -; Z: Min=-1 Max=15 Size=16 -; -; Tools table: -; T1 D=3.175 CR=0 - ZMIN=-1 - flat end mill -; T2 D=1.5 CR=0 - ZMIN=-1 - flat end mill - -; *** START begin *** -G90 -G21 -M84 S0 -G92 X0 Y0 Z0 -; COMMAND_TOOL_MEASURE -; --- PROBE TOOL begin --- -M0 Attach ZProbe -G28 Z -G92 Z0.8 -G0 Z50 F300 -M0 Detach ZProbe -; --- PROBE TOOL end --- -; *** START end *** - -; *** SECTION begin *** -;2D Contour1 - Milling - Tool: 1 - 1/8inch flat end mill -; X Min: 2.588 - X Max: 49.412 -; Y Min: 2.588 - Y Max: 49.412 -; Z Min: -1 - Z Max: 15 -M400 -; COMMAND_START_SPINDLE -; COMMAND_SPINDLE_CLOCKWISE -M0 Turn ON spindle -; COMMAND_COOLANT_ON -M117 2D Contour1 -G0 Z15 -G0 X49.412 Y26 F2500 -G0 Z5 F300 -; MOVEMENT_PLUNGE -G1 Z1 F100 -G1 Z-1 -; 14 -G1 Y49.412 F300 -G1 X2.588 -G1 Y2.588 -G1 X49.412 -G1 Y26 -; MOVEMENT_RAPID -G0 Z15 -; *** SECTION end *** - -; *** SECTION begin *** -;2D Contour2 - Milling - Tool: 1 - 1/8inch flat end mill -; X Min: 9.587 - X Max: 42.412 -; Y Min: 9.587 - Y Max: 42.412 -; Z Min: -1 - Z Max: 15 -M400 -; COMMAND_START_SPINDLE -; COMMAND_SPINDLE_CLOCKWISE -; COMMAND_COOLANT_ON -M117 2D Contour2 -G0 Z15 F300 -G0 X42.412 Y26 F2500 -G0 Z5 F300 -; MOVEMENT_PLUNGE -G1 Z1 F100 -G1 Z-1 -; 14 -G1 Y42.412 F300 -G1 X9.587 -G1 Y9.587 -G1 X42.412 -G1 Y26 -; MOVEMENT_RAPID -G0 Z15 -; *** SECTION end *** - -; *** SECTION begin *** -; --- CHANGE TOOL begin --- -; COMMAND_COOLANT_OFF -M400 -M300 S400 P2000 -G0 Z50 F300 -G0 X0 Y0 F2500 -; COMMAND_STOP_SPINDLE -M0 Turn OFF spindle -M0 Put tool 2 - 1.5mm -; COMMAND_TOOL_MEASURE -; --- PROBE TOOL begin --- -M0 Attach ZProbe -G28 Z -G92 Z0.8 -G0 Z50 F300 -M0 Detach ZProbe -; --- PROBE TOOL end --- -; --- CHANGE TOOL end --- -;Trace1 - Milling - Tool: 2 - 1.5mm flat end mill -; X Min: 16 - X Max: 36 -; Y Min: 16 - Y Max: 36 -; Z Min: -1 - Z Max: 15 -M400 -; COMMAND_START_SPINDLE -; COMMAND_SPINDLE_CLOCKWISE -M0 Turn ON spindle -; COMMAND_COOLANT_ON -M117 Trace1 -G0 Z15 -G0 X36 Y36 F2500 -G0 Z4 F300 -; MOVEMENT_LEAD_IN -G1 Z-1 F300 -; MOVEMENT_CUTTING -G1 Y16 -G1 X16 -G1 Y36 -G1 X36 -; MOVEMENT_LEAD_OUT -G1 Z4 -; MOVEMENT_RAPID -G0 Z15 -; *** SECTION end *** - -; *** STOP begin *** -M400 -; COMMAND_COOLANT_OFF -; COMMAND_STOP_SPINDLE -M0 Turn OFF spindle -G0 X0 Y0 F2500 -M117 Job end -; *** STOP end *** -``` - -## Gcode of milling with spindel controlled by M3/M4/M5 +|Title|Description|Default|Values| +|---|---|---|---| +Coolant: A Mode|Enable channel A when tool is set this coolant|**off**|off, flood, mist, throughTool, air, airThroughTool, suction, floodMist, floodThroughTool| +Coolant: B Mode|Enable channel B when tool is set this coolant|**off**|off, flood, mist, throughTool, air, airThroughTool, suction, floodMist, floodThroughTool| +Coolant: A Enable|GCode to turn On coolant channel A|**Mrln: M42 P6 S255**|"Mrln: M42 P6 S255", , Mrln: M42 P11 S255", "Grbl: M7 (mist)", "Grbl: M8 (flood)"| +Coolant: A Disable Off command|GCode to turn Off coolant channel A|**Mrln: M42 P6 S0**|"Mrln: M42 P6 S0", "Mrln: M42 P11 S0", "Grbl: M9 (off)"| +Coolant: B Enable|GCode to turn On coolant channel B|**Mrln: M42 P11 S255**|"Mrln: M42 P11 S255", "Mrln: M42 P6 S255", "Grbl: M7 (mist)", "Grbl: M8 (flood)"| +Coolant: B Disable Off command|GCode to turn Off coolant channel B|**Mrln: M42 P11 S0**|"Mrln: M42 P11 S0", "Mrln: M42 P6 S0", "Grbl: M9 (off)"| -```G-code -;Fusion 360 CAM 2.0.4860 -; Posts processor: MPCNC_Mill_Laser.cps -; Gcode generated: Sunday, December 2, 2018 1:56:26 PM GMT -; Document: cam_testpp v5 -; Setup: Setup1 -; -; Ranges table: -; X: Min=2.588 Max=36 Size=33.412 -; Y: Min=2.588 Max=36 Size=33.412 -; Z: Min=-1 Max=15 Size=16 -; -; Tools table: -; T1 D=3.175 CR=0 - ZMIN=-1 - flat end mill -; T2 D=1.5 CR=0 - ZMIN=-1 - flat end mill - -; *** START begin *** -G90 -G21 -M84 S0 -G92 X0 Y0 Z0 -; COMMAND_TOOL_MEASURE -; --- PROBE TOOL begin --- -M0 Attach ZProbe -G28 Z -G92 Z0.8 -G0 Z50 F300 -M0 Detach ZProbe -; --- PROBE TOOL end --- -; *** START end *** - -; *** SECTION begin *** -;2D Contour1 - Milling - Tool: 1 - 1/8inch flat end mill -; X Min: 2.588 - X Max: 49.412 -; Y Min: 2.588 - Y Max: 49.412 -; Z Min: -1 - Z Max: 15 -M400 -; COMMAND_START_SPINDLE -; COMMAND_SPINDLE_CLOCKWISE -; >>> Spindle Speed 21000 -M3 S21000 -; COMMAND_COOLANT_ON -M117 2D Contour1 -G0 Z15 -G0 X49.412 Y26 F2500 -G0 Z5 F300 -; MOVEMENT_PLUNGE -G1 Z1 F100 -G1 Z-1 -; 14 -G1 Y49.412 F300 -G1 X2.588 -G1 Y2.588 -G1 X49.412 -G1 Y26 -; MOVEMENT_RAPID -G0 Z15 -; *** SECTION end *** - -; *** SECTION begin *** -;2D Contour2 - Milling - Tool: 1 - 1/8inch flat end mill -; X Min: 9.587 - X Max: 42.412 -; Y Min: 9.587 - Y Max: 42.412 -; Z Min: -1 - Z Max: 15 -M400 -; COMMAND_START_SPINDLE -; COMMAND_SPINDLE_CLOCKWISE -; >>> Spindle Speed 20000 -M3 S20000 -; COMMAND_COOLANT_ON -M117 2D Contour2 -G0 Z15 F300 -G0 X42.412 Y26 F2500 -G0 Z5 F300 -; MOVEMENT_PLUNGE -G1 Z1 F100 -G1 Z-1 -; 14 -G1 Y42.412 F300 -G1 X9.587 -G1 Y9.587 -G1 X42.412 -G1 Y26 -; MOVEMENT_RAPID -G0 Z15 -; *** SECTION end *** - -; *** SECTION begin *** -; --- CHANGE TOOL begin --- -; COMMAND_COOLANT_OFF -M400 -M300 S400 P2000 -G0 Z50 F300 -G0 X0 Y0 F2500 -; COMMAND_STOP_SPINDLE -M5 -M0 Put tool 2 - 1.5mm -; COMMAND_TOOL_MEASURE -; --- PROBE TOOL begin --- -M0 Attach ZProbe -G28 Z -G92 Z0.8 -G0 Z50 F300 -M0 Detach ZProbe -; --- PROBE TOOL end --- -; --- CHANGE TOOL end --- -;Trace1 - Milling - Tool: 2 - 1.5mm flat end mill -; X Min: 16 - X Max: 36 -; Y Min: 16 - Y Max: 36 -; Z Min: -1 - Z Max: 15 -M400 -; COMMAND_START_SPINDLE -; COMMAND_SPINDLE_CLOCKWISE -; >>> Spindle Speed 21000 -M3 S21000 -; COMMAND_COOLANT_ON -M117 Trace1 -G0 Z15 -G0 X36 Y36 F2500 -G0 Z4 F300 -; MOVEMENT_LEAD_IN -G1 Z-1 F300 -; MOVEMENT_CUTTING -G1 Y16 -G1 X16 -G1 Y36 -G1 X36 -; MOVEMENT_LEAD_OUT -G1 Z4 -; MOVEMENT_RAPID -G0 Z15 -; *** SECTION end *** - -; *** STOP begin *** -M400 -; COMMAND_COOLANT_OFF -; COMMAND_STOP_SPINDLE -M5 -G0 X0 Y0 F2500 -M117 Job end -; *** STOP end *** -``` +## Group 9: Duet Properties -## Gcode of milling with spindel controlled by M3/M4/M5 with using Coolants (both A and B channels) +|Title|Description|Default| +|---|---|---| +Duet: Milling mode|GCode command to setup Duet3d milling mode|**M453 P2 I0 R30000 F200**| +Duet: Laser mode|GCode command to setup Duet3d laser mode|**M452 P2 I0 R255 F200**| -```G-code -;Fusion 360 CAM 2.0.4860 -; Posts processor: MPCNC_Mill_Laser.cps -; Gcode generated: Sunday, December 2, 2018 2:06:54 PM GMT -; Document: cam_testpp v5 -; Setup: Setup1 -; -; Ranges table: -; X: Min=2.588 Max=36 Size=33.412 -; Y: Min=2.588 Max=36 Size=33.412 -; Z: Min=-1 Max=15 Size=16 -; -; Tools table: -; T1 D=3.175 CR=0 - ZMIN=-1 - flat end mill -; T2 D=1.5 CR=0 - ZMIN=-1 - flat end mill - -; *** START begin *** -G90 -G21 -M84 S0 -G92 X0 Y0 Z0 -; COMMAND_TOOL_MEASURE -; --- PROBE TOOL begin --- -M0 Attach ZProbe -G28 Z -G92 Z0.8 -G0 Z50 F300 -M0 Detach ZProbe -; --- PROBE TOOL end --- -; *** START end *** - -; *** SECTION begin *** -;2D Contour1 - Milling - Tool: 1 - 1/8inch flat end mill -; X Min: 2.588 - X Max: 49.412 -; Y Min: 2.588 - Y Max: 49.412 -; Z Min: -1 - Z Max: 15 -M400 -; COMMAND_START_SPINDLE -; COMMAND_SPINDLE_CLOCKWISE -; >>> Spindle Speed 21000 -M3 S21000 -; COMMAND_COOLANT_ON -; >>> Coolant A ON -M42 P11 S255 -M117 2D Contour1 -G0 Z15 -G0 X49.412 Y26 F2500 -G0 Z5 F300 -; MOVEMENT_PLUNGE -G1 Z1 F100 -G1 Z-1 -; 14 -G1 Y49.412 F300 -G1 X2.588 -G1 Y2.588 -G1 X49.412 -G1 Y26 -; MOVEMENT_RAPID -G0 Z15 -; *** SECTION end *** - -; *** SECTION begin *** -;2D Contour2 - Milling - Tool: 1 - 1/8inch flat end mill -; X Min: 9.587 - X Max: 42.412 -; Y Min: 9.587 - Y Max: 42.412 -; Z Min: -1 - Z Max: 15 -M400 -; COMMAND_START_SPINDLE -; COMMAND_SPINDLE_CLOCKWISE -; >>> Spindle Speed 20000 -M3 S20000 -; COMMAND_COOLANT_ON -; >>> Coolant A OFF -M42 P11 S0 -; >>> Coolant B ON -M42 P6 S255 -M117 2D Contour2 -G0 Z15 F300 -G0 X42.412 Y26 F2500 -G0 Z5 F300 -; MOVEMENT_PLUNGE -G1 Z1 F100 -G1 Z-1 -; 14 -G1 Y42.412 F300 -G1 X9.587 -G1 Y9.587 -G1 X42.412 -G1 Y26 -; MOVEMENT_RAPID -G0 Z15 -; *** SECTION end *** - -; *** SECTION begin *** -; --- CHANGE TOOL begin --- -M400 -G0 Z50 F300 -G0 X0 Y0 F2500 -; COMMAND_COOLANT_OFF -; >>> Coolant B OFF -M42 P6 S0 -; COMMAND_STOP_SPINDLE -M5 -M300 S400 P2000 -M0 Put tool 2 - 1.5mm -; COMMAND_TOOL_MEASURE -; --- PROBE TOOL begin --- -M0 Attach ZProbe -G28 Z -G92 Z0.8 -G0 Z50 F300 -M0 Detach ZProbe -; --- PROBE TOOL end --- -; --- CHANGE TOOL end --- -;Trace1 - Milling - Tool: 2 - 1.5mm flat end mill -; X Min: 16 - X Max: 36 -; Y Min: 16 - Y Max: 36 -; Z Min: -1 - Z Max: 15 -M400 -; COMMAND_START_SPINDLE -; COMMAND_SPINDLE_CLOCKWISE -; >>> Spindle Speed 21000 -M3 S21000 -; COMMAND_COOLANT_ON -M117 Trace1 -G0 Z15 -G0 X36 Y36 F2500 -G0 Z4 F300 -; MOVEMENT_LEAD_IN -G1 Z-1 F300 -; MOVEMENT_CUTTING -G1 Y16 -G1 X16 -G1 Y36 -G1 X36 -; MOVEMENT_LEAD_OUT -G1 Z4 -; MOVEMENT_RAPID -G0 Z15 -; *** SECTION end *** - -; *** STOP begin *** -M400 -; COMMAND_COOLANT_OFF -; COMMAND_STOP_SPINDLE -M5 -G0 X0 Y0 F2500 -M117 Job end -; *** STOP end *** -``` +# Sample of issued code blocks -## Gcode of laser cutting +## Gcode of milling with manually control spindel ```G-code -;Fusion 360 CAM 2.0.4860 -; Posts processor: MPCNC_Mill_Laser.cps -; Gcode generated: Sunday, December 2, 2018 2:07:32 PM GMT -; Document: cam_testpp v5 -; Setup: Setup2 -; -; Ranges table: -; X: Min=-25 Max=25 Size=50 -; Y: Min=-25.5 Max=25 Size=50.5 -; Z: Min=0 Max=15 Size=15 -; -; Tools table: -; T1 D=0 CR=0 - ZMIN=0 - laser cutter - -; *** START begin *** -G90 -G21 -M84 S0 -G92 X0 Y0 Z0 -; COMMAND_TOOL_MEASURE -; *** START end *** - -; *** SECTION begin *** -;2D Profile1 - Laser/Plasma - Cutting mode: auto -; X Min: -25 - X Max: 25 -; Y Min: -25.5 - Y Max: 25 -; Z Min: 0 - Z Max: 15 -M400 -; COMMAND_START_SPINDLE -; COMMAND_SPINDLE_COUNTERCLOCKWISE -; COMMAND_COOLANT_ON -M117 2D Profile1 -G0 Z15 F300 -G0 X-9.94 Y-10.5 F2500 -G0 Z0 F300 -; >>> LASER Power ON -M106 S200 -; COMMAND_POWER_ON -; MOVEMENT_LEAD_IN -G1 Y-10 F1000 -G1 X-9.95 -; MOVEMENT_CUTTING -G1 X-10 -G1 Y10 -G1 X10 -G1 Y-10 -G1 X-9.95 -; MOVEMENT_LEAD_OUT -G1 X-9.96 -G1 Y-10.5 -; >>> LASER Power OFF -M107 -; COMMAND_POWER_OFF -; MOVEMENT_RAPID -G0 Z5 F300 -G0 X-9.99 Y-25.5 F2500 -G0 Z0 F300 -; >>> LASER Power ON -M106 S200 -; COMMAND_POWER_ON -; MOVEMENT_LEAD_IN -G1 Y-25 F1000 -G1 X-10 -; MOVEMENT_CUTTING -G1 X-25 -G1 Y25 -G1 X25 -G1 Y-25 -G1 X-10 -; MOVEMENT_LEAD_OUT -G1 X-10.01 -G1 Y-25.5 -; >>> LASER Power OFF -M107 -; COMMAND_POWER_OFF -; MOVEMENT_RAPID -G0 Z15 F300 -; *** SECTION end *** - -; *** STOP begin *** -M400 -; COMMAND_COOLANT_OFF -; COMMAND_STOP_SPINDLE -G0 X0 Y0 F2500 -M117 Job end -; *** STOP end *** +To be updated ``` # Resorces From 340edc81c337059fd5b6bb9a0a4a0ce4305de483 Mon Sep 17 00:00:00 2001 From: flyfisher604 Date: Fri, 5 Feb 2021 17:36:45 -0800 Subject: [PATCH 14/24] Remove unneeded files --- DIYCNC_Common.js | 1349 ------------------------------------------- DIYCNC_Grbl11.cps | 147 ----- DIYCNC_Marlin20.cps | 21 - DIYCNC_RepRapFW.cps | 65 --- 4 files changed, 1582 deletions(-) delete mode 100644 DIYCNC_Common.js delete mode 100644 DIYCNC_Grbl11.cps delete mode 100644 DIYCNC_Marlin20.cps delete mode 100644 DIYCNC_RepRapFW.cps diff --git a/DIYCNC_Common.js b/DIYCNC_Common.js deleted file mode 100644 index f083579..0000000 --- a/DIYCNC_Common.js +++ /dev/null @@ -1,1349 +0,0 @@ -/* - -https://github.com/flyfisher604/mpcnc_post_processor - -MPCNC posts processor for milling and laser/plasma cutting. - -*/ - -// Internal properties -certificationLevel = 2; -extension = "gcode"; -setCodePage("ascii"); -capabilities = CAPABILITY_MILLING | CAPABILITY_JET; - -// vendor of MPCNC -vendor = "flyfisher604"; -vendorUrl = "https://github.com/flyfisher604/mpcnc_post_processor"; - - -// user-defined properties -properties = { - jobManualSpindlePowerControl: true, // Spindle motor is controlled by manual switch - - jobUseArcs: true, // Produce G2/G3 for arcs - - jobSetOriginOnStart: true, // Set origin when gcode start (G92) - jobGoOriginOnFinish: true, // Go X0 Y0 Z0 at gcode end - - jobSequenceNumbers: false, // show sequence numbers - jobSequenceNumberStart: 10, // first sequence number - jobSequenceNumberIncrement: 1, // increment for sequence numbers - jobSeparateWordsWithSpace: true, // specifies that the words should be separated with a white space - - jobDuetMillingMode: "M453 P2 I0 R30000 F200", // GCode command to setup Duet3d milling mode - jobDuetLaserMode: "M452 P2 I0 R255 F200", // GCode command to setup Duet3d laser mode - - fr0_TravelSpeedXY: 2500, // High speed for travel movements X & Y (mm/min) - fr1_TravelSpeedZ: 300, // High speed for travel movements Z (mm/min) - frA_ScaleFeedrate: false, // Will feedrated be scaled - frB_MaxCutSpeedXY: 900, // Max speed for cut movements X & Y (mm/min) - frC_MaxCutSpeedZ: 180, // Max speed for cut movements Z (mm/min) - frD_MaxCutSpeedXYZ: 1000, // Max feedrate after scaling - - mapD_RestoreFirstRapids: false, // Map first G01 --> G00 - mapE_RestoreRapids: false, // Map G01 --> G00 for SafeTravelsAboveZ - mapF_SafeZ: 10, // G01 mapped to G00 if Z is >= jobSafeZRapid - mapG_AllowRapidZ: true, // Allow G01 --> G00 for vertical retracts and Z descents above safe - - toolChangeEnabled: true, // Enable tool change code (bultin tool change requires LCD display) - toolChangeX: 0, // X position for builtin tool change - toolChangeY: 0, // Y position for builtin tool change - toolChangeZ: 40, // Z position for builtin tool change - toolChangeZProbe: true, // Z probe after tool change - toolChangeDisableZStepper: false, // disable Z stepper when change a tool - - probeOnStart: true, // Execute probe gcode to align tool - probeThickness: 0.8, // plate thickness - probeUseHomeZ: true, // use G28 or G38 for probing - probeG38Target: -10, // probing up to pos - probeG38Speed: 30, // probing with speed - - gcodeStartFile: "", // File with custom Gcode for header/start (in nc folder) - gcodeStopFile: "", // File with custom Gcode for footer/end (in nc folder) - gcodeToolFile: "", // File with custom Gcode for tool change (in nc folder) - gcodeProbeFile: "", // File with custom Gcode for tool probe (in nc folder) - - cutterOnVaporize: 100, // Persent of power to turn on the laser/plasma cutter in vaporize mode - cutterOnThrough: 80, // Persent of power to turn on the laser/plasma cutter in through mode - cutterOnEtch: 40, // Persent of power to turn on the laser/plasma cutter in etch mode - - coolantA_Mode: 0, // Enable issuing g-codes for control Coolant channel A - coolantB_Mode: 0, // Use issuing g-codes for control Coolant channel B - - commentWriteTools: true, - commentActivities: true, - commentSections: true, - commentCommands: true, - commentMovements: true, -}; - -propertyDefinitions = { - /* - jobFirmware: { - title: "Job: Firmware", description: "GCode output mode", group: 1, - type: "integer", default_mm: 0, default_in: 0, - values: [ - { title: "Don's Marlin 2.0/Repetier 1.0.3", id: 0 }, - { title: "GRBL 1.1", id: 1 }, - { title: "RepRap firmware (Duet)", id: 2 }, - ] - }, - */ - jobManualSpindlePowerControl: { - title: "Job: Manual Spindle On/Off", description: "Set Yes when your spindle motor is controlled by manual switch", group: 1, - type: "boolean", default_mm: true, default_in: true - }, - jobUseArcs: { - title: "Job: Use Arcs", description: "Use G2/G3 g-codes fo circular movements", group: 1, - type: "boolean", default_mm: true, default_in: true - }, - - jobMarlinEnforcFeFeedrate: { - title: "Job: Marlin Enforce Feedrate", description: "Add feedrate to each movement g-code", group: 1, - type: "boolean", default_mm: false, default_in: false - }, - - jobSetOriginOnStart: { - title: "Job: Reset on start (G92)", description: "Set origin when gcode start (G92)", group: 1, - type: "boolean", default_mm: true, default_in: true - }, - jobGoOriginOnFinish: { - title: "Job: Goto 0, 0 at end", description: "Go X0 Y0 at gcode end", group: 1, - type: "boolean", default_mm: true, default_in: true - }, - - jobSequenceNumbers: { - title: "Job: Line numbers", description: "Show sequence numbers", group: 1, - type: "boolean", default_mm: false, default_in: false - }, - jobSequenceNumberStart: { - title: "Job: Line # start", description: "First sequence number", group: 1, - type: "integer", default_mm: 10, default_in: 10 - }, - jobSequenceNumberIncrement: { - title: "Job: Line # increment", description: "Increment for sequence numbers", group: 1, - type: "integer", default_mm: 1, default_in: 1 - }, - jobSeparateWordsWithSpace: { - title: "Job: Separate words", description: "Specifies that the words should be separated with a white space", group: 1, - type: "boolean", default_mm: true, default_in: true - }, - jobDuetMillingMode: { - title: "Job: Duet Milling mode", description: "GCode command to setup Duet3d milling mode", group: 1, - type: "string", default_mm: "M453 P2 I0 R30000 F200", default_in: "M453 P2 I0 R30000 F200" - }, - jobDuetLaserMode: { - title: "Job: Duet Laser mode", description: "GCode command to setup Duet3d laser mode", group: 1, - type: "string", default_mm: "M452 P2 I0 R255 F200", default_in: "M452 P2 I0 R255 F200" - }, - - - fr0_TravelSpeedXY: { - title: "Feed: Travel speed X/Y", description: "High speed for Rapid movements X & Y (mm/min; in/min)", group: 2, - type: "spatial", default_mm: 2500, default_in: 100 - }, - fr1_TravelSpeedZ: { - title: "Feed: Travel Speed Z", description: "High speed for Rapid movements z (mm/min; in/min)", group: 2, - type: "spatial", default_mm: 300, default_in: 12 - }, - frA_ScaleFeedrate: { - title: "Feed: Scale feedrate", description: "Scale feedrate based on X, Y, Z axis maximums", group: 2, - type: "boolean", default_mm: false, default_in: false - }, - frB_MaxCutSpeedXY: { - title: "Feed: Max cut speed X or Y", description: "Max X or Y axis cut speed (mm/min; in/min)", group: 2, - type: "spatial", default_mm: 900, default_in: 35.43 - }, - frC_MaxCutSpeedZ: { - title: "Feed: Max cut speed Z", description: "Max Z axis cut speed (mm/min; in/min)", group: 2, - type: "spatial", default_mm: 180, default_in: 7.08 - }, - frD_MaxCutSpeedXYZ: { - title: "Feed: Max toolpath speed", description: "After scaling limit feedrate to this (mm/min; in/min)", group: 2, - type: "spatial", default_mm: 1000, default_in: 39.37 - }, - - - mapD_RestoreFirstRapids: { - title: "Map: First G1 -> G0 Rapids", description: "Convert first G1 of a cut to G0 Rapids", group: 3, - type: "boolean", default_mm: false, default_in: false - }, - mapE_RestoreRapids: { - title: "Map: G1 -> G0 Rapids", description: "When safe, convert G1s to G0 Rapids", group: 3, - type: "boolean", default_mm: false, default_in: false - }, - mapF_SafeZ: { - title: "Map: Safe Z for Rapids", description: "Z must be above or equal to this to map G01 --> G00", group: 3, - type: "integer", default_mm: 10, default_in: 0.590551 - }, - mapG_AllowRapidZ: { - title: "Map: Allow Rapid Z", description: "If G01 to Rapids allowed, then include vertical retracts and safe descents", group: 3, - type: "boolean", default_mm: true, default_in: true - }, - - - toolChangeEnabled: { - title: "Change: Enabled", description: "Enable tool change code (bultin tool change requires LCD display)", group: 4, - type: "boolean", default_mm: true, default_in: true - }, - toolChangeX: { - title: "Change: X", description: "X position for builtin tool change", group: 4, - type: "spatial", default_mm: 0, default_in: 0 - }, - toolChangeY: { - title: "Change: Y", description: "Y position for builtin tool change", group: 4, - type: "spatial", default_mm: 0, default_in: 0 - }, - toolChangeZ: { - title: "Change: Z ", description: "Z position for builtin tool change", group: 4, - type: "spatial", default_mm: 40, default_in: 1.6 - }, - toolChangeZProbe: { - title: "Change: Make Z Probe", description: "Z probe after tool change", group: 4, - type: "boolean", default_mm: true, default_in: true - }, - toolChangeDisableZStepper: { - title: "Change: Disable Z stepper", description: "Disable Z stepper when change a tool", group: 4, - type: "boolean", default_mm: false, default_in: false - }, - - probeOnStart: { - title: "Probe: On job start", description: "Execute probe gcode on job start", group: 5, - type: "boolean", default_mm: true, default_in: true - }, - probeThickness: { - title: "Probe: Plate thickness", description: "Plate thickness", group: 5, - type: "spatial", default_mm: 0.8, default_in: 0.032 - }, - probeUseHomeZ: { - title: "Probe: Use Home Z", description: "Use G28 or G38 for probing", group: 5, - type: "boolean", default_mm: true, default_in: true - }, - probeG38Target: { - title: "Probe: G38 target", description: "Probing up to Z position", group: 5, - type: "spatial", default_mm: -10, default_in: -0.5 - }, - probeG38Speed: { - title: "Probe: G38 speed", description: "Probing with speed (mm/min; in/min)", group: 5, - type: "spatial", default_mm: 30, default_in: 1.2 - }, - - cutterOnVaporize: { - title: "Laser: On - Vaporize", description: "Persent of power to turn on the laser/plasma cutter in vaporize mode", group: 6, - type: "number", default_mm: 100, default_in: 100 - }, - cutterOnThrough: { - title: "Laser: On - Through", description: "Persent of power to turn on the laser/plasma cutter in through mode", group: 6, - type: "number", default_mm: 80, default_in: 80 - }, - cutterOnEtch: { - title: "Laser: On - Etch", description: "Persent of power to on the laser/plasma cutter in etch mode", group: 6, - type: "number", default_mm: 40, default_in: 40 - }, - cutterMarlinMode: { - title: "Laser: Marlin/Reprap mode", description: "Marlin/Reprar mode of the laser/plasma cutter", group: 6, - type: "integer", default_mm: 106, default_in: 106, - values: [ - { title: "M106 S{PWM}/M107", id: 106 }, - { title: "M3 O{PWM}/M5", id: 3 }, - { title: "M42 P{pin} S{PWM}", id: 42 }, - ] - }, - cutterMarlinPin: { - title: "Laser: Marlin M42 pin", description: "Marlin custom pin number for the laser/plasma cutter", group: 6, - type: "integer", default_mm: 4, default_in: 4 - }, - - /* - cutterGrblMode: { - title: "Laser: GRBL mode", description: "GRBL mode of the laser/plasma cutter", group: 5, - type: "integer", default_mm: 4, default_in: 4, - values: [ - { title: "M4 S{PWM}/M5 dynamic power", id: 4 }, - { title: "M3 S{PWM}/M5 static power", id: 3 }, - ] - }, -*/ - - gcodeStartFile: { - title: "Extern: Start File", description: "File with custom Gcode for header/start (in nc folder)", group: 7, - type: "file", default_mm: "", default_in: "" - }, - gcodeStopFile: { - title: "Extern: Stop File", description: "File with custom Gcode for footer/end (in nc folder)", group: 7, - type: "file", default_mm: "", default_in: "" - }, - gcodeToolFile: { - title: "Extern: Tool File", description: "File with custom Gcode for tool change (in nc folder)", group: 7, - type: "file", default_mm: "", default_in: "" - }, - gcodeProbeFile: { - title: "Extern: Probe File", description: "File with custom Gcode for tool probe (in nc folder)", group: 7, - type: "file", default_mm: "", default_in: "" - }, - - coolantA_Mode: { - title: "Coolant: A Mode", description: "Enable issuing g-codes for control Coolant channel A", group: 8, type: "integer", - default_mm: 0, default_in: 0, - values: [ - { title: "off", id: 0 }, - { title: "flood", id: 1 }, - { title: "mist", id: 2 }, - { title: "throughTool", id: 3 }, - { title: "air", id: 4 }, - { title: "airThroughTool", id: 5 }, - { title: "suction", id: 6 }, - { title: "floodMist", id: 7 }, - { title: "floodThroughTool", id: 8 } - ] - }, - coolantAMarlinOn: { title: "Coolant: A On command", description: "GCode command to turn on Coolant channel A", group: 8, type: "string", default_mm: "M42 P11 S255" }, - coolantAMarlinOff: { - title: "Coolant: A Off command", description: "Gcode command to turn off Coolant A", group: 8, type: "string", - default_mm: "M42 P11 S0", default_in: "M42 P11 S0" - }, - - coolantB_Mode: { - title: "Coolant: B Mode", description: "Enable issuing g-codes for control Coolant channel B", group: 8, type: "integer", - default_mm: 0, default_in: 0, - values: [ - { title: "off", id: 0 }, - { title: "flood", id: 1 }, - { title: "mist", id: 2 }, - { title: "throughTool", id: 3 }, - { title: "air", id: 4 }, - { title: "airThroughTool", id: 5 }, - { title: "suction", id: 6 }, - { title: "floodMist", id: 7 }, - { title: "floodThroughTool", id: 8 } - ] - }, - coolantBMarlinOn: { - title: "Coolant: B On command", description: "GCode command to turn on Coolant channel B", group: 8, type: "string", - default_mm: "M42 P6 S255", default_in: "M42 P6 S255" - }, - coolantBMarlinOff: { - title: "Coolant: B Off command", description: "Gcode command to turn off Coolant channel B", group: 8, type: "string", - default_mm: "M42 P6 S0", default_in: "M42 P6 S0" - }, - - commentWriteTools: { - title: "Comment: Write Tools", description: "Write table of used tools in job header", group: 9, - type: "boolean", default_mm: true, default_in: true - }, - commentActivities: { - title: "Comment: Activities", description: "Write comments which somehow helps to understand current piece of g-code", group: 9, - type: "boolean", default_mm: true, default_in: true - }, - commentSections: { - title: "Comment: Sections", description: "Write header of every section", group: 9, - type: "boolean", default_mm: true, default_in: true - }, - commentCommands: { - title: "Comment: Trace Commands", description: "Write stringified commands called by CAM", group: 9, - type: "boolean", default_mm: true, default_in: true - }, - commentMovements: { - title: "Comment: Trace Movements", description: "Write stringified movements called by CAM", group: 9, - type: "boolean", default_mm: true, default_in: true - }, -}; - -/* - -https://github.com/guffy1234/mpcnc_posts_processor - -MPCNC posts processor for milling and laser/plasma cutting. - -*/ - -var sequenceNumber; - -// Formats -var gFormat = createFormat({ prefix: "G", decimals: 1 }); -var mFormat = createFormat({ prefix: "M", decimals: 0 }); - -var xyzFormat = createFormat({ decimals: (unit == MM ? 3 : 4) }); -var xFormat = createFormat({ prefix: "X", decimals: (unit == MM ? 3 : 4) }); -var yFormat = createFormat({ prefix: "Y", decimals: (unit == MM ? 3 : 4) }); -var zFormat = createFormat({ prefix: "Z", decimals: (unit == MM ? 3 : 4) }); -var iFormat = createFormat({ prefix: "I", decimals: (unit == MM ? 3 : 4) }); -var jFormat = createFormat({ prefix: "J", decimals: (unit == MM ? 3 : 4) }); -var kFormat = createFormat({ prefix: "K", decimals: (unit == MM ? 3 : 4) }); - -var speedFormat = createFormat({ decimals: 0 }); -var sFormat = createFormat({ prefix: "S", decimals: 0 }); - -var pFormat = createFormat({ prefix: "P", decimals: 0 }); -var oFormat = createFormat({ prefix: "O", decimals: 0 }); - -var feedFormat = createFormat({ decimals: (unit == MM ? 0 : 2) }); -var fFormat = createFormat({ prefix: "F", decimals: (unit == MM ? 0 : 2) }); - -var toolFormat = createFormat({ decimals: 0 }); -var tFormat = createFormat({ prefix: "T", decimals: 0 }); - -var taperFormat = createFormat({ decimals: 1, scale: DEG }); -var secFormat = createFormat({ decimals: 3, forceDecimal: true }); // seconds - range 0.001-1000 - -// Linear outputs -var xOutput = createVariable({}, xFormat); -var yOutput = createVariable({}, yFormat); -var zOutput = createVariable({}, zFormat); -var fOutput = createVariable({ force: false }, fFormat); -var sOutput = createVariable({ force: true }, sFormat); - -// Circular outputs -var iOutput = createReferenceVariable({}, iFormat); -var jOutput = createReferenceVariable({}, jFormat); -var kOutput = createReferenceVariable({}, kFormat); - -// Modals -var gMotionModal = createModal({}, gFormat); // modal group 1 // G0-G3, ... -var gPlaneModal = createModal({ onchange: function () { gMotionModal.reset(); } }, gFormat); // modal group 2 // G17-19 -var gAbsIncModal = createModal({}, gFormat); // modal group 3 // G90-91 -var gFeedModeModal = createModal({}, gFormat); // modal group 5 // G93-94 -var gUnitModal = createModal({}, gFormat); // modal group 6 // G20-21 - -// Arc support variables -minimumChordLength = spatial(0.01, MM); -minimumCircularRadius = spatial(0.01, MM); -maximumCircularRadius = spatial(1000, MM); -minimumCircularSweep = toRad(0.01); -maximumCircularSweep = toRad(180); -allowHelicalMoves = false; -allowedCircularPlanes = undefined; - -// Writes the specified block. -function writeBlock() { - if (properties.jobSequenceNumbers) { - writeWords2("N" + sequenceNumber, arguments); - sequenceNumber += properties.jobSequenceNumberIncrement; - } else { - writeWords(arguments); - } -} - -function FirmwareBase() { - this.machineMode = undefined; //TYPE_MILLING, TYPE_JET -} - -FirmwareBase.prototype.section = function () { - this.machineMode = currentSection.type; -} - -var currentFirmware; - -// Called in every new gcode file -function onOpen() { - currentFirmware.init(); - - sequenceNumber = properties.jobSequenceNumberStart; - if (!properties.jobSeparateWordsWithSpace) { - setWordSeparator(""); - } -} - -// Called at end of gcode file -function onClose() { - writeActivityComment(" *** STOP begin ***"); - currentFirmware.flushMotions(); - if (properties.gcodeStopFile == "") { - onCommand(COMMAND_COOLANT_OFF); - if (properties.jobGoOriginOnFinish) { - rapidMovementsXY(0, 0); - } - onCommand(COMMAND_STOP_SPINDLE); - currentFirmware.end(); - writeActivityComment(" *** STOP end ***"); - } else { - loadFile(properties.gcodeStopFile); - } - currentFirmware.close(); -} - -var cutterOnCurrentPower; -var forceSectionToStartWithRapid = false; - -function onSection() { - // Every section needs to start with a Rapid to get to the initial location. - // In the hobby version Rapids have been elliminated and the first command is - // a onLinear not a onRapid command. This results in not current position being - // that same as the cut to position which means wecan't determine the direction - // of the move. Without a direction vector we can't scale the feedrate or convert - // onLinear moves back into onRapids. By ensuring the first onLinear is treated as - // a onRapid we have a currentPosition that is correct. - - forceSectionToStartWithRapid = true; - - // Write Start gcode of the documment (after the "onParameters" with the global info) - if (isFirstSection()) { - writeFirstSection(); - } - - writeActivityComment(" *** SECTION begin ***"); - - // Tool change - if (properties.toolChangeEnabled && !isFirstSection() && tool.number != getPreviousSection().getTool().number) { - if (properties.gcodeToolFile == "") { - // Builtin tool change gcode - writeActivityComment(" --- CHANGE TOOL begin ---"); - currentFirmware.toolChange(); - writeActivityComment(" --- CHANGE TOOL end ---"); - } else { - // Custom tool change gcode - loadFile(properties.gcodeToolFile); - } - } - - if (properties.commentSections) { - // Machining type - if (currentSection.type == TYPE_MILLING) { - // Specific milling code - writeComment(" " + sectionComment + " - Milling - Tool: " + tool.number + " - " + tool.comment + " " + getToolTypeName(tool.type)); - } - - if (currentSection.type == TYPE_JET) { - // Cutter mode used for different cutting power in PWM laser - switch (currentSection.jetMode) { - case JET_MODE_THROUGH: - cutterOnCurrentPower = properties.cutterOnThrough; - break; - case JET_MODE_ETCHING: - cutterOnCurrentPower = properties.cutterOnEtch; - break; - case JET_MODE_VAPORIZE: - cutterOnCurrentPower = properties.cutterOnVaporize; - break; - default: - error("Cutting mode is not supported."); - } - writeComment(" " + sectionComment + " - Laser/Plasma - Cutting mode: " + getParameter("operation:cuttingMode")); - } - - // Print min/max boundaries for each section - vectorX = new Vector(1, 0, 0); - vectorY = new Vector(0, 1, 0); - writeComment(" X Min: " + xyzFormat.format(currentSection.getGlobalRange(vectorX).getMinimum()) + " - X Max: " + xyzFormat.format(currentSection.getGlobalRange(vectorX).getMaximum())); - writeComment(" Y Min: " + xyzFormat.format(currentSection.getGlobalRange(vectorY).getMinimum()) + " - Y Max: " + xyzFormat.format(currentSection.getGlobalRange(vectorY).getMaximum())); - writeComment(" Z Min: " + xyzFormat.format(currentSection.getGlobalZRange().getMinimum()) + " - Z Max: " + xyzFormat.format(currentSection.getGlobalZRange().getMaximum())); - } - - currentFirmware.section(); //adjust mode - - onCommand(COMMAND_START_SPINDLE); - onCommand(COMMAND_COOLANT_ON); - - // Display section name in LCD - currentFirmware.display_text(" " + sectionComment); -} - -function resetAll() { - xOutput.reset(); - yOutput.reset(); - zOutput.reset(); - fOutput.reset(); -} - -// Called in every section end -function onSectionEnd() { - resetAll(); - writeActivityComment(" *** SECTION end ***"); - writeln(""); -} - -function onComment(message) { - writeComment(message); -} - -var pendingRadiusCompensation = RADIUS_COMPENSATION_OFF; - -function onRadiusCompensation() { - pendingRadiusCompensation = radiusCompensation; -} - -// Rapid movements -function onRapid(x, y, z) { - forceSectionToStartWithRapid = false; - - rapidMovements(x, y, z); -} - -function safeToRapid(x, y, z) { - if (properties.mapE_RestoreRapids) { - let zSafe = (z >= properties.mapF_SafeZ); - - // Destination z must be in safe zone. - if (zSafe) { - let cur = getCurrentPosition(); - let zConstant = (z == cur.z); - let zUp = (z > cur.z); - let xyConstant = ((x == cur.x) && (y == cur.y)); - let curZSafe = (cur.z >= properties.mapF_SafeZ); - - // Restore Rapids only when the target Z is safe and - // Case 1: Z is not changing, but XY are - // Case 2: Z is increasing, but XY constant - - // Z is not changing and we know we are in the safe zone - if (zConstant) { - return true; - } - - // We include moves of Z up as long as xy are constant - else if (properties.mapG_AllowRapidZ && zUp && xyConstant) { - return true; - } - - // We include moves of Z down as long as xy are constant and z always remains safe - else if (properties.mapG_AllowRapidZ && (!zUp) && xyConstant && curZSafe) { - return true; - } - } - } - - return false; -} - -// Feed movements -function onLinear(x, y, z, feed) { - // If we are allowing Rapids to be recovered from Linear (cut) moves, which is - // only required when F360 Personal edition is used, then if this Linear (cut) - // move is the first operationin a Section (milling operation) then convert it - // to a Rapid. This is OK because Sections normally begin with a Rapid to move - // to the first cutting location but these Rapids were changed to Linears by - // the personal edition. If this Rapid is not recovered and feedrate scaling - // is enabled then the first move to the start of a section will be at the - // slowest cutting feedrate, generally Z's feedrate. - - if (properties.mapD_RestoreFirstRapids && (forceSectionToStartWithRapid == true)) { - writeComment(" First G1 --> G0"); - - forceSectionToStartWithRapid = false; - onRapid(x, y, z); - } - else if (safeToRapid(x, y, z)) { - writeComment(" Safe G1 --> G0"); - - onRapid(x, y, z); - } - else { - linearMovements(x, y, z, feed, true); - } -} - -function onRapid5D(_x, _y, _z, _a, _b, _c) { - forceSectionToStartWithRapid = false; - - error(localize("Multi-axis motion is not supported.")); -} - -function onLinear5D(_x, _y, _z, _a, _b, _c, feed) { - forceSectionToStartWithRapid = false; - - error(localize("Multi-axis motion is not supported.")); -} - -function onCircular(clockwise, cx, cy, cz, x, y, z, feed) { - forceSectionToStartWithRapid = false; - - if (pendingRadiusCompensation != RADIUS_COMPENSATION_OFF) { - error(localize("Radius compensation cannot be activated/deactivated for a circular move.")); - return; - } - currentFirmware.circular(clockwise, cx, cy, cz, x, y, z, feed) -} - -// Called on waterjet/plasma/laser cuts -var powerState = false; - -function onPower(power) { - if (power != powerState) { - if (power) { - writeActivityComment(" >>> LASER Power ON"); - currentFirmware.laserOn(cutterOnCurrentPower); - } else { - writeActivityComment(" >>> LASER Power OFF"); - currentFirmware.laserOff(); - } - powerState = power; - } -} - -// Called on Dwell Manual NC invocation -function onDwell(seconds) { - if (seconds > 99999.999) { - warning(localize("Dwelling time is out of range.")); - } - writeActivityComment(" >>> Dwell"); - currentFirmware.dwell(seconds); -} - -// Called with every parameter in the documment/section -function onParameter(name, value) { - - // Write gcode initial info - // Product version - if (name == "generated-by") { - writeComment(value); - writeComment(" Posts processor: " + FileSystem.getFilename(getConfigurationPath())); - } - // Date - if (name == "generated-at") writeComment(" Gcode generated: " + value + " GMT"); - // Document - if (name == "document-path") writeComment(" Document: " + value); - // Setup - if (name == "job-description") writeComment(" Setup: " + value); - - // Get section comment - if (name == "operation-comment") sectionComment = value; -} - -function onMovement(movement) { - if (properties.commentMovements) { - var jet = tool.isJetTool && tool.isJetTool(); - var id; - switch (movement) { - case MOVEMENT_RAPID: - id = "MOVEMENT_RAPID"; - break; - case MOVEMENT_LEAD_IN: - id = "MOVEMENT_LEAD_IN"; - break; - case MOVEMENT_CUTTING: - id = "MOVEMENT_CUTTING"; - break; - case MOVEMENT_LEAD_OUT: - id = "MOVEMENT_LEAD_OUT"; - break; - case MOVEMENT_LINK_TRANSITION: - id = jet ? "MOVEMENT_BRIDGING" : "MOVEMENT_LINK_TRANSITION"; - break; - case MOVEMENT_LINK_DIRECT: - id = "MOVEMENT_LINK_DIRECT"; - break; - case MOVEMENT_RAMP_HELIX: - id = jet ? "MOVEMENT_PIERCE_CIRCULAR" : "MOVEMENT_RAMP_HELIX"; - break; - case MOVEMENT_RAMP_PROFILE: - id = jet ? "MOVEMENT_PIERCE_PROFILE" : "MOVEMENT_RAMP_PROFILE"; - break; - case MOVEMENT_RAMP_ZIG_ZAG: - id = jet ? "MOVEMENT_PIERCE_LINEAR" : "MOVEMENT_RAMP_ZIG_ZAG"; - break; - case MOVEMENT_RAMP: - id = "MOVEMENT_RAMP"; - break; - case MOVEMENT_PLUNGE: - id = jet ? "MOVEMENT_PIERCE" : "MOVEMENT_PLUNGE"; - break; - case MOVEMENT_PREDRILL: - id = "MOVEMENT_PREDRILL"; - break; - case MOVEMENT_EXTENDED: - id = "MOVEMENT_EXTENDED"; - break; - case MOVEMENT_REDUCED: - id = "MOVEMENT_REDUCED"; - break; - case MOVEMENT_HIGH_FEED: - id = "MOVEMENT_HIGH_FEED"; - break; - case MOVEMENT_FINISH_CUTTING: - id = "MOVEMENT_FINISH_CUTTING"; - break; - } - if (id == undefined) { - id = String(movement); - } - writeComment(" " + id); - } -} - -var currentSpindleSpeed = 0; - -function setSpindeSpeed(_spindleSpeed, _clockwise) { - if (currentSpindleSpeed != _spindleSpeed) { - if (_spindleSpeed > 0) { - currentFirmware.spindleOn(_spindleSpeed, _clockwise); - } else { - currentFirmware.spindleOff(); - } - currentSpindleSpeed = _spindleSpeed; - } -} - -function onSpindleSpeed(spindleSpeed) { - setSpindeSpeed(spindleSpeed, tool.clockwise); -} - -function onCommand(command) { - if (properties.commentActivities) { - var stringId = getCommandStringId(command); - writeComment(" " + stringId); - } - switch (command) { - case COMMAND_START_SPINDLE: - onCommand(tool.clockwise ? COMMAND_SPINDLE_CLOCKWISE : COMMAND_SPINDLE_COUNTERCLOCKWISE); - return; - case COMMAND_SPINDLE_CLOCKWISE: - if (tool.jetTool) - return; - setSpindeSpeed(spindleSpeed, true); - return; - case COMMAND_SPINDLE_COUNTERCLOCKWISE: - if (tool.jetTool) - return; - setSpindeSpeed(spindleSpeed, false); - return; - case COMMAND_STOP_SPINDLE: - if (tool.jetTool) - return; - setSpindeSpeed(0, true); - return; - case COMMAND_COOLANT_ON: - setCoolant(tool.coolant); - return; - case COMMAND_COOLANT_OFF: - setCoolant(0); //COOLANT_DISABLED - return; - case COMMAND_LOCK_MULTI_AXIS: - return; - case COMMAND_UNLOCK_MULTI_AXIS: - return; - case COMMAND_BREAK_CONTROL: - return; - case COMMAND_TOOL_MEASURE: - if (tool.jetTool) - return; - currentFirmware.probeTool(); - return; - case COMMAND_STOP: - writeBlock(mFormat.format(0)); - return; - } -} - -function writeFirstSection() { - // dump tool information - var toolZRanges = {}; - var vectorX = new Vector(1, 0, 0); - var vectorY = new Vector(0, 1, 0); - var ranges = { - x: { min: undefined, max: undefined }, - y: { min: undefined, max: undefined }, - z: { min: undefined, max: undefined }, - }; - var handleMinMax = function (pair, range) { - var rmin = range.getMinimum(); - var rmax = range.getMaximum(); - if (pair.min == undefined || pair.min > rmin) { - pair.min = rmin; - } - if (pair.max == undefined || pair.max < rmin) { // was pair.min - changed by DG 1/4/2021 - pair.max = rmax; - } - } - - var numberOfSections = getNumberOfSections(); - for (var i = 0; i < numberOfSections; ++i) { - var section = getSection(i); - var tool = section.getTool(); - var zRange = section.getGlobalZRange(); - var xRange = section.getGlobalRange(vectorX); - var yRange = section.getGlobalRange(vectorY); - handleMinMax(ranges.x, xRange); - handleMinMax(ranges.y, yRange); - handleMinMax(ranges.z, zRange); - if (is3D() && properties.commentWriteTools) { - if (toolZRanges[tool.number]) { - toolZRanges[tool.number].expandToRange(zRange); - } else { - toolZRanges[tool.number] = zRange; - } - } - } - - writeComment(" "); - writeComment(" Ranges table:"); - writeComment(" X: Min=" + xyzFormat.format(ranges.x.min) + " Max=" + xyzFormat.format(ranges.x.max) + " Size=" + xyzFormat.format(ranges.x.max - ranges.x.min)); - writeComment(" Y: Min=" + xyzFormat.format(ranges.y.min) + " Max=" + xyzFormat.format(ranges.y.max) + " Size=" + xyzFormat.format(ranges.y.max - ranges.y.min)); - writeComment(" Z: Min=" + xyzFormat.format(ranges.z.min) + " Max=" + xyzFormat.format(ranges.z.max) + " Size=" + xyzFormat.format(ranges.z.max - ranges.z.min)); - - if (properties.commentWriteTools) { - writeComment(" "); - writeComment(" Tools table:"); - var tools = getToolTable(); - if (tools.getNumberOfTools() > 0) { - for (var i = 0; i < tools.getNumberOfTools(); ++i) { - var tool = tools.getTool(i); - var comment = " T" + toolFormat.format(tool.number) + " D=" + xyzFormat.format(tool.diameter) + " CR=" + xyzFormat.format(tool.cornerRadius); - if ((tool.taperAngle > 0) && (tool.taperAngle < Math.PI)) { - comment += " TAPER=" + taperFormat.format(tool.taperAngle) + "deg"; - } - if (toolZRanges[tool.number]) { - comment += " - ZMIN=" + xyzFormat.format(toolZRanges[tool.number].getMinimum()); - } - comment += " - " + getToolTypeName(tool.type) + " " + tool.comment; - writeComment(comment); - } - } - } - writeln(""); - - writeActivityComment(" *** START begin ***"); - - if (properties.gcodeStartFile == "") { - currentFirmware.start(); - } else { - loadFile(properties.gcodeStartFile); - } - writeActivityComment(" *** START end ***"); - writeln(""); -} - -// Output a comment -function writeComment(text) { - currentFirmware.comment(text); -} - -// Rapid movements with G1 and differentiated travel speeds for XY -// Changes F360 current XY. -// No longer called for general Rapid only for probing, homing, etc. -function rapidMovementsXY(_x, _y) { - let x = xOutput.format(_x); - let y = yOutput.format(_y); - - if (x || y) { - if (pendingRadiusCompensation != RADIUS_COMPENSATION_OFF) { - error(localize("Radius compensation mode cannot be changed at rapid traversal.")); - } - else { - let f = fOutput.format(propertyMmToUnit(properties.fr0_TravelSpeedXY)); - writeBlock(gMotionModal.format(0), x, y, f); - } - } -} - -// Rapid movements with G1 and differentiated travel speeds for Z -// Changes F360 current Z -// No longer called for general Rapid only for probing, homing, etc. -function rapidMovementsZ(_z) { - let z = zOutput.format(_z); - - if (z) { - if (pendingRadiusCompensation != RADIUS_COMPENSATION_OFF) { - error(localize("Radius compensation mode cannot be changed at rapid traversal.")); - } - else { - let f = fOutput.format(propertyMmToUnit(properties.fr1_TravelSpeedZ)); - writeBlock(gMotionModal.format(0), z, f); - } - } -} - -// Rapid movements with G1 uses the max travel rate (xy or z) and then relies on feedrate scaling -function rapidMovements(_x, _y, _z) { - - rapidMovementsZ(_z); - rapidMovementsXY(_x, _y); -} - -// Calculate the feedX, feedY and feedZ components - -function limitFeedByXYZComponents(curPos, destPos, feed) { - if (!properties.frA_ScaleFeedrate) - return feed; - - var xyz = Vector.diff(destPos, curPos); // Translate the cut so curPos is at 0,0,0 - var dir = xyz.getNormalized(); // Normalize vector to get a direction vector - var xyzFeed = Vector.product(dir.abs, feed); // Determine the effective x,y,z speed on each axis - - // Get the max speed for each axis - let xyLimit = propertyMmToUnit(properties.frB_MaxCutSpeedXY); - let zLimit = propertyMmToUnit(properties.frC_MaxCutSpeedZ); - - // Normally F360 begins a Section (a milling operation) with a Rapid to move to the beginning of the cut. - // Rapids use the defined Travel speed and the Post Processor does not depend on the current location. - // This function must know the current location in order to calculate the actual vector traveled. Without - // the first Rapid the current location is the same as the desination location, which creates a 0 length - // vector. A zero length vector is unusable and so a instead the slowest of the xyLimit or zLimit is used. - // - // Note: if Map: G1 -> Rapid is enabled in the Properties then if the first operation in a Section is a - // cut (which it should always be) then it will be converted to a Rapid. This prevents ever getting a zero - // length vector. - if (xyz.length == 0) { - var lesserFeed = (xyLimit < zLimit) ? xyLimit : zLimit; - - return lesserFeed; - } - - // Force the speed of each axis to be within limits - if (xyzFeed.z > zLimit) { - xyzFeed.multiply(zLimit / xyzFeed.z); - } - - if (xyzFeed.x > xyLimit) { - xyzFeed.multiply(xyLimit / xyzFeed.x); - } - - if (xyzFeed.y > xyLimit) { - xyzFeed.multiply(xyLimit / xyzFeed.y); - } - - // Calculate the new feedrate based on the speed allowed on each axis: feedrate = sqrt(x^2 + y^2 + z^2) - // xyzFeed.length is the same as Math.sqrt((xyzFeed.x * xyzFeed.x) + (xyzFeed.y * xyzFeed.y) + (xyzFeed.z * xyzFeed.z)) - - // Limit the new feedrate by the maximum allowable cut speed - - let xyzLimit = propertyMmToUnit(properties.frD_MaxCutSpeedXYZ); - let newFeed = (xyzFeed.length > xyzLimit) ? xyzLimit : xyzFeed.length; - - if (Math.abs(newFeed - feed) > 0.01) { - return newFeed; - } - else { - return feed; - } -} - -// Linear movements -function linearMovements(_x, _y, _z, _feed) { - if (pendingRadiusCompensation != RADIUS_COMPENSATION_OFF) { - // ensure that we end at desired position when compensation is turned off - xOutput.reset(); - yOutput.reset(); - } - - // Force the feedrate to be scaled (if enabled). The feedrate is projected into the - // x, y, and z axis and each axis is tested to see if it exceeds its defined max. If - // it does then the speed in all 3 axis is scaled proportionately. The resulting feedrate - // is then capped at the maximum defined cutrate. - - let feed = limitFeedByXYZComponents(getCurrentPosition(), new Vector(_x, _y, _z), _feed); - - let x = xOutput.format(_x); - let y = yOutput.format(_y); - let z = zOutput.format(_z); - let f = fOutput.format(feed); - - if (x || y || z) { - if (pendingRadiusCompensation != RADIUS_COMPENSATION_OFF) { - error(localize("Radius compensation mode is not supported.")); - } else { - writeBlock(gMotionModal.format(1), x, y, z, f); - } - } else if (f) { - if (getNextRecord().isMotion()) { // try not to output feed without motion - fOutput.reset(); // force feed on next line - } else { - writeBlock(gMotionModal.format(1), f); - } - } -} - -// Test if file exist/can read and load it -function loadFile(_file) { - var folder = FileSystem.getFolderPath(getOutputPath()) + PATH_SEPARATOR; - if (FileSystem.isFile(folder + _file)) { - var txt = loadText(folder + _file, "utf-8"); - if (txt.length > 0) { - writeActivityComment(" --- Start custom gcode " + folder + _file); - write(txt); - writeActivityComment(" --- End custom gcode " + folder + _file); - writeln(""); - } - } else { - writeComment(" Can't open file " + folder + _file); - error("Can't open file " + folder + _file); - } -} - -var currentCoolantMode = 0; - -// Manage coolant state -function setCoolant(coolant) { - if (currentCoolantMode == coolant) { - return; - } - if (properties.coolantA_Mode != 0) { - if (currentCoolantMode == properties.coolantA_Mode) { - writeActivityComment(" >>> Coolant A OFF"); - currentFirmware.coolantA(true); - } else if (coolant == properties.coolantA_Mode) { - writeActivityComment(" >>> Coolant A ON"); - currentFirmware.coolantA(false); - } - } - if (properties.coolantB_Mode != 0) { - if (currentCoolantMode == properties.coolantB_Mode) { - writeActivityComment(" >>> Coolant B OFF"); - currentFirmware.coolantB(true); - } else if (coolant == properties.coolantB_Mode) { - writeActivityComment(" >>> Coolant B ON"); - currentFirmware.coolantB(false); - } - } - currentCoolantMode = coolant; -} - -function propertyMmToUnit(_v) { - return (_v / (unit == IN ? 25.4 : 1)); -} - -function writeActivityComment(_comment) { - if (properties.commentActivities) { - writeComment(_comment); - } -} - -function mergeProperties(to, from) { - for (var attrname in from) { - to[attrname] = from[attrname]; - } -} - -function Firmware3dPrinterLike() { - FirmwareBase.apply(this, arguments); - this.spindleEnabled = false; -} - -Firmware3dPrinterLike.prototype = Object.create(FirmwareBase.prototype); -Firmware3dPrinterLike.prototype.constructor = Firmware3dPrinterLike; -Firmware3dPrinterLike.prototype.init = function () { - gMotionModal = createModal({ force: true }, gFormat); // modal group 1 // G0-G3, ... - - if (properties.jobMarlinEnforceFeedrate) { - fOutput = createVariable({ force: true }, fFormat); - } -} - -Firmware3dPrinterLike.prototype.start = function () { - writeComment(" Set Absolute Positioning"); - writeComment(" Units = " + (unit == IN ? "inch" : "mm")); - writeComment(" Disable stepper timeout"); - if (properties.jobSetOriginOnStart) { - writeComment(" Set current position = 0,0,0"); - } - - writeBlock(gAbsIncModal.format(90)); // Set to Absolute Positioning - writeBlock(gUnitModal.format(unit == IN ? 20 : 21)); // Set the units - writeBlock(mFormat.format(84), sFormat.format(0)); // Disable steppers timeout - - if (properties.jobSetOriginOnStart) { - writeBlock(gFormat.format(92), xFormat.format(0), yFormat.format(0), zFormat.format(0)); // Set origin to initial position - } - - if (properties.probeOnStart && tool.number != 0 && !tool.jetTool) { - onCommand(COMMAND_TOOL_MEASURE); - } -} - -Firmware3dPrinterLike.prototype.end = function () { - this.display_text("Job end"); -} -Firmware3dPrinterLike.prototype.close = function () { -} -Firmware3dPrinterLike.prototype.comment = function (text) { - writeln(";" + String(text).replace(/[\(\)]/g, "")); -} -Firmware3dPrinterLike.prototype.flushMotions = function () { - writeBlock(mFormat.format(400)); -} -Firmware3dPrinterLike.prototype.spindleOn = function (_spindleSpeed, _clockwise) { - if (properties.jobManualSpindlePowerControl) { - // for manual any positive input speed assumed as enabled. so it's just a flag - if (!this.spindleEnabled) { - this.askUser("Turn ON " + speedFormat.format(_spindleSpeed) + "RPM", "Spindle", false); - } - } else { - writeActivityComment(" >>> Spindle Speed " + speedFormat.format(_spindleSpeed)); - writeBlock(mFormat.format(_clockwise ? 3 : 4), sOutput.format(spindleSpeed)); - } - this.spindleEnabled = true; -} -Firmware3dPrinterLike.prototype.spindleOff = function () { - if (properties.jobManualSpindlePowerControl) { - writeBlock(mFormat.format(300), sFormat.format(300), pFormat.format(3000)); - this.askUser("Turn OFF spindle", "Spindle", false); - } else { - writeBlock(mFormat.format(5)); - } - this.spindleEnabled = false; -} -Firmware3dPrinterLike.prototype.laserOn = function (power) { - var laser_pwm = power / 100 * 255; - switch (properties.cutterMarlinMode) { - case 106: - writeBlock(mFormat.format(106), sFormat.format(laser_pwm)); - break; - case 3: - writeBlock(mFormat.format(3), oFormat.format(laser_pwm)); - break; - case 42: - writeBlock(mFormat.format(42), pFormat.format(properties.cutterMarlinPin), sFormat.format(laser_pwm)); - break; - } -} -Firmware3dPrinterLike.prototype.laserOff = function () { - switch (properties.cutterMarlinMode) { - case 106: - writeBlock(mFormat.format(107)); - break; - case 3: - writeBlock(mFormat.format(5)); - break; - case 42: - writeBlock(mFormat.format(42), pFormat.format(properties.cutterMarlinPin), sFormat.format(0)); - break; - } -} -Firmware3dPrinterLike.prototype.coolantA = function (on) { - writeBlock(on ? properties.coolantAMarlinOn : properties.coolantAMarlinOff); -} -Firmware3dPrinterLike.prototype.coolantB = function (on) { - writeBlock(on ? properties.coolantBMarlinOn : roperties.coolantBMarlinOff); -} -Firmware3dPrinterLike.prototype.dwell = function (seconds) { - writeBlock(gFormat.format(4), "S" + secFormat.format(seconds)); -} -Firmware3dPrinterLike.prototype.display_text = function (txt) { - writeBlock(mFormat.format(117), (properties.jobSeparateWordsWithSpace ? "" : " ") + txt); -} -Firmware3dPrinterLike.prototype.circular = function (clockwise, cx, cy, cz, x, y, z, feed) { - if (!properties.jobUseArcs) { - linearize(tolerance); - return; - } - // Marlin supports arcs only on XY plane - var start = getCurrentPosition(); - - if (isFullCircle()) { - if (isHelical()) { - linearize(tolerance); - return; - } - switch (getCircularPlane()) { - case PLANE_XY: - writeBlock(gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), iOutput.format(cx - start.x, 0), jOutput.format(cy - start.y, 0), fOutput.format(feed)); - break; - default: - linearize(tolerance); - } - } else { - switch (getCircularPlane()) { - case PLANE_XY: - writeBlock(gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), iOutput.format(cx - start.x, 0), jOutput.format(cy - start.y, 0), fOutput.format(feed)); - break; - default: - linearize(tolerance); - } - } -} - -Firmware3dPrinterLike.prototype.askUser = function (text, title, allowJog) { - writeBlock(mFormat.format(0), (properties.jobSeparateWordsWithSpace ? "" : " ") + text); -} - -Firmware3dPrinterLike.prototype.toolChange = function () { - this.flushMotions(); - // Go to tool change position - onRapid(propertyMmToUnit(properties.toolChangeX), propertyMmToUnit(properties.toolChangeY), propertyMmToUnit(properties.toolChangeZ)); - currentFirmware.flushMotions(); - // turn off spindle and coolant - onCommand(COMMAND_COOLANT_OFF); - onCommand(COMMAND_STOP_SPINDLE); - if (!properties.jobManualSpindlePowerControl) { - // Beep - writeBlock(mFormat.format(300), sFormat.format(400), pFormat.format(2000)); - } - - // Disable Z stepper - if (properties.toolChangeDisableZStepper) { - this.askUser("Z Stepper will disabled. Wait for STOP!!", "Tool change", false); - writeBlock(mFormat.format(17), 'Z'); // Disable steppers timeout - } - // Ask tool change and wait user to touch lcd button - this.askUser("Tool " + tool.number + " " + tool.comment, "Tool change", true); - - // Run Z probe gcode - if (properties.toolChangeZProbe && tool.number != 0) { - onCommand(COMMAND_TOOL_MEASURE); - } -} - -Firmware3dPrinterLike.prototype.probeTool = function () { - writeComment(" Ask User to Attach the Z Probe"); - writeComment(" Probe"); - writeComment(" Set Z to probe thickness: " + zFormat.format(propertyMmToUnit(properties.probeThickness))) - if (properties.toolChangeZ != "") { - writeComment(" Retract the tool to " + propertyMmToUnit(properties.toolChangeZ)); - } - writeComment(" Ask User to Remove the Z Probe"); - - this.askUser("Attach ZProbe", "Probe", false); - // refer http://marlinfw.org/docs/gcode/G038.html - if (properties.probeUseHomeZ) { - writeBlock(gFormat.format(28), 'Z'); - } else { - writeBlock(gMotionModal.format(38.3), fFormat.format(propertyMmToUnit(properties.probeG38Speed)), zFormat.format(propertyMmToUnit(properties.probeG38Target))); - } - - let z = zFormat.format(propertyMmToUnit(properties.probeThickness)); - writeBlock(gFormat.format(92), z); // Set origin to initial position - - resetAll(); - if (properties.toolChangeZ != "") { // move up tool to safe height again after probing - rapidMovementsZ(propertyMmToUnit(properties.toolChangeZ), false); - } - this.flushMotions(); - this.askUser("Detach ZProbe", "Probe", false); -} - -properties3dPrinter = { - jobMarlinEnforceFeedrate: false, // Add feedrate to each movement line - - cutterMarlinMode: 106, // Marlin mode laser/plasma cutter - cutterMarlinPin: 4, // Marlin laser/plasma cutter pin for M42 - - coolantAMarlinOn: "M42 P11 S255", // GCode command to turn on Coolant channel A - coolantAMarlinOff: "M42 P11 S0", // Gcode command to turn off Coolant channel A - coolantBMarlinOn: "M42 P6 S255", // GCode command to turn on Coolant channel B - coolantBMarlinOff: "M42 P6 S0", // Gcode command to turn off Coolant channel B -}; - -propertyDefinitions3dPrinter = { - jobMarlinEnforceFeedrate: { - title: "Job: Enforce Feedrate", description: "Add feedrate to each movement g-code", group: 1, - type: "boolean", default_mm: false, default_in: false - }, - cutterMarlinMode: { - title: "Laser: Marlin/Reprap mode", description: "Marlin/Reprar mode of the laser/plasma cutter", group: 5, - type: "integer", default_mm: 106, default_in: 106, - values: [ - { title: "M106 S{PWM}/M107", id: 106 }, - { title: "M3 O{PWM}/M5", id: 3 }, - { title: "M42 P{pin} S{PWM}", id: 42 }, - ] - }, - cutterMarlinPin: { - title: "Laser: Marlin M42 pin", description: "Marlin custom pin number for the laser/plasma cutter", group: 5, - type: "integer", default_mm: 4, default_in: 4 - }, - - coolantAMarlinOn: { title: "Coolant: A On command", description: "GCode command to turn on Coolant channel A", group: 7, type: "string", default_mm: "M42 P11 S255" }, - coolantAMarlinOff: { - title: "Coolant: A Off command", description: "Gcode command to turn off Coolant A", group: 7, type: "string", - default_mm: "M42 P11 S0", default_in: "M42 P11 S0" - }, - - coolantBMarlinOn: { - title: "Coolant: B On command", description: "GCode command to turn on Coolant channel B", group: 7, type: "string", - default_mm: "M42 P6 S255", default_in: "M42 P6 S255" - }, - coolantBMarlinOff: { - title: "Coolant: B Off command", description: "Gcode command to turn off Coolant channel B", group: 7, type: "string", - default_mm: "M42 P6 S0", default_in: "M42 P6 S0" - }, -}; diff --git a/DIYCNC_Grbl11.cps b/DIYCNC_Grbl11.cps deleted file mode 100644 index 4b8fcbc..0000000 --- a/DIYCNC_Grbl11.cps +++ /dev/null @@ -1,147 +0,0 @@ -/* - -https://github.com/guffy1234/mpcnc_posts_processor - -MPCNC posts processor for milling and laser/plasma cutting. - -*/ -include("DIYCNC_Common.js"); - -description = "DIYCNC Milling/Laser - Grbl 1.1"; - -// user-defined properties -mergeProperties(properties, { - cutterGrblMode: 4, // GRBL mode laser/plasma cutter - coolantAGrbl: 7, // GCode command to turn on Coolant channel A - coolantBGrbl: 8, // GCode command to turn on Coolant channel A -}); - -mergeProperties(propertyDefinitions, { - cutterGrblMode: { - title: "Laser: GRBL mode", description: "GRBL mode of the laser/plasma cutter", group: 4, - type: "integer", default_mm: 4, default_in: 4, - values: [ - { title: "M4 S{PWM}/M5 dynamic power", id: 4 }, - { title: "M3 S{PWM}/M5 static power", id: 3 }, - ] - }, - coolantAGrbl: { - title: "Coolant: A code", description: "GRBL g-codes for control Coolant channel A", group: 6, type: "integer", - default_mm: 7, default_in: 7, - values: [ - { title: "M7 flood", id: 7 }, - { title: "M8 mist", id: 8 }, - ] - }, - coolantBGrbl: { - title: "Coolant: B code", description: "GRBL g-codes for control Coolant channel B", group: 6, type: "integer", - default_mm: 8, default_in: 8, - values: [ - { title: "M7 flood", id: 7 }, - { title: "M8 mist", id: 8 }, - ] - }, -}); - -function FirmwareGrbl() { - FirmwareBase.apply(this, arguments); -} - -FirmwareGrbl.prototype = Object.create(FirmwareBase.prototype); -FirmwareGrbl.prototype.constructor = FirmwareGrbl; -FirmwareGrbl.prototype.init = function () { - gMotionModal = createModal({}, gFormat); // modal group 1 // G0-G3, ... - writeln("%"); -} -FirmwareGrbl.prototype.start = function () { - writeBlock(gAbsIncModal.format(90)); // Set to Absolute Positioning - writeBlock(gFeedModeModal.format(94)); - writeBlock(gPlaneModal.format(17)); - writeBlock(gUnitModal.format(unit == IN ? 20 : 21)); -} -FirmwareGrbl.prototype.end = function () { - writeBlock(mFormat.format(30)); -} -FirmwareGrbl.prototype.close = function () { - writeln("%"); -} -FirmwareGrbl.prototype.comment = function (text) { - writeln("(" + String(text).replace(/[\(\)]/g, "") + ")"); -} -FirmwareGrbl.prototype.flushMotions = function () { -}, - FirmwareGrbl.prototype.spindleOn = function (_spindleSpeed, _clockwise) { - writeActivityComment(" >>> Spindle Speed " + speedFormat.format(_spindleSpeed)); - writeBlock(mFormat.format(_clockwise ? 3 : 4), sOutput.format(spindleSpeed)); - } -FirmwareGrbl.prototype.spindleOff = function () { - writeBlock(mFormat.format(5)); -} -FirmwareGrbl.prototype.laserOn = function (power) { - var laser_pwm = power / 100 * 255; - writeBlock(mFormat.format(properties.cutterGrblMode), sFormat.format(laser_pwm)); -} -FirmwareGrbl.prototype.laserOff = function () { - writeBlock(mFormat.format(5)); -} -FirmwareGrbl.prototype.coolantA = function (on) { - writeBlock(mFormat.format(on ? properties.coolantAGrbl : 9)); -} -FirmwareGrbl.prototype.coolantB = function (on) { - writeBlock(mFormat.format(on ? properties.coolantBGrbl : 9)); -} -FirmwareGrbl.prototype.dwell = function (seconds) { - seconds = clamp(0.001, seconds, 99999.999); - writeBlock(gFormat.format(4), "P" + secFormat.format(seconds)); -} -FirmwareGrbl.prototype.display_text = function (txt) { -} -FirmwareGrbl.prototype.circular = function (clockwise, cx, cy, cz, x, y, z, feed) { - if (!properties.jobUseArcs) { - linearize(tolerance); - return; - } - var start = getCurrentPosition(); - - if (isFullCircle()) { - if (isHelical()) { - linearize(tolerance); - return; - } - switch (getCircularPlane()) { - case PLANE_XY: - writeBlock(gPlaneModal.format(17), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), iOutput.format(cx - start.x, 0), jOutput.format(cy - start.y, 0), fOutput.format(feed)); - break; - case PLANE_ZX: - writeBlock(gPlaneModal.format(18), gMotionModal.format(clockwise ? 2 : 3), zOutput.format(z), iOutput.format(cx - start.x, 0), kOutput.format(cz - start.z, 0), fOutput.format(feed)); - break; - case PLANE_YZ: - writeBlock(gPlaneModal.format(19), gMotionModal.format(clockwise ? 2 : 3), yOutput.format(y), jOutput.format(cy - start.y, 0), kOutput.format(cz - start.z, 0), fOutput.format(feed)); - break; - default: - linearize(tolerance); - } - } else { - switch (getCircularPlane()) { - case PLANE_XY: - writeBlock(gPlaneModal.format(17), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), iOutput.format(cx - start.x, 0), jOutput.format(cy - start.y, 0), fOutput.format(feed)); - break; - case PLANE_ZX: - writeBlock(gPlaneModal.format(18), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), iOutput.format(cx - start.x, 0), kOutput.format(cz - start.z, 0), fOutput.format(feed)); - break; - case PLANE_YZ: - writeBlock(gPlaneModal.format(19), gMotionModal.format(clockwise ? 2 : 3), xOutput.format(x), yOutput.format(y), zOutput.format(z), jOutput.format(cy - start.y, 0), kOutput.format(cz - start.z, 0), fOutput.format(feed)); - break; - default: - linearize(tolerance); - } - } -} -FirmwareGrbl.prototype.toolChange = function () { - writeBlock(mFormat.format(6), tFormat.format(tool.number)); - writeBlock(gFormat.format(54)); -} -FirmwareGrbl.prototype.probeTool = function () { -} - -currentFirmware = new FirmwareGrbl(); \ No newline at end of file diff --git a/DIYCNC_Marlin20.cps b/DIYCNC_Marlin20.cps deleted file mode 100644 index d2500d2..0000000 --- a/DIYCNC_Marlin20.cps +++ /dev/null @@ -1,21 +0,0 @@ -/* - -https://github.com/guffy1234/mpcnc_posts_processor - -MPCNC posts processor for milling and laser/plasma cutting. - -*/ -include("DIYCNC_Common.js"); - -description = "DIYCNC Milling/Laser - Marlin 2.0"; - -mergeProperties(properties, properties3dPrinter); -mergeProperties(propertyDefinitions, propertyDefinitions3dPrinter); - -function FirmwareMarlin20() { - Firmware3dPrinterLike.apply(this, arguments); -} -FirmwareMarlin20.prototype = Object.create(Firmware3dPrinterLike.prototype); -FirmwareMarlin20.prototype.constructor = FirmwareMarlin20; - -currentFirmware = new FirmwareMarlin20(); diff --git a/DIYCNC_RepRapFW.cps b/DIYCNC_RepRapFW.cps deleted file mode 100644 index 0bcdcca..0000000 --- a/DIYCNC_RepRapFW.cps +++ /dev/null @@ -1,65 +0,0 @@ -/* - -https://github.com/guffy1234/mpcnc_posts_processor - -MPCNC posts processor for milling and laser/plasma cutting. - -*/ -include("DIYCNC_Common.js"); - -description = "DIYCNC Milling/Laser - RepRapFirmware"; - -// user-defined properties -mergeProperties(properties, properties3dPrinter); -mergeProperties(propertyDefinitions, propertyDefinitions3dPrinter); - -mergeProperties(properties, { - jobDuetMillingMode: "M453 P2 I0 R30000 F200", // GCode command to setup Duet3d milling mode - jobDuetLaserMode: "M452 P2 I0 R255 F200", // GCode command to setup Duet3d laser mode -}); -mergeProperties(propertyDefinitions, { - jobDuetMillingMode: { - title: "Job: Duet Milling mode", description: "GCode command to setup Duet3d milling mode", group: 1, type: "string", - default_mm: "M453 P2 I0 R30000 F200", default_in: "M453 P2 I0 R30000 F200" - }, - jobDuetLaserMode: { - title: "Job: Duet Laser mode", description: "GCode command to setup Duet3d laser mode", group: 1, type: "string", - default_mm: "M452 P2 I0 R255 F200", default_in: "M452 P2 I0 R255 F200" - }, -}); - - -function FirmwareRepRap() { - Firmware3dPrinterLike.apply(this, arguments); -} -FirmwareRepRap.prototype = Object.create(Firmware3dPrinterLike.prototype); -FirmwareRepRap.prototype.constructor = FirmwareRepRap; -FirmwareRepRap.prototype.askUser = function (text, title, allowJog) { - var v1 = " P\"" + text + "\" R\"" + title + "\" S3"; - var v2 = allowJog ? " X1 Y1 Z1" : ""; - writeBlock(mFormat.format(291), (properties.jobSeparateWordsWithSpace ? "" : " ") + v1 + v2); -} -FirmwareRepRap.prototype.section = function () { - if (this.machineMode != currentSection.type) { - switch (currentSection.type) { - case TYPE_MILLING: - writeBlock(properties.jobDuetMillingMode); - break; - case TYPE_JET: - writeBlock(properties.jobDuetLaserMode); - break; - } - } - this.machineMode = currentSection.type; -} -FirmwareRepRap.prototype.laserOn = function (power) { - switch (properties.cutterMarlinMode) { - case 3: - var laser_pwm = power / 100 * 255; - writeBlock(mFormat.format(3), sFormat.format(laser_pwm)); - return; - } - Firmware3dPrinterLike.prototype.laserOn.apply(this, arguments); -} - -currentFirmware = new FirmwareRepRap(); \ No newline at end of file From 3c2946347608c40a212c017d7d2633fb0718b80c Mon Sep 17 00:00:00 2001 From: flyfisher604 Date: Sun, 7 Feb 2021 16:41:22 -0800 Subject: [PATCH 15/24] Debug outputs all params --- MPCNC.cps | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/MPCNC.cps b/MPCNC.cps index 9350777..9bf0a32 100644 --- a/MPCNC.cps +++ b/MPCNC.cps @@ -772,15 +772,30 @@ function onParameter(name, value) { writeComment(eComment.Important, value); writeComment(eComment.Important, " Posts processor: " + FileSystem.getFilename(getConfigurationPath())); } + // Date - if (name == "generated-at") writeComment(eComment.Important, " Gcode generated: " + value + " GMT"); + else if (name == "generated-at") { + writeComment(eComment.Important, " Gcode generated: " + value + " GMT"); + } + // Document - if (name == "document-path") writeComment(eComment.Important, " Document: " + value); + else if (name == "document-path") { + writeComment(eComment.Important, " Document: " + value); + } + // Setup - if (name == "job-description") writeComment(eComment.Important, " Setup: " + value); + else if (name == "job-description") { + writeComment(eComment.Important, " Setup: " + value); + } // Get section comment - if (name == "operation-comment") sectionComment = value; + else if (name == "operation-comment") { + sectionComment = value; + } + + else { + writeComment(eComment.Debug, " param: " + name + " = " + value); + } } function onMovement(movement) { From de81ddfbe764c2d9d37266edf6e2858a32d79e49 Mon Sep 17 00:00:00 2001 From: flyfisher604 Date: Sun, 7 Feb 2021 18:57:38 -0800 Subject: [PATCH 16/24] Parsing enhanced safeZ --- MPCNC.cps | 152 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 111 insertions(+), 41 deletions(-) diff --git a/MPCNC.cps b/MPCNC.cps index 9bf0a32..eced1d9 100644 --- a/MPCNC.cps +++ b/MPCNC.cps @@ -67,7 +67,7 @@ properties = { mapD_RestoreFirstRapids: false, // Map first G01 --> G00 mapE_RestoreRapids: false, // Map G01 --> G00 for SafeTravelsAboveZ - mapF_SafeZ: 5, // G01 mapped to G00 if Z is >= jobSafeZRapid + mapF_SafeZ: "5", // G01 mapped to G00 if Z is >= jobSafeZRapid mapG_AllowRapidZ: false, // Allow G01 --> G00 for vertical retracts and Z descents above safe toolChange0_Enabled: false, // Enable tool change code (bultin tool change requires LCD display) @@ -201,7 +201,7 @@ propertyDefinitions = { }, mapF_SafeZ: { title: "Map: Safe Z to Rapid", description: "Must be above or equal to this value to map G1s --> G0s", group: 3, - type: "integer", default_mm: 10, default_in: 0.590551 + type: "string", default_mm: "10", default_in: "0.590551" }, mapG_AllowRapidZ: { title: "Map: Allow Rapid Z", description: "Enable to include vertical retracts and safe descents", group: 3, @@ -288,7 +288,6 @@ propertyDefinitions = { ] }, - gcodeStartFile: { title: "Extern: Start File", description: "File with custom Gcode for header/start (in nc folder)", group: 7, type: "file", default_mm: "", default_in: "" @@ -463,6 +462,101 @@ function flushMotions() { } } +//---------------- Safe Rapids ---------------- + +var eSafeZ = { + CONST: 0, + FEED: 1, + RETRACT: 2, + CLEARANCE: 3, + ERROR: 4, + prop: { + 0: {name: "Const", regex: /^\d+\.?\d*$/, numRegEx: /^(\d+\.?\d*)$/, value: 0}, + 1: {name: "Feed", regex: /^Feed:/i, numRegEx: /:(\d+\.?\d*)$/, value: 1}, + 2: {name: "Retract", regex: /^Retract:/i, numRegEx: /:(\d+\.?\d*)$/, alue: 2}, + 3: {name: "Clearance", regex: /^Clearance:/i, numRegEx: /:(\d+\.?\d*)$/, value: 3}, + 4: {name: "Error", regex: /^$/, numRegEx: /^$/, value: 4} + } +}; + +var safeZMode = eSafeZ.CONST; +var safeZHeightDefault = 15; +var safeZHeight; + +function parseSafeZProperty() { + var str = properties.mapF_SafeZ; + + // Look for either a number by itself or 'Feed:', 'Retract:' or 'Clearance:' + for (safeZMode = eSafeZ.CONST; safeZMode < eSafeZ.ERROR; safeZMode++) { + if (str.search(eSafeZ.prop[safeZMode].regex) == 0) { + break; + } + } + + // If it was not an error then get the number + if (safeZMode != eSafeZ.ERROR) { + safeZHeightDefault = str.match(eSafeZ.prop[safeZMode].numRegEx); + + if ((safeZHeightDefault == null) || (safeZHeightDefault.length !=2)) { + writeComment(eComment.Debug, " parseSafeZProperty: " + safeZHeightDefault); + writeComment(eComment.Debug, " parseSafeZProperty.length: " + (safeZHeightDefault != null? safeZHeightDefault.length : "na")); + writeComment(eComment.Debug, " parseSafeZProperty: Couldn't find number"); + safeZMode = eSafeZ.ERROR; + safeZHeightDefault = 15; + } + else { + safeZHeightDefault = safeZHeightDefault[1]; + } + } + + writeComment(eComment.Debug, " parseSafeZProperty: safeZMode = '" + eSafeZ.prop[safeZMode].name + "'"); + writeComment(eComment.Debug, " parseSafeZProperty: safeZHeightDefault = " + safeZHeightDefault); +} + +function setSafeZforSection() +{ + +} + + +// Returns true if the rules to convert G1s to G0s are satisfied +function isSafeToRapid(x, y, z) { + if (properties.mapE_RestoreRapids) { + let zSafe = (z >= properties.mapF_SafeZ); + + // Destination z must be in safe zone. + if (zSafe) { + let cur = getCurrentPosition(); + let zConstant = (z == cur.z); + let zUp = (z > cur.z); + let xyConstant = ((x == cur.x) && (y == cur.y)); + let curZSafe = (cur.z >= properties.mapF_SafeZ); + + // Restore Rapids only when the target Z is safe and + // Case 1: Z is not changing, but XY are + // Case 2: Z is increasing, but XY constant + + // Z is not changing and we know we are in the safe zone + if (zConstant) { + return true; + } + + // We include moves of Z up as long as xy are constant + else if (properties.mapG_AllowRapidZ && zUp && xyConstant) { + return true; + } + + // We include moves of Z down as long as xy are constant and z always remains safe + else if (properties.mapG_AllowRapidZ && (!zUp) && xyConstant && curZSafe) { + return true; + } + } + } + + return false; +} + +//---------------- Coolant ---------------- // Coolant function CoolantA(on) { writeBlock(on ? properties.cl2_coolantAOn : properties.cl3_coolantAOff); @@ -476,22 +570,34 @@ function CoolantB(on) { function onOpen() { fw = properties.job0_SelectedFirmware; + // Output anything special to start the GCode if (fw == eFirmware.GRBL) { - gMotionModal = createModal({}, gFormat); // modal group 1 // G0-G3, ... writeln("%"); } + + // Configure the GCode G commands + if (fw == eFirmware.GRBL) { + gMotionModal = createModal({}, gFormat); // modal group 1 // G0-G3, ... + } else { gMotionModal = createModal({ force: true }, gFormat); // modal group 1 // G0-G3, ... } + // Configure how the feedrate is formatted if (properties.fr2_EnforceFeedrate) { fOutput = createVariable({ force: true }, fFormat); } + // Set the starting sequence number for line numbering sequenceNumber = properties.job6_SequenceNumberStart; + + // Set the seperator used between text if (!properties.job8_SeparateWordsWithSpace) { setWordSeparator(""); } + + // Determine the safeZHeight to do rapids + parseSafeZProperty(); } // Called at end of gcode file @@ -640,42 +746,6 @@ function onRapid(x, y, z) { rapidMovements(x, y, z); } -function safeToRapid(x, y, z) { - if (properties.mapE_RestoreRapids) { - let zSafe = (z >= properties.mapF_SafeZ); - - // Destination z must be in safe zone. - if (zSafe) { - let cur = getCurrentPosition(); - let zConstant = (z == cur.z); - let zUp = (z > cur.z); - let xyConstant = ((x == cur.x) && (y == cur.y)); - let curZSafe = (cur.z >= properties.mapF_SafeZ); - - // Restore Rapids only when the target Z is safe and - // Case 1: Z is not changing, but XY are - // Case 2: Z is increasing, but XY constant - - // Z is not changing and we know we are in the safe zone - if (zConstant) { - return true; - } - - // We include moves of Z up as long as xy are constant - else if (properties.mapG_AllowRapidZ && zUp && xyConstant) { - return true; - } - - // We include moves of Z down as long as xy are constant and z always remains safe - else if (properties.mapG_AllowRapidZ && (!zUp) && xyConstant && curZSafe) { - return true; - } - } - } - - return false; -} - // Feed movements function onLinear(x, y, z, feed) { // If we are allowing Rapids to be recovered from Linear (cut) moves, which is @@ -693,7 +763,7 @@ function onLinear(x, y, z, feed) { forceSectionToStartWithRapid = false; onRapid(x, y, z); } - else if (safeToRapid(x, y, z)) { + else if (isSafeToRapid(x, y, z)) { writeComment(eComment.Important, " Safe G1 --> G0"); onRapid(x, y, z); From 8a015465b31f265dc0626a11e6afaa0438f459a2 Mon Sep 17 00:00:00 2001 From: flyfisher604 Date: Mon, 8 Feb 2021 00:48:24 -0800 Subject: [PATCH 17/24] docs updated --- MPCNC.cps | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++----- README.md | 19 +++++++----- 2 files changed, 94 insertions(+), 15 deletions(-) diff --git a/MPCNC.cps b/MPCNC.cps index eced1d9..119aaeb 100644 --- a/MPCNC.cps +++ b/MPCNC.cps @@ -67,7 +67,7 @@ properties = { mapD_RestoreFirstRapids: false, // Map first G01 --> G00 mapE_RestoreRapids: false, // Map G01 --> G00 for SafeTravelsAboveZ - mapF_SafeZ: "5", // G01 mapped to G00 if Z is >= jobSafeZRapid + mapF_SafeZ: "Retract:15", // G01 mapped to G00 if Z is >= jobSafeZRapid mapG_AllowRapidZ: false, // Allow G01 --> G00 for vertical retracts and Z descents above safe toolChange0_Enabled: false, // Enable tool change code (bultin tool change requires LCD display) @@ -200,8 +200,8 @@ propertyDefinitions = { type: "boolean", default_mm: false, default_in: false }, mapF_SafeZ: { - title: "Map: Safe Z to Rapid", description: "Must be above or equal to this value to map G1s --> G0s", group: 3, - type: "string", default_mm: "10", default_in: "0.590551" + title: "Map: Safe Z to Rapid", description: "Must be above or equal to this value to map G1s --> G0s; constant or keyword (see docs)", group: 3, + type: "string", default_mm: "Retract:15", default_in: "Retract:15" }, mapG_AllowRapidZ: { title: "Map: Allow Rapid Z", description: "Enable to include vertical retracts and safe descents", group: 3, @@ -513,16 +513,89 @@ function parseSafeZProperty() { writeComment(eComment.Debug, " parseSafeZProperty: safeZHeightDefault = " + safeZHeightDefault); } -function setSafeZforSection() +function safeZforSection(_section) { - + if (properties.mapE_RestoreRapids) { + switch (safeZMode) { + case eSafeZ.CONST: + safeZHeight = safeZHeightDefault; + writeComment(eComment.Important, " SafeZ using const: " + safeZHeight); + break; + + case eSafeZ.FEED: + if (hasParameter("operation:feedHeight_value") && hasParameter("operation:feedHeight_absolute")) { + let feed = _section.getParameter("operation:feedHeight_value"); + let abs = _section.getParameter("operation:feedHeight_absolute"); + + if (abs == 1) { + safeZHeight = feed; + writeComment(eComment.Info, " SafeZ feed level: " + safeZHeight); + } + else { + safeZHeight = safeZHeightDefault; + writeComment(eComment.Important, " SafeZ feed level not abs: " + safeZHeight); + } + } + else { + safeZHeight = safeZHeightDefault; + writeComment(eComment.Important, " SafeZ feed level not defined: " + safeZHeight); + } + break; + + case eSafeZ.RETRACT: + if (hasParameter("operation:retractHeight_value") && hasParameter("operation:retractHeight_absolute")) { + let retract = _section.getParameter("operation:retractHeight_value"); + let abs = _section.getParameter("operation:retractHeight_absolute"); + + if (abs == 1) { + safeZHeight = retract; + writeComment(eComment.Info, " SafeZ retract level: " + safeZHeight); + } + else { + safeZHeight = safeZHeightDefault; + writeComment(eComment.Important, " SafeZ retract level not abs: " + safeZHeight); + } + } + else { + safeZHeight = safeZHeightDefault; + writeComment(eComment.Important, " SafeZ: retract level not defined: " + safeZHeight); + } + break; + + case eSafeZ.CLEARANCE: + if (hasParameter("operation:clearanceHeight_value") && hasParameter("operation:clearanceHeight_absolute")) { + var clearance = _section.getParameter("operation:clearanceHeight_value"); + let abs = _section.getParameter("operation:clearanceHeight_absolute"); + + if (abs == 1) { + safeZHeight = clearance; + writeComment(eComment.Info, " SafeZ clearance level: " + safeZHeight); + } + else { + safeZHeight = safeZHeightDefault; + writeComment(eComment.Important, " SafeZ clearance level not abs: " + safeZHeight); + } + } + else { + safeZHeight = safeZHeightDefault; + writeComment(eComment.Important, " SafeZ clearance level not defined: " + safeZHeight); + } + break; + + case eSafeZ.ERROR: + safeZHeight = safeZHeightDefault; + writeComment(eComment.Important, " >>> WARNING: " + propertyDefinitions.mapF_SafeZ.title + "format error: " + safeZHeight); + break; + } + } } // Returns true if the rules to convert G1s to G0s are satisfied function isSafeToRapid(x, y, z) { if (properties.mapE_RestoreRapids) { - let zSafe = (z >= properties.mapF_SafeZ); + //let zSafe = (z >= properties.mapF_SafeZ); + let zSafe = (z >= safeZHeight); // Destination z must be in safe zone. if (zSafe) { @@ -646,6 +719,9 @@ function onSection() { writeComment(eComment.Important, " *** SECTION begin ***"); + // Determine the Safe Z Height to map G1s to G0s + safeZforSection(currentSection); + // Do a tool change if tool changes are enabled and its not the first section and this section uses // a different tool then the previous section if (properties.toolChange0_Enabled && !isFirstSection() && tool.number != getPreviousSection().getTool().number) { @@ -1076,7 +1152,7 @@ function writeInformation() { writeComment(eComment.Info, " G1->G0 Mapping Properties:"); writeComment(eComment.Info, " Map: First G1 -> G0 Rapid = " + properties.mapD_RestoreFirstRapids); writeComment(eComment.Info, " Map: G1s -> G0 Rapids = " + properties.mapE_RestoreRapids); - writeComment(eComment.Info, " Map: Safe Z to Rapid = " + properties.mapF_SafeZ); + writeComment(eComment.Info, " Map: SafeZ Mode = " + eSafeZ.prop[safeZMode].name + " : default = " + safeZHeightDefault); writeComment(eComment.Info, " Map: Allow Rapid Z = " + properties.mapG_AllowRapidZ); writeComment(eComment.Info, " "); diff --git a/README.md b/README.md index 4a85d42..8a746a7 100644 --- a/README.md +++ b/README.md @@ -91,19 +91,22 @@ identified in forums as the tool being initially dragged across the work surface If [Map: G1s -> G0s] is true then allows G1 XY cut movements (i.e. no change in Z) that occur at a height greater or equal to [Map: Safe Z to Rapid] to be converted to G0 Rapids. -Note: this assumes that the top of material is 0 in F360 and that any Z above -[Map: Safe Z to Rapid] is a movement in the air and clear of obstacles. If top of material is not 0 -or there are holddown clamp then adjust [Map: Safe Z to Rapid] appropriately. +Note: this assumes that any Z above [Map: Safe Z to Rapid] is a movement in the air and clear of +obstacles. Can be defined as a number or one of F360's planes (Feed, Retract or Clearance). + +Map: Safe Z for Rapids may be defined as: +* As a constant numeric value - safe Z will then always be this value for all sections, or +* As a reference to a F360 Height - safe Z will then follow the Height defined within the operation's Height tab. Allowable Heights are: Feed, Retract, or Clearance. The Height must be followed by a ":" and then a numeric value. The value will be used if Height is not defined for a section. If [Map: Allow Rapid Z] is true then G1 Z cut movements that either move straight up and end above [Map: Safe Z to Rapid], or straight down with the start and end positions both above [Map: Safe Z to Rapid] are included. Only occurs if [Map: G1s -> G0s] is also true. -|Title|Description|Default| -|---|---|---| -Map: First G1 -> G0 Rapid|Converts the first G1 of a cut to G0 Rapid|**false**| -Map: G1s -> G0s|Allow G1 cuts to be converted to Rapid G0 moves when safe and appropriate.|**false**| -Map: Safe Z for Rapids|A G1 cut's Z must be >= to this to be mapped to a Rapid G0.|**10**| +|Title|Description|Default|Format| +|---|---|---|---| +Map: First G1 -> G0 Rapid|Converts the first G1 of a cut to G0 Rapid|**false**| | +Map: G1s -> G0s|Allow G1 cuts to be converted to Rapid G0 moves when safe and appropriate.|**false**| | +Map: Safe Z for Rapids|A G1 cut's Z must be >= to this to be mapped to a Rapid G0. Can be a number (used for all sections) or a reference to F360's Height followed by a default if Height is not available.|**Retract:15**| \ or \:\; e.g. 10 or Retract:7 or Feed:5| Map: Allow Rapid Z|Include vertical cut if they are safe.|**false**| ## Group 4: Tool change Properties From fdee99cef94091d83573dac6a22fece5b559f494 Mon Sep 17 00:00:00 2001 From: flyfisher604 Date: Wed, 10 Feb 2021 23:48:50 -0800 Subject: [PATCH 18/24] Readme updates --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8a746a7..9bc2d99 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,12 @@ Some design points: # Properties +> WARNING: If you are using the Fusion 360 for Personal Use license, formally know as the Fusion 360 Hobbyist license, please respect the [limitations of that license](https://knowledge.autodesk.com/support/fusion-360/learn-explore/caas/sfdcarticles/sfdcarticles/Fusion-360-Free-License-Changes.html). To remain compliant with that license set your [Feed: Travel Speed X/Y] and [Feed: Travel Speed Z] no faster then your machine's maximum cut feedrate (see Group 2 Properties). +> +>Fusion 360 for Personal Use restricts all moves not to exceed the maximum cut speed. This has been implemented not by reducing the speed of G0s but by changing all G0 (moves) to G1 (cut) commands. The side effect of this was to unintentionally introduce situations where tool dragging and/or work piece collisions occur, general at the start of jobs or after tool changes. +> +>You can choose to resolve these issues by enabling the selective mapping of G1s->G0s (see Group 3 Properties). Theses issues are resolved as the post processor implements G0 moves by doing first a move in Z and then a move in X,Y while a G1 cuts travel in X,Y,Z at the same time. + ## Group 1: Job Properties Use these properties to control overall aspects of the job. @@ -106,8 +112,8 @@ above [Map: Safe Z to Rapid] are included. Only occurs if [Map: G1s -> G0s] is a |---|---|---|---| Map: First G1 -> G0 Rapid|Converts the first G1 of a cut to G0 Rapid|**false**| | Map: G1s -> G0s|Allow G1 cuts to be converted to Rapid G0 moves when safe and appropriate.|**false**| | -Map: Safe Z for Rapids|A G1 cut's Z must be >= to this to be mapped to a Rapid G0. Can be a number (used for all sections) or a reference to F360's Height followed by a default if Height is not available.|**Retract:15**| \ or \:\; e.g. 10 or Retract:7 or Feed:5| -Map: Allow Rapid Z|Include vertical cut if they are safe.|**false**| +Map: Safe Z for Rapids|A G1 cut's Z must be >= to this to be mapped to a Rapid G0. Can be two formats (1) a number which will be used for all sections, or (2) a reference to F360's Height followed by a default if Height is not available.|**Retract:15** (use the Retract height and if not available 15)| \ or \:\; e.g. 10 or Retract:7 or Feed:5| +Map: Allow Rapid Z|Include the mapping of vertical cuts if they are safe.|**false**| ## Group 4: Tool change Properties From 7216e9ef71ef724659f6e3b97652bf5941f60bc0 Mon Sep 17 00:00:00 2001 From: flyfisher604 Date: Wed, 10 Feb 2021 23:53:19 -0800 Subject: [PATCH 19/24] Grbl laser 0 to 1000 --- MPCNC.cps | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/MPCNC.cps b/MPCNC.cps index 119aaeb..69dc08a 100644 --- a/MPCNC.cps +++ b/MPCNC.cps @@ -1493,15 +1493,18 @@ function spindleOff() { } function laserOn(power) { - var laser_pwm = power / 100 * 255; // Firmware is Grbl if (fw == eFirmware.GRBL) { + var laser_pwm = power * 10; + writeBlock(mFormat.format(properties.cutterGrblMode), sFormat.format(laser_pwm)); } // Default firmware else { + var laser_pwm = power / 100 * 255; + switch (properties.cutterMarlinMode) { case 106: writeBlock(mFormat.format(106), sFormat.format(laser_pwm)); From 17c9d2e9b39cf465aa3be1aa89335bee370dba7e Mon Sep 17 00:00:00 2001 From: flyfisher604 Date: Sat, 13 Feb 2021 16:43:33 -0800 Subject: [PATCH 20/24] Fixes #6 --- MPCNC.cps | 174 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 103 insertions(+), 71 deletions(-) diff --git a/MPCNC.cps b/MPCNC.cps index 69dc08a..0905c1f 100644 --- a/MPCNC.cps +++ b/MPCNC.cps @@ -44,6 +44,30 @@ var eComment = { } }; +var eCoolant = { + Off: 0, + Flood: 1, + Mist: 2, + ThroughTool: 3, + Air: 4, + AirThroughTool: 5, + Suction: 6, + FloodMist: 7, + FloodThroughTool: 8, + prop: { + 0: {name: "Off", value: 0}, + 1: {name: "Flood", value: 1}, + 2: {name: "Mist", value: 2}, + 3: {name: "ThroughTool", value: 3}, + 4: {name: "Air", value: 4}, + 5: {name: "AirThroughTool", value: 5}, + 6: {name: "Suction", value: 6}, + 7: {name: "Flood and Mist", value: 7}, + 8: {name: "Flood and ThroughTool", value: 8}, + } +}; + + // user-defined properties properties = { job0_SelectedFirmware : fw, // Firmware to use in special cases @@ -95,8 +119,8 @@ properties = { cutterMarlinPin: 4, // Marlin laser/plasma cutter pin for M42 cutterGrblMode: 4, // GRBL mode laser/plasma cutter - cl0_coolantA_Mode: 0, // Enable issuing g-codes for control Coolant channel A - cl1_coolantB_Mode: 0, // Use issuing g-codes for control Coolant channel B + cl0_coolantA_Mode: eCoolant.Off, // Enable issuing g-codes for control Coolant channel A + cl1_coolantB_Mode: eCoolant.Off, // Use issuing g-codes for control Coolant channel B cl2_coolantAOn: "M42 P6 S255", // GCode command to turn on Coolant channel A cl3_coolantAOff: "M42 P6 S0", // Gcode command to turn off Coolant channel A cl4_coolantBOn: "M42 P11 S255", // GCode command to turn on Coolant channel B @@ -310,30 +334,30 @@ propertyDefinitions = { title: "Coolant: A Mode", description: "Enable channel A when tool is set this coolant", group: 8, type: "integer", default_mm: 0, default_in: 0, values: [ - { title: "off", id: 0 }, - { title: "flood", id: 1 }, - { title: "mist", id: 2 }, - { title: "throughTool", id: 3 }, - { title: "air", id: 4 }, - { title: "airThroughTool", id: 5 }, - { title: "suction", id: 6 }, - { title: "floodMist", id: 7 }, - { title: "floodThroughTool", id: 8 } + { title: eCoolant.prop[eCoolant.Off].name, id: eCoolant.Off }, + { title: eCoolant.prop[eCoolant.Flood].name, id: eCoolant.Flood }, + { title: eCoolant.prop[eCoolant.Mist].name, id: eCoolant.Mist }, + { title: eCoolant.prop[eCoolant.ThroughTool].name, id: eCoolant.ThroughTool }, + { title: eCoolant.prop[eCoolant.Air].name, id: eCoolant.Air }, + { title: eCoolant.prop[eCoolant.AirThroughTool].name, id: eCoolant.AirThroughTool }, + { title: eCoolant.prop[eCoolant.Suction].name, id: eCoolant.Suction }, + { title: eCoolant.prop[eCoolant.FloodMist].name, id: eCoolant.FloodMist }, + { title: eCoolant.prop[eCoolant.FloodThroughTool].name, id: eCoolant.FloodThroughTool } ] }, cl1_coolantB_Mode: { title: "Coolant: B Mode", description: "Enable channel B when tool is set this coolant", group: 8, type: "integer", default_mm: 0, default_in: 0, values: [ - { title: "off", id: 0 }, - { title: "flood", id: 1 }, - { title: "mist", id: 2 }, - { title: "throughTool", id: 3 }, - { title: "air", id: 4 }, - { title: "airThroughTool", id: 5 }, - { title: "suction", id: 6 }, - { title: "floodMist", id: 7 }, - { title: "floodThroughTool", id: 8 } + { title: eCoolant.prop[eCoolant.Off].name, id: eCoolant.Off }, + { title: eCoolant.prop[eCoolant.Flood].name, id: eCoolant.Flood }, + { title: eCoolant.prop[eCoolant.Mist].name, id: eCoolant.Mist }, + { title: eCoolant.prop[eCoolant.ThroughTool].name, id: eCoolant.ThroughTool }, + { title: eCoolant.prop[eCoolant.Air].name, id: eCoolant.Air }, + { title: eCoolant.prop[eCoolant.AirThroughTool].name, id: eCoolant.AirThroughTool }, + { title: eCoolant.prop[eCoolant.Suction].name, id: eCoolant.Suction }, + { title: eCoolant.prop[eCoolant.FloodMist].name, id: eCoolant.FloodMist }, + { title: eCoolant.prop[eCoolant.FloodThroughTool].name, id: eCoolant.FloodThroughTool } ] }, cl2_coolantAOn: { @@ -630,7 +654,7 @@ function isSafeToRapid(x, y, z) { } //---------------- Coolant ---------------- -// Coolant + function CoolantA(on) { writeBlock(on ? properties.cl2_coolantAOn : properties.cl3_coolantAOff); } @@ -639,6 +663,64 @@ function CoolantB(on) { writeBlock(on ? properties.cl4_coolantBOn : properties.cl5_coolantBOff); } +// Manage two channels of coolant by tracking which coolant is being using for +// a channel (0 = disabled). SetCoolant called with desired coolant to use or 0 to disable + +var curCoolant = eCoolant.Off; // The coolant requested by the tool +var coolantChannelA = 0; // The coolant running in ChannelA +var coolantChannelB = 0; // The coolant running in ChannelB + +function setCoolant(coolant) { + // If the coolant for this tool is the same as the current coolant then there is nothing to do + if (curCoolant == coolant) { + return; + } + + // We are changing coolant, so disable any active coolant channels + // before we switch to the other coolant + if (coolantChannelA != eCoolant.Off) { + writeComment((coolant == eCoolant.Off) ? eComment.Important: eComment.Info, " >>> Coolant Channel A: " + eCoolant.prop[eCoolant.Off].name); + coolantChannelA = eCoolant.Off; + CoolantA(false); + } + + if (coolantChannelB != eCoolant.Off) { + writeComment((coolant == eCoolant.Off) ? eComment.Important: eComment.Info, " >>> Coolant Channel B: " + eCoolant.prop[eCoolant.Off].name); + coolantChannelB = eCoolant.Off; + CoolantB(false); + } + + // At this point we know that all coolant is off so make that the current coolant + curCoolant = eCoolant.Off; + + // As long as we are not disabling coolant (coolant = 0), then check if either coolant channel + // matches the coolant requested. If neither do then issue an warning + + var warn = true; + + if (coolant != eCoolant.Off) { + if (properties.cl0_coolantA_Mode == coolant) { + writeComment(eComment.Important, " >>> Coolant Channel A: " + eCoolant.prop[coolant].name); + coolantChannelA = coolant; + warn = false; + CoolantA(true); + } + + if (properties.cl1_coolantB_Mode == coolant) { + writeComment(eComment.Important, " >>> Coolant Channel B: " + eCoolant.prop[coolant].name); + coolantChannelB = coolant; + warn = false; + CoolantB(true); + } + + if (warn) { + writeComment(eComment.Important, " >>> WARNING: No matching Coolant channel : " + ((coolant <= eCoolant.FloodThroughTool) ? eCoolant.prop[coolant].name : "unknown") + " requested"); + } + } +} + +//---------------- on Entry Points ---------------- + // Called in every new gcode file function onOpen() { fw = properties.job0_SelectedFirmware; @@ -1337,56 +1419,6 @@ function loadFile(_file) { } } -// Manage two channels of coolant by tracking which coolant is being using for -// a channel (0 = disabled). SetCoolant called with desired coolant to use or 0 to disable - -var coolantChannelA = 0; -var coolantChannelB = 0; - -function setCoolant(coolant) { - // As long as we are not disabling coolant (= 0), then if either of the coolant - // channels are already operating in the mode requested then there is - // nothing to do - if ((coolant != 0) && - ((coolantChannelA == coolant) || (coolantChannelB == coolant))) { - return; - } - - // F360 allows only 1 coolant to be defined on an operation. If a coolant channel - // is active then disable it before we switch to the other - if (coolantChannelA != 0) { - writeComment((coolant == 0) ? eComment.Important: eComment.Info, " >>> Coolant Channel A: off"); - coolantChannelA = 0; - CoolantA(false); - } - - if (coolantChannelB != 0) { - writeComment((coolant == 0) ? eComment.Important: eComment.Info, " >>> Coolant Channel B: off"); - coolantChannelB = 0; - CoolantB(false); - } - - // As long as we are not disabling coolant (coolant = 0), then check the coolant channels - // and enable the one that provides the coolant requested. If neither do then - // issue an warning - if (coolant != 0) { - if (properties.cl0_coolantA_Mode == coolant) { - writeComment(eComment.Important, " >>> Coolant Channel A: " + propertyDefinitions.cl0_coolantA_Mode.values[coolant].title); - coolantChannelA = coolant; - CoolantA(true); - } - else if (properties.cl1_coolantB_Mode == coolant) { - writeComment(eComment.Important, " >>> Coolant Channel B: " + propertyDefinitions.cl1_coolantB_Mode.values[coolant].title); - coolantChannelB = coolant; - CoolantB(true); - } - else { - writeComment(eComment.Important, " >>> WARNING: No Coolant Channels Enabled: " + ((coolant < propertyDefinitions.cl0_coolantA_Mode.values.length) ? - propertyDefinitions.cl0_coolantA_Mode.values[coolant].title : "unknown") + " requested"); - } - } -} - function propertyMmToUnit(_v) { return (_v / (unit == IN ? 25.4 : 1)); } From 3dfdc08c2e74d5b1e8ba9b0cd546e86d75437d95 Mon Sep 17 00:00:00 2001 From: flyfisher604 Date: Sat, 13 Feb 2021 22:21:21 -0800 Subject: [PATCH 21/24] Merge commit '42628d156c638189e892b2af696f77811dc986fe' --- MPCNC.cps | 273 +++++++++++++++++++++++++++++++----------------------- README.md | 27 ++++-- 2 files changed, 177 insertions(+), 123 deletions(-) diff --git a/MPCNC.cps b/MPCNC.cps index 0905c1f..6c364c9 100644 --- a/MPCNC.cps +++ b/MPCNC.cps @@ -107,18 +107,19 @@ properties = { probe5_G38Target: -10, // probing up to pos probe6_G38Speed: 30, // probing with speed - gcodeStartFile: "", // File with custom Gcode for header/start (in nc folder) - gcodeStopFile: "", // File with custom Gcode for footer/end (in nc folder) - gcodeToolFile: "", // File with custom Gcode for tool change (in nc folder) - gcodeProbeFile: "", // File with custom Gcode for tool probe (in nc folder) - - cutterOnVaporize: 100, // Persent of power to turn on the laser/plasma cutter in vaporize mode - cutterOnThrough: 80, // Persent of power to turn on the laser/plasma cutter in through mode - cutterOnEtch: 40, // Persent of power to turn on the laser/plasma cutter in etch mode - cutterMarlinMode: 106, // Marlin mode laser/plasma cutter - cutterMarlinPin: 4, // Marlin laser/plasma cutter pin for M42 - cutterGrblMode: 4, // GRBL mode laser/plasma cutter - + gcodeStartFile: "", // File with custom Gcode for header/start (in nc folder) + gcodeStopFile: "", // File with custom Gcode for footer/end (in nc folder) + gcodeToolFile: "", // File with custom Gcode for tool change (in nc folder) + gcodeProbeFile: "", // File with custom Gcode for tool probe (in nc folder) + + cutter1_OnVaporize: 100, // Percentage of power to turn on the laser/plasma cutter in vaporize mode + cutter2_OnThrough: 80, // Percentage of power to turn on the laser/plasma cutter in through mode + cutter3_OnEtch: 40, // Percentage of power to turn on the laser/plasma cutter in etch mode + cutter4_MarlinMode: 106, // Marlin mode laser/plasma cutter + cutter5_MarlinPin: 4, // Marlin laser/plasma cutter pin for M42 + cutter6_GrblMode: 4, // GRBL mode laser/plasma cutter + cutter7_Coolant: eCoolant.Off, // Use this coolant. F360 doesn't define a coolant for cutters + cl0_coolantA_Mode: eCoolant.Off, // Enable issuing g-codes for control Coolant channel A cl1_coolantB_Mode: eCoolant.Off, // Use issuing g-codes for control Coolant channel B cl2_coolantAOn: "M42 P6 S255", // GCode command to turn on Coolant channel A @@ -278,19 +279,19 @@ propertyDefinitions = { type: "spatial", default_mm: 30, default_in: 1.2 }, - cutterOnVaporize: { + cutter1_OnVaporize: { title: "Laser: On - Vaporize", description: "Persent of power to turn on the laser/plasma cutter in vaporize mode", group: 6, type: "number", default_mm: 100, default_in: 100 }, - cutterOnThrough: { + cutter2_OnThrough: { title: "Laser: On - Through", description: "Persent of power to turn on the laser/plasma cutter in through mode", group: 6, type: "number", default_mm: 80, default_in: 80 }, - cutterOnEtch: { + cutter3_OnEtch: { title: "Laser: On - Etch", description: "Persent of power to on the laser/plasma cutter in etch mode", group: 6, type: "number", default_mm: 40, default_in: 40 }, - cutterMarlinMode: { + cutter4_MarlinMode: { title: "Laser: Marlin/Reprap Mode", description: "Marlin/Reprap mode of the laser/plasma cutter", group: 6, type: "integer", default_mm: 106, default_in: 106, values: [ @@ -299,11 +300,11 @@ propertyDefinitions = { { title: "Pin - M42 P{pin} S{PWM}", id: 42 }, ] }, - cutterMarlinPin: { + cutter5_MarlinPin: { title: "Laser: Marlin M42 Pin", description: "Marlin custom pin number for the laser/plasma cutter", group: 6, type: "integer", default_mm: 4, default_in: 4 }, - cutterGrblMode: { + cutter6_GrblMode: { title: "Laser: GRBL Mode", description: "GRBL mode of the laser/plasma cutter", group: 6, type: "integer", default_mm: 4, default_in: 4, values: [ @@ -311,6 +312,21 @@ propertyDefinitions = { { title: "M3 S{PWM}/M5 static power", id: 3 }, ] }, + cutter7_Coolant: { + title: "Laser: Coolant", description: "Force a coolant to be used", group: 6, + type: "integer", default_mm: eCoolant.Off, default_in: eCoolant.Off, + values: [ + { title: eCoolant.prop[eCoolant.Off].name, id: eCoolant.Off }, + { title: eCoolant.prop[eCoolant.Flood].name, id: eCoolant.Flood }, + { title: eCoolant.prop[eCoolant.Mist].name, id: eCoolant.Mist }, + { title: eCoolant.prop[eCoolant.ThroughTool].name, id: eCoolant.ThroughTool }, + { title: eCoolant.prop[eCoolant.Air].name, id: eCoolant.Air }, + { title: eCoolant.prop[eCoolant.AirThroughTool].name, id: eCoolant.AirThroughTool }, + { title: eCoolant.prop[eCoolant.Suction].name, id: eCoolant.Suction }, + { title: eCoolant.prop[eCoolant.FloodMist].name, id: eCoolant.FloodMist }, + { title: eCoolant.prop[eCoolant.FloodThroughTool].name, id: eCoolant.FloodThroughTool } + ] + }, gcodeStartFile: { title: "Extern: Start File", description: "File with custom Gcode for header/start (in nc folder)", group: 7, @@ -666,11 +682,13 @@ function CoolantB(on) { // Manage two channels of coolant by tracking which coolant is being using for // a channel (0 = disabled). SetCoolant called with desired coolant to use or 0 to disable -var curCoolant = eCoolant.Off; // The coolant requested by the tool -var coolantChannelA = 0; // The coolant running in ChannelA -var coolantChannelB = 0; // The coolant running in ChannelB +var curCoolant = eCoolant.Off; // The coolant requested by the tool +var coolantChannelA = eCoolant.Off; // The coolant running in ChannelA +var coolantChannelB = eCoolant.Off; // The coolant running in ChannelB function setCoolant(coolant) { + writeComment(eComment.Debug, " ---- Coolant: " + coolant + " cur: " + curCoolant + " A: " + coolantChannelA + " B: " + coolantChannelB); + // If the coolant for this tool is the same as the current coolant then there is nothing to do if (curCoolant == coolant) { return; @@ -702,6 +720,7 @@ function setCoolant(coolant) { if (properties.cl0_coolantA_Mode == coolant) { writeComment(eComment.Important, " >>> Coolant Channel A: " + eCoolant.prop[coolant].name); coolantChannelA = coolant; + curCoolant = coolant; warn = false; CoolantA(true); } @@ -709,6 +728,7 @@ function setCoolant(coolant) { if (properties.cl1_coolantB_Mode == coolant) { writeComment(eComment.Important, " >>> Coolant Channel B: " + eCoolant.prop[coolant].name); coolantChannelB = coolant; + curCoolant = coolant; warn = false; CoolantB(true); } @@ -719,6 +739,62 @@ function setCoolant(coolant) { } } +//---------------- Cutters - Waterjet/Laser/Plasma ---------------- + +var cutterOnCurrentPower; + +function laserOn(power) { + // Firmware is Grbl + if (fw == eFirmware.GRBL) { + var laser_pwm = power * 10; + + writeBlock(mFormat.format(properties.cutter6_GrblMode), sFormat.format(laser_pwm)); + } + + // Default firmware + else { + var laser_pwm = power / 100 * 255; + + switch (properties.cutter4_MarlinMode) { + case 106: + writeBlock(mFormat.format(106), sFormat.format(laser_pwm)); + break; + case 3: + if (fw == eFirmware.REPRAP) { + writeBlock(mFormat.format(3), sFormat.format(laser_pwm)); + } else { + writeBlock(mFormat.format(3), oFormat.format(laser_pwm)); + } + break; + case 42: + writeBlock(mFormat.format(42), pFormat.format(properties.cutter5_MarlinPin), sFormat.format(laser_pwm)); + break; + } + } +} + +function laserOff() { + // Firmware is Grbl + if (fw == eFirmware.GRBL) { + writeBlock(mFormat.format(5)); + } + + // Default + else { + switch (properties.cutter4_MarlinMode) { + case 106: + writeBlock(mFormat.format(107)); + break; + case 3: + writeBlock(mFormat.format(5)); + break; + case 42: + writeBlock(mFormat.format(42), pFormat.format(properties.cutter5_MarlinPin), sFormat.format(0)); + break; + } + } +} + //---------------- on Entry Points ---------------- // Called in every new gcode file @@ -780,7 +856,6 @@ function onClose() { } } -var cutterOnCurrentPower; var forceSectionToStartWithRapid = false; function onSection() { @@ -801,6 +876,13 @@ function onSection() { writeComment(eComment.Important, " *** SECTION begin ***"); + // Print min/max boundaries for each section + vectorX = new Vector(1, 0, 0); + vectorY = new Vector(0, 1, 0); + writeComment(eComment.Info, " X Min: " + xyzFormat.format(currentSection.getGlobalRange(vectorX).getMinimum()) + " - X Max: " + xyzFormat.format(currentSection.getGlobalRange(vectorX).getMaximum())); + writeComment(eComment.Info, " Y Min: " + xyzFormat.format(currentSection.getGlobalRange(vectorY).getMinimum()) + " - Y Max: " + xyzFormat.format(currentSection.getGlobalRange(vectorY).getMaximum())); + writeComment(eComment.Info, " Z Min: " + xyzFormat.format(currentSection.getGlobalZRange().getMinimum()) + " - Z Max: " + xyzFormat.format(currentSection.getGlobalZRange().getMaximum())); + // Determine the Safe Z Height to map G1s to G0s safeZforSection(currentSection); @@ -825,30 +907,37 @@ function onSection() { writeComment(eComment.Info, " " + sectionComment + " - Milling - Tool: " + tool.number + " - " + tool.comment + " " + getToolTypeName(tool.type)); } - if (currentSection.type == TYPE_JET) { + else if (currentSection.type == TYPE_JET) { + var jetModeStr; + var warn = false; + // Cutter mode used for different cutting power in PWM laser switch (currentSection.jetMode) { case JET_MODE_THROUGH: - cutterOnCurrentPower = properties.cutterOnThrough; + cutterOnCurrentPower = properties.cutter2_OnThrough; + jetModeStr = "Through" break; case JET_MODE_ETCHING: - cutterOnCurrentPower = properties.cutterOnEtch; + cutterOnCurrentPower = properties.cutter3_OnEtch; + jetModeStr = "Etching" break; case JET_MODE_VAPORIZE: - cutterOnCurrentPower = properties.cutterOnVaporize; + jetModeStr = "Vaporize" + cutterOnCurrentPower = properties.cutter1_OnVaporize; break; default: - error("Cutting mode is not supported."); + jetModeStr = "*** Unknown ***" + warn = true; } - writeComment(eComment.Info, " " + sectionComment + " - Laser/Plasma - Cutting mode: " + getParameter("operation:cuttingMode")); - } - // Print min/max boundaries for each section - vectorX = new Vector(1, 0, 0); - vectorY = new Vector(0, 1, 0); - writeComment(eComment.Info, " X Min: " + xyzFormat.format(currentSection.getGlobalRange(vectorX).getMinimum()) + " - X Max: " + xyzFormat.format(currentSection.getGlobalRange(vectorX).getMaximum())); - writeComment(eComment.Info, " Y Min: " + xyzFormat.format(currentSection.getGlobalRange(vectorY).getMinimum()) + " - Y Max: " + xyzFormat.format(currentSection.getGlobalRange(vectorY).getMaximum())); - writeComment(eComment.Info, " Z Min: " + xyzFormat.format(currentSection.getGlobalZRange().getMinimum()) + " - Z Max: " + xyzFormat.format(currentSection.getGlobalZRange().getMaximum())); + if (warn) { + writeComment(eComment.Info, " " + sectionComment + ", Laser/Plasma Cutting mode: " + getParameter("operation:cuttingMode") + ", jetMode: " + jetModeStr); + writeComment(eComment.Important, "Selected cutting mode " + currentSection.jetMode + " not mapped to power level"); + } + else { + writeComment(eComment.Info, " " + sectionComment + ", Laser/Plasma Cutting mode: " + getParameter("operation:cuttingMode") + ", jetMode: " + jetModeStr + ", power: " + cutterOnCurrentPower); + } + } // Adjust the mode if (fw == eFirmware.REPRAP) { @@ -873,13 +962,6 @@ function onSection() { display_text(" " + sectionComment); } -function resetAll() { - xOutput.reset(); - yOutput.reset(); - zOutput.reset(); - fOutput.reset(); -} - // Called in every section end function onSectionEnd() { resetAll(); @@ -1106,34 +1188,43 @@ function onSpindleSpeed(spindleSpeed) { } function onCommand(command) { - if (properties.commentActivities) { - var stringId = getCommandStringId(command); - writeComment(eComment.Info, " " + stringId); - } + writeComment(eComment.Info, " " + getCommandStringId(command)); + switch (command) { case COMMAND_START_SPINDLE: onCommand(tool.clockwise ? COMMAND_SPINDLE_CLOCKWISE : COMMAND_SPINDLE_COUNTERCLOCKWISE); return; case COMMAND_SPINDLE_CLOCKWISE: - if (tool.jetTool) - return; - setSpindeSpeed(spindleSpeed, true); + if (!tool.isJetTool()) { + setSpindeSpeed(spindleSpeed, true); + } return; case COMMAND_SPINDLE_COUNTERCLOCKWISE: - if (tool.jetTool) - return; - setSpindeSpeed(spindleSpeed, false); + if (!tool.isJetTool()) { + setSpindeSpeed(spindleSpeed, false); + } return; case COMMAND_STOP_SPINDLE: - if (tool.jetTool) - return; - setSpindeSpeed(0, true); + if (!tool.isJetTool()) { + setSpindeSpeed(0, true); + } return; case COMMAND_COOLANT_ON: - setCoolant(tool.coolant); + if (tool.isJetTool()) { + // F360 doesn't support coolant with jet tools (water jet/laser/plasma) but we've + // added a parameter to force a coolant to be selected for jet tool operations. Note: tool.coolant + // is not used as F360 doesn't define it. + + if (properties.cutter7_Coolant != eCoolant.Off) { + setCoolant(properties.cutter7_Coolant); + } + } + else { + setCoolant(tool.coolant); + } return; case COMMAND_COOLANT_OFF: - setCoolant(0); //COOLANT_DISABLED + setCoolant(eCoolant.Off); //COOLANT_DISABLED return; case COMMAND_LOCK_MULTI_AXIS: return; @@ -1142,9 +1233,9 @@ function onCommand(command) { case COMMAND_BREAK_CONTROL: return; case COMMAND_TOOL_MEASURE: - if (tool.jetTool) - return; - probeTool(); + if (!tool.isJetTool()) { + probeTool(); + } return; case COMMAND_STOP: writeBlock(mFormat.format(0)); @@ -1152,6 +1243,13 @@ function onCommand(command) { } } +function resetAll() { + xOutput.reset(); + yOutput.reset(); + zOutput.reset(); + fOutput.reset(); +} + function writeInformation() { // Calcualte the min/max ranges across all sections var toolZRanges = {}; @@ -1465,7 +1563,7 @@ function Start() { writeBlock(gFormat.format(92), xFormat.format(0), yFormat.format(0), zFormat.format(0)); // Set origin to initial position } - if (properties.probe1_OnStart && tool.number != 0 && !tool.jetTool) { + if (properties.probe1_OnStart && tool.number != 0 && !tool.isJetTool()) { onCommand(COMMAND_TOOL_MEASURE); } } @@ -1524,59 +1622,6 @@ function spindleOff() { } } -function laserOn(power) { - - // Firmware is Grbl - if (fw == eFirmware.GRBL) { - var laser_pwm = power * 10; - - writeBlock(mFormat.format(properties.cutterGrblMode), sFormat.format(laser_pwm)); - } - - // Default firmware - else { - var laser_pwm = power / 100 * 255; - - switch (properties.cutterMarlinMode) { - case 106: - writeBlock(mFormat.format(106), sFormat.format(laser_pwm)); - break; - case 3: - if (fw == eFirmware.REPRAP) { - writeBlock(mFormat.format(3), sFormat.format(laser_pwm)); - } else { - writeBlock(mFormat.format(3), oFormat.format(laser_pwm)); - } - break; - case 42: - writeBlock(mFormat.format(42), pFormat.format(properties.cutterMarlinPin), sFormat.format(laser_pwm)); - break; - } - } -} - -function laserOff() { - // Firmware is Grbl - if (fw == eFirmware.GRBL) { - writeBlock(mFormat.format(5)); - } - - // Default - else { - switch (properties.cutterMarlinMode) { - case 106: - writeBlock(mFormat.format(107)); - break; - case 3: - writeBlock(mFormat.format(5)); - break; - case 42: - writeBlock(mFormat.format(42), pFormat.format(properties.cutterMarlinPin), sFormat.format(0)); - break; - } - } -} - function display_text(txt) { // Firmware is Grbl if (fw == eFirmware.GRBL) { diff --git a/README.md b/README.md index 9bc2d99..a9d35dc 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This is modified fork of https://github.com/guffy1234/mpcnc_posts_processor that CAM posts processor for use with Fusion 360 and [MPCNC](https://www.v1engineering.com). -Supported firmwares: +Supported firmware: - Marlin 2.0 - Repetier firmware 1.0.3 (not tested. gcode is same as for Marlin) - GRBL 1.1 @@ -120,9 +120,9 @@ Map: Allow Rapid Z|Include the mapping of vertical cuts if they are safe.|**fals |Title|Description|Default| |---|---|---| Tool Change: Enable|Include tool change code when tool changes (bultin tool change requires LCD display|**false**| -Tool Change: X|X position for builtin tool change|**0**| -Tool Change: Y|Y position for builtin tool change|**0**| -Tool Change: Z|Z position for builtin tool change|**40**| +Tool Change: X|X position for built-in tool change|**0**| +Tool Change: Y|Y position for built-in tool change|**0**| +Tool Change: Z|Z position for built-in tool change|**40**| Tool Change: Disable Z stepper|Disable Z stepper after reaching tool change location|**false**| ## Group 5: Z Probe Properties @@ -138,6 +138,12 @@ Probe: G38 speed|G38 Probing's speed|**30**| ## Group 6: Laser/Plasma Properties +Fusion 360 defines four levels of Through cut, currently these all map to power level "On - Through". + +The firmware selected in the parameter [Job: CNC Firmware] determines if the Grbl or Marlin/Reprap laser parameters are used. + +Fusion 360 does not use a coolant when using its jet tools (waterjet/laser/plasma). When using a laser it may be desirable to use air or some other device you have connected to the coolant channels. The [Laser: Coolant] can be used to force a coolant to be used for the laser operations (see coolant parameter on details for configuring the coolant channels). + |Title|Description|Default|Values| |---|---|---|---| Laser: On - Vaporize|Persent of power to turn on the laser/plasma cutter in vaporize mode|**100**|| @@ -146,6 +152,7 @@ Laser: On - Etch|Persent of power to turn on the laser/plasma cutter in etch mod Laser: Marlin/Reprap Mode|Marlin/Reprap mode of the laser/plasma cutter|**Fan - M106 S{PWM}/M107**|"Fan - M106 S{PWM}/M107", "Spindle - M3 O{PWM}/M5", "Pin - M42 P{pin} S{PWM}"| Laser: Marlin M42 Pin|Marlin custom pin number for the laser/plasma cutter|**4**|| Laser: GRBL Mode|GRBL mode of the laser/plasma cutter|**M4 S{PWM}/M5 dynamic power**|"M4 S{PWM}/M5 dynamic power", "M3 S{PWM}/M5 static power"| +Laser: Coolant|Force a coolant to be used|**Off**|off, flood, mist, throughTool, air, airThroughTool, suction, floodMist, floodThroughTool| ## Group 7: Override Behaviour by External File Properties @@ -158,13 +165,15 @@ Extern: Probe File|File with custom Gcode for tool probe (in nc folder)|| ## Group 7: Coolant Control Pin Properties -Coolant has two channels, A and B. Each channel can be configured to be off or set to 1 of the 8 coolant modes that Fusion 360 allows on operation. If a tool's collant requirements match a channel's setting then that channel is enabled, Channel A has priority. Setting both channels' mode to off disables coolant but will produce a warning if a tool askes -for coolant. +Coolant has two channels, A and B. Each channel can be configured to be off or set to 1 of the 8 coolant modes that Fusion 360 allows on operation. If a tool's collant requirements match a channel's setting then that channel is enabled. A warning is generated if a tool askes for coolant and there is not a channel that matches. -If a channel becomes Enabled by matching the coolant requested by the tool then the channel is physically enabled by the post processor by including the text associated with the corresponding property [Coolant \ Enable]. Note, Marlin and Grbl values are included as options, you must select based on your actual configuration. The firmware selected in property [Job: CNC Firmware] will not override your selection. +If a channel matches the coolant requested the Channel becomes enabled. When a channel is enabled the post processor will include the text associated with the corresponding property [Coolant \ Enable]. Note, Marlin and Grbl values are included as options, you must select based on your actual configuration. The firmware selected in property [Job: CNC Firmware] will not override your selection. If a channel needs to be Disabled because it no longer matchs the coolant requested then the channel is physically disabled by the post processor by including the text associated with the corresponding property [Coolant \ Disable]. Note, Marlin and Grbl values are included as options, you must select based on your actual configuration. The firmware selected in the propery [Job: CNC Firmware] will not override your selection. +For coolant requests, like "Flood and Mist" or "Flood and Through Tool" you may want to enable one or +two channels dependent on if your hardware uses one connections to enable both or a seperate connection for each. Two channels may be enabled by placing the same coolant code in both. For example, setting both channels to "Flood and Mist" will result in enabling both channel A and channel B when the tool requests "Flood and Mist". Correspondingly channels A's enable value will be output (to enable flooding) and channel B's enable value will be output (to enable Mist). + |Title|Description|Default|Values| |---|---|---|---| Coolant: A Mode|Enable channel A when tool is set this coolant|**off**|off, flood, mist, throughTool, air, airThroughTool, suction, floodMist, floodThroughTool| @@ -183,13 +192,13 @@ Duet: Laser mode|GCode command to setup Duet3d laser mode|**M452 P2 I0 R255 F200 # Sample of issued code blocks -## Gcode of milling with manually control spindel +## Gcode of milling with manually control spindle ```G-code To be updated ``` -# Resorces +# Resources [Marlin G-codes](http://marlinfw.org/meta/gcode/) From fc5a7a750028d074e314b83b8d6c75664fdfb5d5 Mon Sep 17 00:00:00 2001 From: flyfisher604 Date: Sat, 13 Feb 2021 22:26:01 -0800 Subject: [PATCH 22/24] Fixes #7 --- MPCNC.zip | Bin 0 -> 14939 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 MPCNC.zip diff --git a/MPCNC.zip b/MPCNC.zip new file mode 100644 index 0000000000000000000000000000000000000000..90e9faae090ef6a777d038d87426058e17f0d841 GIT binary patch literal 14939 zcmV-hI;6!=O9KQH000080IRZ1Qnz=kz~?yt02~GZ00{s908LOsPD3tZaC7Wkd2{2o zlK+3I<~tzTt&Eh&5_R~JcaoCNIBShnw)1A}ysV0%Ac+}@)Z;NeCjRc*jf3C;N}}Vp z^<7fbM^Sifi-oBZK;WFqon=?C{N8^U&Et<1vI(=-lJKg4DX}Q*D z=>=ghTKb+vgTV8VYcM?ea70)Ei3`XS{$JRRW4kkAx)b7<0ri_p_*j_4ioy^I8p!@# z6aSsi!1C>7XnQVsPbwU9!1#U2Ctg~)Hw4{w=(yk%}Gboa-BH2!nXaTns z^^T$z_ETg#iflKdE9+|03hgTDJsq`Hl0C^3`w#2`d! z`k|--k$Ev$cp(fjc0epnUo4_M5w!w=3h^TAP z57A;weZZQUPLQ=?F!%0BASj8;Nd?4C212w&%c!RyrnVo1SquTOn}IlYEuW&&*!w65 zTRvu56o|72SWDA4L;BJ4C&5P;)UTJOMUzHCjnJj0=%C@;4B;P2?vWl(PlmfVu+V$odKZjB?ilE`<^ zOJ#94LcYtOwnr!6vA#u5fd!3}QyW106F?K?7|j%BCNU;~2?6C`{n52$Iti$p3nJP_ znEl0Yyn&Ew!Z8jZXdjNEFgDjSe5Ezd5T%Ldpad!ll7p!?ql%E7pB{ysc z!`{){bZ6864>!l)U-=rLI$p-eiN)v%&gMyV967L*Nfr3eQQ1E9G#5w5WMT)f=y|NA zD{GBD;k=7zexR~XYUDzt#*v+^BaPM`-L62pEs53{fzi8KI6%8AiPjw*+X33{?mDF4 z1imsapiOugpa#4Y`dsQtLz)bSHx$e;#$dL1=+}4!Z>R?f0ZBPMVM{J_JBX#3E8qlJ z8^CU2Ikl~RCt!F)W^`mlozczQwm!SCNQ5S6>}e!|=Ev?(lEtiSIRD98VEpLDb3WgK zVSJB(q0c&d%;3n1Yw8$gdjv%{raz-#m93Vpzmh!B5={Z^r?_{JoApgNQsmn_!OaFm z-tF-wVa8?6acVm_sjO&xhE4FGg&DUMLI1NLXRK9Fn>jTn)NhJ88TgTF!E*!59LxcKms*>5x6kOO{l7pg%4jlz;*=f z3$xWe;pi=ieprZ(I+TGv6wvKh@Jkm{1>H6o?vU&DwwUIioiUZi7Hv4yNO)ULTn^b$ zkeGalF%8i*Af%;*oKA}{yRik7n5~wQvy7OB9CBMhDlrk$P?~Qn=Ajrdjw2e1q%LnM zfZgtpVVj&A(sud|V=^?S^zleFil(VLm!qEPA;ds4B%yC|Al6S^5WNGQaY#gnX5v zD+V;fuUY=z8kktB6MK@!CMpB99uB)LJs9iI%0TgSwH}O@#c;pj2YwMvsY^ELn(~hN z9%1F^iWeT=0pQuCT+?34$1$o=O7f8+;7mMNK!;;Cv35Y-D^Q63WN8S|#sf?NDHa*7t%1UK(Y}$|$S${^7lV6x1;Ej?= zzm*NUbcQb#bE%@W0Vk=sSIci;|CC23o@;|cj}mV^XtCnbGKip)9t;Xf;IMrREf6co zM{G7Vs%w56{;@RI^1lQ!PpW1G#Ik)Wa!g-kbza|THF;Q_;3BdvaEA3CdGW7xY1)#) zie+z7TJ|U5I0PhkfXrZ0S;8Po8dQdkkuhhjZm?A*E} zxlWHhONo=2heHPpdpRx6SP9Rho1w_&085?R5oiR{h8bAo^40g`mG!{?HF^4s9;YmG z!f8Zu?NhoZz>hakJ(MAWWGiPzO|;@ zN@gAz>z`G}$Ti1)qq8d&!q39}t&Cm+b17#SXDz}ues~|0Q|!bIBA>F5X3KlF@Pb7( z%YfnLli1@;00^BruM;V{4L6-OXRRQqNPd#1R#%qi;szIEVOwc}g>RbRrq(}0i+Gby zCp{K{|ARF8W*9`!RJen}_T9j#U^WE{N=z1EN|7yp_`-3?Ex}9?9H6cNTY>=3XZnbH z^`sh5N+zBa)C%0rLZ;YBjNrEZCdGRwHtI z@|BwpKeZd28FjFaAaWaw6Xo=gbI#ljDD%C<(_r&GQKfG8HPlTi%Qje7srf0V;U|@c z$!zQt%Bk<~GM$~FlaFoLu97c5hrIp2l#gu!uafVM()Y7F?scIEJ4mHVp8j+6N$v0Jl^Le@_j9V`%k^>=1S_5?NQG;| z=(ICZCXW*6g~UV`65#oyv-Vy-InC(!qzF$ORBvfeljjbqAG}&g^R8PA<&Q4t<;Lnm zMv;>ki-!Dc!n=S>BOkmX2oncXN?Lj=n^@X18rvC(lgA~B1rD@R?X7781Q+{ty6 zv1j0??rcCtYPMs>dXg<7iSoWd{QyI)C#_kW1I#QLGMXh*8JYtKE7TG+ zuccM;Y(hDuva7nioJ#71!wP+nU?XKVJn>LYiR{?i%_)&SH=$RAQ#7yW(uaxvfJ>2G znI=itK?YE+K%qh%ic-isS@)8B#Tzn}QxnZU09tbWb@*}c+=SnED}0**pFY>~OmgcC z7(3)rux$&bj+SL;vwCpD{VQ-ki`oPaJeEv}JrK<~lU0`I=(by6b$JR2kDiFMH=EJD zit)P{2g)juJldkyf$aoqokkscc{N|jid*C-$rc=RV-MLTlSkKF*cOjV*@%gTPce29 zj4(|LGkl%mwoe@7(OXRv=WKS$GNtPL4)h!_6NrLjMtvhorH|btjg~4|7iTfC+!%~m zGuwjkb6pe_ps;%{S{!~OW^*LGWupbcf)Y51`!`y+M0p9+zU^z#;CVTeb>gK-N??m? zO zMEFi+9V&J!m2|{b66vtaDcnNwy=7_X3s2|1s_g27Z-MNr>B`DpeDe2Ig&(TZ!v)gw zrQ3_dUuw=3zmD|y*=))|hYeHtW1ty@1aXh_^`pDUsjBmzD)(py;#8G7r>gYWOY5N@ zy|P)czs9M*#;N~5my!bph z%W_@1@ro}VQ1dYvMY20|4M%$pt zjG_iJWOJ=Zgr%Fx$TpNw(Zxr$k&Iju74Qjb?~|%Gohn=JSF}-*z6w)3g1t0G4$GTc zxn$nraakFoZ|LJMkFAoiQ7ST0t(CcDRNP$UEy(PRFEpDIBN%rydn=S~8$MSPZ&H5!J|+QQSvqMyXOKG@7r zxQt|X`Ebd;#g+ce^lhAJRKGsgWrq~^D6426)3i^kXrI!w(?VLVtvH$lV}bOL*l24x zxq<33rfPD`IFgs#Qr56Dcvo~veH?I7;@fE>(Wt=7J%xIYfgU8}Sf9R{>-Z0)z?xDOo=&U;EjZF8v3)_zw& z{Q})eX_y@b(>Au+Ezw$i-y%V@#LJ{GY39uejkmB}ymN3g_x#BPb!Xumsu2gAst~l$ zK@0}iXkXMqo9bEUt}nx<(Ck&xYzfTE`c=kfQx}@0MkURJp*Y>JOcg`b?{jC z!2819e#k;qmeGmiXa0rd>IJRBN*{f^p~p@u1mY!i6Eb!@>ofRf>~Z%Enw$bNZg#b>U9Ehmknb}y$vQFpS;X#epZ%2i*@)PwJrL_5TKPMs*2^S}y{n&OLH-)G(iAc~*k-KJwcrN(c$>bdR26t^+u zV@uaCYH2~5&8^H2zvCcoT4W35*hkqN2_jy8d35>V`bH+HPft#c<(c1PsGIolzK)oB#9o$@hP6{P_3D zcmLU}<9VGcIy+$n)wraFMPD-SN=?2gm7iFQA=w3@rk#T8>EYtHs;1u7%dR*i5#>#b zHK3Wduyzt^J1}^gF1zd+qs9-{;eN@yv$d;$Pki6=lb~5MCiuJ0(plnZ58mLo!;TkP zpSwYWwf{k)_$O-5=Am#;plfaCOAk_Uur&REqYZi3J<4ccY$3kpIuVfSp3XrW4HusG znQiq_8#))CnDQ*w_>tIQK%FTb@O{Uc`dyv8lP&a)Jyw=|hj@rnEmSpOg#VHy%$E}- z-+v!>M;OqcLL-1Gta(*1u*7*x{#%2!M-9W?h&c%v!+7*r^ii@ggu>@j(2Lxg0dc*M zm@c8%ve>h_WG3FZq25Evgowrd=6y=;xI%67q3qCo6pJpsrzTp1*H+bmy$6vTr$+wx zgJ{Yd4j&-DdEc%jjKF#{@nVFk{H4L(kWeQTjq`w;W2c|Pm%aT9AcbfgS*O}JT(uuH z)k?L1*)=P*KOqI4Ym1x-zKIG()rowifI`&xEceV5fi^&67fTN(MNW}>_-pGojibIm z#iS1J(A-6C2OS!eR^AEyUs_dGwPN2%58jLhdWvhxzE?*9|D{IWzKKWjbgz}UBdOx< zp1ns|MQFnN@wL#Y{--BPQca_6lLJMnw@&=>6SNSkgG2$QHQ9~CTpZOBfU;}S$;oB` ziWChoH-jN`u?refzgqF+%Ncr@N#NikHtJMr;3$AQid>A)hg zNgB{0uEP_xA7r7Ro{~sPvV?i09T*&hTt?_@TO!;+nxLQs*_(G{<1xJ*{%W8VZ5Ky6 z|4GL?|0&^G__MKlDGB+wH4ZkHH1TU*XQ?Z~g52qM&GlxwDl(NOYbVy~y{C5Z{t;{csD*0U(T|7Ob zXi6xvfhs@z@B{hSzxr_g;fxC{X3EJIjwTlR4Yse1(|w-I;;Y?_CaCy(oXEgfV2Mar z|3|(X@GS$I-=Fd$hq9NAz`s-=t59S95z3^Q-mH|_>BU{F&_-{RlQe47&?-TwShoZ4{#SdJxK6jh zw)@U;>dYHMq^G@#J=uNORg+I_0Vub}*;35wxb}#vJaSK-W^Bag4X3SP2)^1YdbOu2 zpH1eeMcFl(%ZG`H+F%WO8==myv#yx&mZbspEvaP5lLHDzmwS8AclAS~26%4oShJmV z7-=Wf?()%EkQk8yjRh(U`28uvUZ;RSxr(lFC4=QajER(W41|+zL*yfarN_Nzt`xX8 zsXB!E6MRyE9V7%wmhNcaC{Q8eB)G6 z+;rn2_mM_Cf40QakFye0RmLWSbvH(RFkV@u_0-Iu6^pF7&LjI=2`6|F{1L)0AEK1Y zS+AdQPLiU{DsPqWyVJ2bVcv_sx7lToKl7P*D*B|V7m4C zwLw+y4s(dvsfqmi#LbN#EXz(gwa{)cRs7?cl&F`NRv$&9!gWbJBV;);FRP;Rxxf@R zA8cF+>|A1BZB^pvt1akmvOuP+)J9clF12=fQ|S7-_Jz}@oVM3xV(v@#HMu z8mkCV0eXv+!n#m9MjFHm8V)mja!RD~wMkix`!|Y9sxFA5ac$*)R(!eJkH^=;_m~sg zfD8^{J*Qx&q!RS6=5Z~9WXu0N*uF3Ok{#t3a6=n>D~bM)s=)!sl*%XQyI>s%bu60IWTRY##SIo3{=ziDTlbI%P+c!ecZthIpnb*x1=E-q^uYr%%IK`rVR3GAJpwN4I> zn%N})FjBVddIe@_mWo`%!BC$0TaQs34v;OS{K^?8mR5M5bq`GwP<+ukF--xKS5DcU z9aN6;koFPF`*3`Bz@Q_oUGfI-4jax-N!6J6PXYSIM7b%EF7dx@L)>S~5b z;S&Ta*DW{UrwD`&reHK04R7(13gsK4QBhw};R8|GptJ;F2xv=a6W!IqpNx;RtOp%5 za7?2F_8oZ1!dE9^xG?3M$sQ~q$-Lp({fI8pn61gTQ8-2mMnB|Ap!T#L45!R80VxR? z@lK*1;4s9v?q$t@6@64h_s|)EqaZO?PjkgiyoXevN;qG2T!m;E8B^|4=4d_Gn}Iwg zcT=)U8YY?#(Z)%Ndw`@`9Ay>)HZ&%o@=LG!m_?M%W{MQlMLoIG^E{PM&s}yxQg$_16UKK;40PGNixCULB9aj;Qs2b^jB?jEyy$& zx43j$!0S!ZV!rQ15L^Vu6k`o1coU?o+ejJJ^URgxkl5MAfUlZhw~Eh?IcNxZiI#vD z2sV89aK8cv_6Nu?@x5Z?1pFoBK&>=ts+TE_ut$H`e zHY{4YguNp08`{xaXKv7L&o<;(YTRocLG-%F{$v-6h^uzcDlkm>-aAudx-Rh=L3y_L z0c_~91!6F~rtr#?!RxIJhV_0L#&?N5CB4lDey~sIm;xerpZm;LG58SM)@9rJj2tA+ zqyy6oxs0Ya_>CKu*^8abjov1T^-K)p!?v&=B}qJ`delUd#X#NER8nksHl*ZBOfBo> zl~sk1@xk))cmmkwc%VRiqs%%Ls-7mAtkISXULRn5aigvuly0V!Z@!gM1mc+LSHyv+uuRsd5mMpWV2mfjJbHg?b{ymAhX?~=VUs%D$sT&fZ^Ie3 z`Enj=I#=P!mrX&mZXlU#z=Q?#?2ltMMKJ_51$p=h3cd{pFzp?m9yEKMx9!t+hi@(W zOOXxPJt^ig>F;D;XC%WnE1E?=dtYGvF}O54`)|=wzdSCQ0>2cICfofhBJ$V9*=f7g zwcTM|aHi9lsCz@> zyQ2PwvWs6573%7dm&FpL-WYs9PewjumD>xw8wPB0OUpq-Jbkw7bDK11#<>#hE?Fwf865W_&QHwhHoM*YswL+%R$M|27?WNJ~ z*v6N+hM^OC%gD9UGJ6Cb(qRob+CRV+Qd+Ht7Q9-KAQza=jEP%eM&m(|O$2r>Y8Ihv z7md-VHg}(2c5HO*LyJFNF-Y4sJ^A7mwtwM!mA!?)wE2!@Cz=34AZ(m70=|L26ZQ_? z4cd)^*1K~Ui{rEA$$10uM@!v~hfV%lWz{_3)7(RAbiCTSUUzxd>dMwG-(YCqSe>Jt zyQFV6oajeuWSz;ZWvy%VXrTlcs366*#dRg7Q6He9%i#4Cwzy)20d115vJq!ZY)i(x zMJ~uvKXAal$ZuZ$uo0ZWPB|WjqaYfvMMgHq;wFPfDLfC^JqSc93M$TRVh&PW4Raw3 zgo&8*kT;~}^{Tkwh%@|9?NDi~MnEyP!T+EB4)pdzbcYmxcy@!M=m_Xx%ZYD2M8q

YX9sVyJTuvRg_c#JrIMvqP*KH+h)w;Oyd&$2bxJ9YrdS43vRD)$x}bOI zVML;o(-u7O*MiK)=W||36a3c)wH|!bgRgqTxvKCMzHCwtsKMF zdia7%UdO5gP=+P#P&BA>b^#wTo*$){Ia=-CfuE)gs`YW(azDgcg?&J^52*G5)gtY? z1fDc;N*AVQrOTcXJD*U=x74@6^usZdigO)s`h+(2^+9BQr&Dnl^feI~-3(;8AY8}b zz_hEzk=!N+HIF)AaXF}UPUzV;$|uwS+VJRo&Y$1@x)xEs^~KB={xx34iMFU#30T)zuPY`kE|b z!&}-U;58L2V3bnOh^HI@6g0+#hPRU%WgJ}7$7@!HhKuW8?qc-bwQIjxUBjG~ywi7I zDgPX#*Q?~oD(d6BS|8q+(;kP<7ZW`kYiyRe=UPwH{%p@SbC%|m`4kRJ3=uN;{!A>R za@&g6VDkEG8V~OJsot?Fo9V=a_GI2#fF^ozHCu5RJx|IQjh%|ESIADCp!J9i)qJi; z1>4 z7zuM=cp=R)G(5Y~F85@2l$(+{r0ono;VmPqxqpJ)0{s2$h3@8Rdc+g-#MF&uM>L)f zli%2;ZZ3Ds6IlZ&Y3M+-o0^6^pkkgmKK*O+xOvj)wHs%xEEf*#O;+5OD?9quw!*kj zj+%{wUhAX`j=Zh{Y5!fPV_T;@Nbq8x6Py0#e5RZTFv%;v$x-B@4q{0 zv|UOvAeFm3YoESp9W^U;Ds2n;)HhXo?Y0hk-Ns?1UV)L#LP7;d)lSQ&((zdp7-vWC zP7W(E%EgtxtJFigdC+bh9hG6K@2kLSUUZr#2hCCiqVKD~f^OgKmxGemRUo}>9lq^3 zIleqtra={GZ(1j<^S6r>liR8Y?&s{Z$5sxLd^S6vAk1^BTaf8(`{TtoCBuPZO;t-c z7e1z9>CgoSlGq`#)PUdDdWqE<58!&nvyNFsaGzls80&#^?sDG1_TSDTDX&h)bGjCW z`UfffG=B~%rrha3IqNUT_BXWxiadU~IP-0|jdzi;9IqDo{O|k&l{K`qAEi%NL|PdL zrk!xp8zBd{$aLY2hmq(EGnWR?J?2CHq_=-`y8rtht@9@6pxnFDcPAZCP})St#jzsz z2>EccX@*|U{%*&TokgQz1-%*3sDz0}#n(c}3VW@Jk>wivbSyTWz>Dn8%jtJ+w|Jz+ z3jy>1BF9llIj#|abOQYlvF}rYH|KZ+MMIEX9ekCH>i5xipCSizI2fQM+&a9bF`L?Q zHM0}Fz(&iKc9>lrB=z7VPB9{Yy;tZ{r!O%MlFvw(xKy#?4uNPG}=i7_Fcz3e=H+$`7<98tEq|-hR<2FfU1YK=Va81gYnZ|a_-t12?6Kh4b?%wl7h#L*6k<4Zy!H3PQU5L+ zrR=P!UdU5%r|eJTB%!!|Ifm0EBko#|!|Vx)=DdG?-q9BoJd{nVd0xucYHHv!M<2F> zeiZad+%C1T1T#{!=a2RZ^zgpkgz^WE@?@So{WA`q5W+a_`7EiCu-7opWo_J4H;4!;8 z*-~h$4FCL`1F#c(|NYPz0X0PtWNB6#+We;lXjdC%zPDDBM-qCsk?R<3HGU{ zdh{@X-tp2FNp!o+pD4-!0o(ZF?AyGwSzbY?^O)Zq&bzd5lh0VqZzO7wKyFw1A_y+9 zl;C)`&=X&WwN5h-ZI&=Zi<*WH-1L0-7%gtAMWD2oYDix$MtW8q>DdxU&s?NuOCa4{ zjPzr5q#u_+`q4%D(I8zQl^xo9e@&^hAgWNR$`fUaE$F@IFrC*)-O|Ja1~w43eV|Ak zmwo7}Wk>CrPe|z+#Vna|%>@7qVn?0YT|Qf?fQRIucs!`xV94haZn@u{)3hH?$C1=X z%CJKAh|@e)a%+s=k0NFZI?(tpeg;uWZ|Y|)cQdMFeUEf?8fQ($!>SGEV3GkOv@P0SZ#_`kWDfjZ z4_ZNsComqtcjrUjx1le^c?6Er3@?+*;UBoza}Ncx=5X`HFNYfdbTauS^Q9Di)tLfc zZd)FP=(iWBAD2gUiPPf}{b2B-)kRX+ho7doI(W{|EpGA%ctP=+U|WM`qxD(HwX2Di@u3o9Fps1YOUcM*ne@!PG1tZ zOr~p1F>!HOrV-dM9Upe2hlTA?5+UiEruODDB(zFx?P_i%W6j z6<$;7beQdGgp_Sx?}2H@*E4uM^Ip&Fnel-3qM0+gU*s}d&1sfm-ZIZwwM2o6m~xZ= za(Rn8j&D0LmU(sa9QpgMYzs_MCcc4o-CF^R*-6<0_xhWN zSGQccy5Cr~y0zY;C037Ulkw!{(UzOX|6d~G?WUKKn8zoG3+6Ro+dgawMNnw7Tzi;d zf*4@G6tizt9^otb)K-WccPYld%&8Z(n>b*zy z-5H8EUtiR5Qr1i#-07-jY6se2+{cNb4KoBKu{6V*Opw2gHTXY;Js4uZGxR`46chp! z=|RnaG(R+*<-Mi_lH5x9gh3YSZ}?as=ug=Fw+0{7!z<;|jyOQuDLo=kK7Gn0{;)P% zdz7Oo^g!8aFnYtBy$>aE8VVmbyVk5W+)m4O9O2*vX6H~cc?yqPq-CmopFdCup3Fbc zccdz5>zCM(ZDCLl+g22grjcB^%_)qxX0(!H14g=$SGQcZI0t>rVO5m1gRAvSD2Llv zfU|D*b7xU(otYq1xkb`-=f6QG^LRSo3;Vt^55sFHBog#>VjpI8_dq2Qw76Nri8ikCN zhR?~+sPv&WE4}m5SP=ou#Q$IVxvSuA#TkJ6+6gc6Nr~{-c zR1P(X>jX7%gC$$F+Q?NTQI%M`SAqj2z%m--BP%gw4J`;5Q-C^w0tQ3koAl;z&no4E zx<}sa+C_yavoOeGG!+d}Qx5(t48%my`fOXC?WiAysL~9=jx1$@&Kt5B(KxYUxy}@Z zc#h!A8;Zs^xj03mVeKA+hG49(ZZW=WGMd$7oY&2pESk>;_W z0B5TnpWL+)@6pYweHA8=Q4XR|@X+q5>Fw-`-5~j2IITYXV+#&NGy31he{5+4u;L)n z;7wvOY}4l!)1F(L0ALpN&n=SdH;>kv$JJFsCo>{X<4ji;G(R(aH05b!MVc7`uP+rB zh(e1Pfq=d%NYx4JWL(Vl=!>@GfCi-#loAm45g91L)KtQ;QY2EOxCI`?3}_=2 za4qws!26}xPo_wp7}*j3Gu-D5f*KGh>U*_Lg=^r8nEW!LfESR8=%F9sAq_K=>B0{pjG^TM7aD19E_?psQUS{TrGYNkqxi;C zMeYTT-ZT)M@6Ur^g^&GzlFjtMGZJJ$Ss zqU~Y95wrA&X7``jF7SW;J*Ux13j6-(o=8; zw{<`hnu1}j4U=>oPWmt(Lf%rN<(1Mdq?HV0)cq|p*Mm4eZbv1d#m&T7b--ogK25prfb2tH1v(fZu_|c^N)|Y#*jjY2;0sB!*djhN7^gV@|%6%3-tc&x!=DN&M0Z@m9{h+NO zjX8l}aC(L7Yn_jJHK%LS47*zZsZO;Sr+0J$+%2XLpgdo9*dTW_Og89`7KfPssuQjVe>aD7a>B?~2zoDqQ+uN1Zs_+h^1Rm&L z*!4^)RROG9js|satTuZpbFulT0SPtdEM*?;|`A3h%s3OfV^@}{!WC%K1-UxYk z<8?@c$t-#4%;)jlpoG8lus8-GpS#WuWhmU+7>yNWS>?V!U-<=$HmXj3H(}my@f9NE z)e^{}7Ar&zegP@-_XL>RM8X8c1BRR<@HdxuHzKk?eR|C5*OEw#$3GpXPK4L28+DZraP^Tx=#tLuy+h@ls z(2sPnQWn1V#PmL2AVA+hgbX#s8!wakwsayorMs4&aMen7eP!{Ur?ocnixEGZ~V)PLDalmrGj4So$}(fXAyI3~yuFPYes#-ibz-G#*9MaNIWo zo3E%$u|l-AlUsbwu(gw!7N0U4*kG8vxf_izYaM#qJ35tLzl}!2e&~lTE+9pJoFGR0 z`JDZ#(dS5*aGQ=11wB#tSN>tjS9v$;T-?qHJF(OGj331^z&JTKl%K~4(;8GL=_~30s|u%V2`+=hk!g1oL(T z3sClU0%jjjQ7M%xBwLK0E-nkF%0fw5EC{{`6b=7eE|zHa{}2{dn{oeDjF$Q39u4%& zhG&#9_beeqGH7u?T;xG@rVU?2zCB)1GHoey#T`IVRf3Dns#K z!K|>%EmInkOKA4BXJyu;^7H(XG8S(3E`Y{rZMS-tmD^^H=q2>%3-ks+qe*;ytws~N zSa;GhRVv!MxWX>BDmdL&GaCV-dr>seKbN#3y(+RIZP`|&&kj%Y>Z7Zd9~t(A{C?Gw zFS_U4-oo5ir@Dc>WIxXVe}R6t;V`9ZVdU7eXK1zRWCE7AfzC1G;F;mO?stnWa16yn zZ6o>UNHhw-J>qniu={Wt-@(#2>JKnUSgN9)nceVP(x=wNNm2B7j<762nn9+0HwL!T zr3`x)6tbS)Q{gr<21PeFU+I!&lBJk3DsOpn>tgftAC2}2X1v63o(V_k1jF0Oh`jp5 z*&gBMb5SpKwd;chT{>TlrEKW#*lTMk#Dy+Gw;iR^u+LYrG|2#S zD++gkB8MJ*^Yfw(?U89m9K_&_j5mK}{JPu#py)4--T^V2M%MuMCQT>X>+8349J;=* z$J6)ggSelp({x=w+<5t8{U*H~l}}tU=)R3_VV&|AS-6aE{is?^7_pp(8K8rk?dv5a zhi%OB;sCU^0?@axz3btjy{abndTLH@ Date: Mon, 15 Feb 2021 11:12:03 -0800 Subject: [PATCH 23/24] Fixes #8 --- MPCNC.cps | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MPCNC.cps b/MPCNC.cps index 6c364c9..89b9de3 100644 --- a/MPCNC.cps +++ b/MPCNC.cps @@ -643,7 +643,7 @@ function isSafeToRapid(x, y, z) { let zConstant = (z == cur.z); let zUp = (z > cur.z); let xyConstant = ((x == cur.x) && (y == cur.y)); - let curZSafe = (cur.z >= properties.mapF_SafeZ); + let curZSafe = (cur.z >= safeZHeight); // Restore Rapids only when the target Z is safe and // Case 1: Z is not changing, but XY are From 45fe8c92eb7bd054de8b14bf2ac300d51eccd773 Mon Sep 17 00:00:00 2001 From: flyfisher604 Date: Mon, 15 Feb 2021 13:25:24 -0800 Subject: [PATCH 24/24] Fixes #9 --- MPCNC.cps | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/MPCNC.cps b/MPCNC.cps index 89b9de3..2c898fb 100644 --- a/MPCNC.cps +++ b/MPCNC.cps @@ -631,11 +631,21 @@ function safeZforSection(_section) } +Number.prototype.round = function(places) { + return +(Math.round(this + "e+" + places) + "e-" + places); +} + // Returns true if the rules to convert G1s to G0s are satisfied function isSafeToRapid(x, y, z) { if (properties.mapE_RestoreRapids) { - //let zSafe = (z >= properties.mapF_SafeZ); - let zSafe = (z >= safeZHeight); + + // Calculat a z to 3 decimal places for zSafe comparison, every where else use z to avoid mixing rounded with unrounded + var z_round = z.round(3); + writeComment(eComment.Debug, "isSafeToRapid z: " + z + " z_round: " + z_round); + + let zSafe = (z_round >= safeZHeight); + + writeComment(eComment.Debug, "isSafeToRapid zSafe: " + zSafe + " z_round: " + z_round + " safeZHeight: " + safeZHeight); // Destination z must be in safe zone. if (zSafe) { @@ -644,6 +654,7 @@ function isSafeToRapid(x, y, z) { let zUp = (z > cur.z); let xyConstant = ((x == cur.x) && (y == cur.y)); let curZSafe = (cur.z >= safeZHeight); + writeComment(eComment.Debug, "isSafeToRapid curZSafe: " + curZSafe + " cur.z: " + cur.z); // Restore Rapids only when the target Z is safe and // Case 1: Z is not changing, but XY are