Tony Willis

Bones Forge Logo

Azure Cloud | Infrastructure Automation & Optimization

Python Based G-Code Creator

I have begun to learn Python and have started developing a simple G-Code creator for CNC machining.

These are based on simple G-Code programs that I have typed out many many times over the years, hopefully I can buld this into something that will help others who are starting out learning CNC.

Currently, I have implemented three basic shapes: rectangles, interpolated circles, and hexagons. Each shape has its own section where you can input the necessary parameters such as dimensions and tool information. The generated G-Code can be copied to the clipboard for easy use in CNC machines.

The Rectangle I feel is fairly self explanatory, and produces a program very similar to the built-in software of an XYZ milling machine.

The Interpolation program, is something that I have used for many years on Haas machines. It is good for milling holes of multiple sizes with one size tool. It is also the same code I use for thread milling. Just substitute the cut size for the thread pitch, hole size is the thread OD.

I added a hexagon generator, because this is something I have occasionally needed, and it's not always been easily accessible in my brain. At some point I'll add other regular polygons and bolt hole positioning.

I plan to add more shapes and features as time goes on. Also as I learn more Python I'll add any other projects I come up with.

It's also possible that I will be creating an Android app to host these codes.

Rectangle G-code Generator

Rectangle Diagram

Enter your parameters below to generate G-code for a simple rectangle.

import js from pyscript import display def generate_rectangle_gcode(event): try: # Get values from HTML input elements tool_no = js.document.getElementById("rect-tool-no").value tool_dia = float(js.document.getElementById("rect-tool-dia").value) tool_rad = tool_dia / 2 wrk_ofset = js.document.getElementById("rect-work-offset").value spdle_rpm = js.document.getElementById("rect-spindle-rpm").value x_pos = float(js.document.getElementById("rect-x-position").value) y_pos = float(js.document.getElementById("rect-y-position").value) z_rapid = float(js.document.getElementById("rect-z-rapid").value) z_start = float(js.document.getElementById("rect-z-start").value) z_cut = float(js.document.getElementById("rect-z-cut").value) nosteps = int(js.document.getElementById("rect-nosteps").value) x_dist = float(js.document.getElementById("rect-x-distance").value) x_cut = x_dist / 2 y_dist = float(js.document.getElementById("rect-y-distance").value) y_cut = y_dist / 2 con_rad = float(js.document.getElementById("rect-corner-radius").value) lead_in = float(js.document.getElementById("rect-lead-in").value) feedrate = float(js.document.getElementById("rect-feed-rate").value) # --- G-code generation logic based on provided Python script --- gcode_lines = [] gcode_lines.append("Welcome to Tonys Basic Rectangle G-Code Creator") gcode_lines.append("Generating G-code...") gcode_lines.append("%") # Start of program gcode_lines.append("M97 P8000") gcode_lines.append("M05") gcode_lines.append(f"T{tool_no} M06") gcode_lines.append(f"M03 P{spdle_rpm}") gcode_lines.append(f"G{wrk_ofset}") gcode_lines.append("G40") gcode_lines.append("G98 G17") gcode_lines.append(f"G00 X{x_pos - lead_in:.2f} Y{y_cut + tool_rad + lead_in:.2f}") gcode_lines.append(f"G{wrk_ofset} G00 Z{z_rapid} G43 H{tool_no} M08") gcode_lines.append(f"G01 Z{z_start} F{feedrate/2:.2f}") gcode_lines.append(f"M97 P301 L{nosteps}") gcode_lines.append(f"G01 Z{z_start} F{feedrate/2:.2f}") gcode_lines.append(f"G00 Z{z_rapid} M09") gcode_lines.append("M05") gcode_lines.append("M97 P8000") gcode_lines.append("M30") gcode_lines.append("\nN301") gcode_lines.append(f"G91 G01 Z-{z_cut:.2f} F{feedrate/2:.2f}") gcode_lines.append(f"G90 G03 X{x_pos:.2f} Y{y_cut + tool_rad:.2f} R{lead_in:.2f} F{feedrate:.2f}") gcode_lines.append(f"G01 X{x_cut - con_rad:.2f}") gcode_lines.append(f"G02 X{x_cut + tool_rad:.2f} Y{y_cut - con_rad:.2f} R{tool_rad + con_rad:.2f}") gcode_lines.append(f"G01 Y-{y_cut - con_rad:.2f}") gcode_lines.append(f"G02 X{x_cut - con_rad:.2f} Y-{y_cut + tool_rad:.2f} R{tool_rad + con_rad:.2f}") gcode_lines.append(f"G01 X-{x_cut - con_rad:.2f}") gcode_lines.append(f"G02 X-{x_cut + tool_rad:.2f} Y-{y_cut - con_rad:.2f} R{tool_rad + con_rad:.2f}") gcode_lines.append(f"G01 Y{y_cut - con_rad:.2f}") gcode_lines.append(f"G02 X-{x_cut - con_rad:.2f} Y{y_cut + tool_rad:.2f} R{tool_rad + con_rad:.2f}") gcode_lines.append(f"G01 X{x_pos:.2f}") gcode_lines.append(f"G03 X{x_pos + lead_in:.2f} Y{y_cut + tool_rad + lead_in:.2f} R{lead_in:.2f}") gcode_lines.append(f"G01 X{x_pos - lead_in:.2f}") gcode_lines.append("M99") gcode_lines.append("\nN8000") gcode_lines.append("G00 G90 M09") gcode_lines.append("G53 G00 G40 Z0") gcode_lines.append("G53 G00 G40 X0 Y0") gcode_lines.append("M01") gcode_lines.append("M99") gcode_lines.append("%") # End of program # Display the generated G-code output_element = js.document.querySelector("#rect-gcode-output pre code") output_element.innerText = "\n".join(gcode_lines) except Exception as e: output_element = js.document.querySelector("#rect-gcode-output pre code") output_element.innerText = f"Error generating G-code: {str(e)}\nPlease check your input values." # This part is crucial for PyScript to call the Python function when the button is clicked. # The 'py-click' attribute on the button handles this automatically. # We just need to ensure the function is defined and accessible. # The function `generate_rectangle_gcode` is defined above. # We can add a placeholder `pass` here if needed, but it's not strictly necessary # as the function definition itself is what PyScript looks for. pass















Generated G-code:

Rectangle G-code Generator (G41 Offset)

This code is similar to the Rectangle code above, but uses G41 to offset the tool according to the tool table.

Rectangle Diagram

This program will create G-code for a simple rectangle, utilising G41 to offset the tool, based on the parameters you input. Please follow the prompts to input the necessary parameters.

import js from pyscript import display def generate_rectangle_g41_gcode(event): try: tool_no = js.document.getElementById("r41-tool-no").value tool_dia = float(js.document.getElementById("r41-tool-dia").value) tool_rad = tool_dia / 2.0 wrk_ofset = js.document.getElementById("r41-work-offset").value spdle_rpm = js.document.getElementById("r41-spindle-rpm").value x_pos = float(js.document.getElementById("r41-x-position").value) y_pos = float(js.document.getElementById("r41-y-position").value) z_rapid = float(js.document.getElementById("r41-z-rapid").value) z_start = float(js.document.getElementById("r41-z-start").value) z_cut = float(js.document.getElementById("r41-z-cut").value) nosteps = int(js.document.getElementById("r41-nosteps").value) x_dist = float(js.document.getElementById("r41-x-distance").value) x_cutl = x_dist / 2.0 y_dist = float(js.document.getElementById("r41-y-distance").value) y_cutl = y_dist / 2.0 con_rad = float(js.document.getElementById("r41-corner-radius").value) lead_in = float(js.document.getElementById("r41-lead-in-radius").value) feedrate = float(js.document.getElementById("r41-feed-rate").value) gcode_lines = [] gcode_lines.append("Welcome to Tonys Basic Rectangle with a G41 offset G-Code Creator") gcode_lines.append("Generating G-code...") gcode_lines.append("\n%") # Start of program gcode_lines.append("M97 P8000") gcode_lines.append("M05") gcode_lines.append(f"T{tool_no} M06 ({tool_dia}mm Cutter)") gcode_lines.append(f"M03 P{spdle_rpm}") gcode_lines.append(f"G{wrk_ofset}") gcode_lines.append("G40") gcode_lines.append("G98 G17") gcode_lines.append(f"G00 X{x_pos:.2f} Y{y_cutl + lead_in:.2f}") gcode_lines.append(f"G{wrk_ofset} G00 Z{z_rapid} G43 H{tool_no} M08") gcode_lines.append(f"G01 Z{z_start:.2f} F{feedrate/2:.2f}") gcode_lines.append(f"M97 P201 L{nosteps}") gcode_lines.append(f"G01 Z{z_start:.2f} F{feedrate/2:.2f}") gcode_lines.append(f"G00 Z{z_rapid} M09") gcode_lines.append("M05") gcode_lines.append("M97 P8000") gcode_lines.append("M30") gcode_lines.append("\nN201") gcode_lines.append(f"G91 G01 Z-{z_cut:.2f} F{feedrate/2:.2f}") gcode_lines.append("G90") gcode_lines.append(f"G01 G41 D{tool_no} X{x_pos - lead_in:.2f} F{feedrate:.2f}") gcode_lines.append(f"G03 X{x_pos:.2f} Y{y_cutl:.2f} R{lead_in:.2f}") gcode_lines.append(f"G01 X{x_cutl - con_rad:.2f} Y{y_cutl:.2f}") gcode_lines.append(f"G02 X{x_cutl:.2f} Y{y_cutl - con_rad:.2f} R{con_rad:.2f}") gcode_lines.append(f"G01 X{x_cutl:.2f} Y-{y_cutl - con_rad:.2f}") gcode_lines.append(f"G02 X{x_cutl - con_rad:.2f} Y-{y_cutl:.2f} R{con_rad:.2f}") gcode_lines.append(f"G01 X-{x_cutl - con_rad:.2f} Y-{y_cutl:.2f}") gcode_lines.append(f"G02 X-{x_cutl:.2f} Y-{y_cutl - con_rad:.2f} R{con_rad:.2f}") gcode_lines.append(f"G01 Y{y_cutl - con_rad:.2f}") gcode_lines.append(f"G02 X-{x_cutl - con_rad:.2f} Y{y_cutl:.2f} R{con_rad:.2f}") gcode_lines.append(f"G01 X{x_pos:.2f} Y{y_cutl:.2f}") gcode_lines.append(f"G03 X{x_pos + lead_in:.2f} Y{y_cutl + lead_in:.2f} R{lead_in:.2f}") gcode_lines.append(f"G01 G40 X{x_pos:.2f}") gcode_lines.append("M99") gcode_lines.append("\nN8000") gcode_lines.append("G00 G90 M09") gcode_lines.append("G53 G00 G40 Z0") gcode_lines.append("G53 G00 G40 X0 Y0") gcode_lines.append("M01") # gcode_lines.append("M99") gcode_lines.append("%") output_element = js.document.querySelector("#r41-gcode-output pre code") output_element.innerText = "\n".join(gcode_lines) except Exception as e: output_element = js.document.querySelector("#r41-gcode-output pre code") output_element.innerText = f"Error generating G-code: {str(e)}\nPlease check your input values." # Placeholder for the function definition itself, as py-click handles the event. pass















Generated G-code:

Interpolation G-code Generator

Interpolation Diagram

Enter your parameters below to generate G-code for hole interpolation or thread milling.

import js from pyscript import display def generate_interpolation_gcode(event): try: # Get values from HTML input elements tool_no = js.document.getElementById("int-tool-no").value tool_dia = float(js.document.getElementById("int-tool-dia").value) tool_rad = tool_dia / 2 wrk_ofset = js.document.getElementById("int-work-offset").value spdle_rpm = js.document.getElementById("int-spindle-rpm").value x_pos = float(js.document.getElementById("int-x-position").value) y_pos = float(js.document.getElementById("int-y-position").value) z_rapid = float(js.document.getElementById("int-z-rapid").value) z_start = float(js.document.getElementById("int-z-start").value) z_cut = float(js.document.getElementById("int-z-cut").value) nosteps = int(js.document.getElementById("int-nosteps").value) diam = float(js.document.getElementById("int-diameter").value) rad = diam / 2 feedrate = float(js.document.getElementById("int-feed-rate").value) # --- G-code generation logic based on provided Python script --- gcode_lines = [] gcode_lines.append("Welcome to Tonys Basic Interpolation G-Code Creator") gcode_lines.append("Generating G-code...") gcode_lines.append("%") # Start of program gcode_lines.append("M97 P8000") gcode_lines.append("M05") gcode_lines.append(f"T{tool_no} M06") gcode_lines.append(f"M03 P{spdle_rpm}") gcode_lines.append(f"G{wrk_ofset}") gcode_lines.append("G40") gcode_lines.append("G98 G17") gcode_lines.append(f"G00 X{x_pos:.2f} Y{y_pos:.2f} (All XY movements in sub-program are)") gcode_lines.append(f"G{wrk_ofset} G00 Z{z_rapid} G43 H{tool_no} M08") gcode_lines.append(f"G01 Z{z_start} F{feedrate/2:.2f}") gcode_lines.append("M97 P401") gcode_lines.append("(For multiple holes add more XY positions and re-run Sub-program)") gcode_lines.append(f"G00 Z{z_rapid + 20} M09") gcode_lines.append("M05") gcode_lines.append("M97 P8000") gcode_lines.append("M30") gcode_lines.append("\nN401") gcode_lines.append(f"G90 G01 Z{z_start} F{feedrate/2:.2f}") gcode_lines.append(f"G91 G01 X{rad - tool_rad:.2f} F{feedrate/2:.2f}") gcode_lines.append(f"G91 G02 Z-{z_cut:.2f} I-{rad - tool_rad:.2f} F{feedrate:.2f} L{nosteps}") gcode_lines.append(f"(For a bottom finish hole, use this line -- G02 I-{rad - tool_rad:.2f})") gcode_lines.append(f"G91 G01 X-{rad - tool_rad:.2f} F{feedrate/2:.2f}") gcode_lines.append(f"G90 G01 Z{z_start}") gcode_lines.append(f"G00 Z{z_rapid}") gcode_lines.append("M99") gcode_lines.append("\nN8000") gcode_lines.append("G00 G90 M09") gcode_lines.append("G53 G00 G40 Z0") gcode_lines.append("G53 G00 G40 X0 Y0") gcode_lines.append("M01") gcode_lines.append("M99") gcode_lines.append("%") # End of program # Display the generated G-code output_element = js.document.querySelector("#int-gcode-output pre code") output_element.innerText = "\n".join(gcode_lines) except Exception as e: output_element = js.document.querySelector("#int-gcode-output pre code") output_element.innerText = f"Error generating G-code: {str(e)}\nPlease check your input values." # Placeholder for the function definition itself, as py-click handles the event. pass












Generated G-code:

Hexagon G-code Generator

Hexagon Diagram

Enter your parameters below to generate G-code for milling a hexagonal profile.

import js from pyscript import display def generate_hexagon_gcode(event): try: # Get values from HTML input elements tool_no = js.document.getElementById("hex-tool-no").value tool_dia = float(js.document.getElementById("hex-tool-dia").value) tool_rad = tool_dia / 2 wrk_ofset = js.document.getElementById("hex-work-offset").value spdle_rpm = js.document.getElementById("hex-spindle-rpm").value x_pos = float(js.document.getElementById("hex-x-position").value) y_pos = float(js.document.getElementById("hex-y-position").value) z_rapid = float(js.document.getElementById("hex-z-rapid").value) z_start = float(js.document.getElementById("hex-z-start").value) z_cut = float(js.document.getElementById("hex-z-cut").value) nosteps = int(js.document.getElementById("hex-nosteps").value) diam = float(js.document.getElementById("hex-diameter").value) rad = diam / 2 diam_t = diam + tool_dia rad_t = diam_t / 2 point_dt = diam_t / 0.86602540378 point_dth = point_dt / 2 point_dtq = point_dt / 4 lead_in = float(js.document.getElementById("hex-lead-in").value) feedrate = float(js.document.getElementById("hex-feed-rate").value) # Pre-calculated positions for G-code generation pxdthr = float(f"{x_pos + point_dth:.2f}") nxdthr = float(f"{x_pos - point_dth:.2f}") pxdtqr = float(f"{x_pos + point_dtq:.2f}") nxdtqr = float(f"{x_pos - point_dtq:.2f}") pyrtr = float(f"{y_pos + rad_t:.2f}") nyrtr = float(f"{y_pos - rad_t:.2f}") # --- G-code generation logic based on provided Python script --- gcode_lines = [] gcode_lines.append("Welcome to Tonys Basic external Hexagonal Milling G-Code Creator") gcode_lines.append("Generating G-code...") gcode_lines.append("%") # Start of program gcode_lines.append("M97 P8000") gcode_lines.append("M05") gcode_lines.append(f"T{tool_no} M06") gcode_lines.append(f"M03 P{spdle_rpm}") gcode_lines.append(f"G{wrk_ofset}") gcode_lines.append("G40") gcode_lines.append("G98 G17") gcode_lines.append(f"G00 X{point_dth + lead_in:.2f} Y{y_pos + lead_in:.2f}") gcode_lines.append(f"G{wrk_ofset} G00 Z{z_rapid} G43 H{tool_no} M08") gcode_lines.append(f"G01 Z{z_start} F{feedrate/2:.2f}") gcode_lines.append(f"M97 P501 L{nosteps}") gcode_lines.append(f"G00 Z{z_rapid + 20} M09") gcode_lines.append("M05") gcode_lines.append("M97 P8000") gcode_lines.append("M30") gcode_lines.append("\nN501") gcode_lines.append(f"G91 G01 Z-{z_cut:.2f} F{feedrate/2:.2f}") gcode_lines.append("G90") gcode_lines.append(f"G03 X{pxdthr:.2f} Y{y_pos:.2f} J-{lead_in:.2f} F{feedrate:.2f}") gcode_lines.append(f"G01 X{pxdtqr:.2f} Y{nyrtr:.2f}") gcode_lines.append(f"G01 X{nxdtqr:.2f} Y{nyrtr:.2f}") gcode_lines.append(f"G01 X{nxdthr:.2f} Y{y_pos:.2f}") gcode_lines.append(f"G01 X{nxdtqr:.2f} Y{pyrtr:.2f}") gcode_lines.append(f"G01 X{pxdtqr:.2f} Y{pyrtr:.2f}") gcode_lines.append(f"G01 X{pxdthr:.2f} Y{y_pos:.2f}") gcode_lines.append(f"G03 X{pxdthr + lead_in:.2f} Y{y_pos - lead_in:.2f} I{lead_in:.2f}") gcode_lines.append(f"G01 X{pxdthr + lead_in:.2f} Y{y_pos + lead_in:.2f}") gcode_lines.append("M99") gcode_lines.append("\nN8000") gcode_lines.append("G00 G90 M09") gcode_lines.append("G53 G00 G40 Z0") gcode_lines.append("G53 G00 G40 X0 Y0") gcode_lines.append("M01") gcode_lines.append("M99") gcode_lines.append("%") # End of program # Display the generated G-code output_element = js.document.querySelector("#hex-gcode-output pre code") output_element.innerText = "\n".join(gcode_lines) except Exception as e: output_element = js.document.querySelector("#hex-gcode-output pre code") output_element.innerText = f"Error generating G-code: {str(e)}\nPlease check your input values." # Placeholder for the function definition itself, as py-click handles the event. pass













Generated G-code:

Bolt Hole on PCD G-code Generator

Bolt Holes

This program will create G-code for peck drilling a series of bolt holes based on the parameters you input. Please follow the prompts to input the necessary parameters.

import js from pyscript import display def generate_bolt_hole_gcode(event): try: tool_no = js.document.getElementById("bh-tool-no").value wrk_ofset = js.document.getElementById("bh-work-offset").value spdle_rpm = js.document.getElementById("bh-spindle-rpm").value x_pos = float(js.document.getElementById("bh-x-position").value) y_pos = float(js.document.getElementById("bh-y-position").value) z_rapid = float(js.document.getElementById("bh-z-rapid").value) peck = float(js.document.getElementById("bh-peck-size").value) z_depth = float(js.document.getElementById("bh-z-depth").value) pcd = float(js.document.getElementById("bh-pcd").value) noholes = int(js.document.getElementById("bh-no-holes").value) feedrate = float(js.document.getElementById("bh-feed-rate").value) gcode_lines = [] gcode_lines.append("Welcome to Tonys Basic Bolt Hole G-Code Creator") gcode_lines.append("Generating G-code...") gcode_lines.append("%") # Start of program gcode_lines.append("M97 P8000") gcode_lines.append("M05") gcode_lines.append(f"T{tool_no} M06") gcode_lines.append(f"M03 P{spdle_rpm}") gcode_lines.append(f"G{wrk_ofset}") gcode_lines.append("G40") gcode_lines.append("G98 G17") gcode_lines.append(f"G00 X{x_pos:.2f} Y{y_pos:.2f}") gcode_lines.append(f"G{wrk_ofset} G00 Z{z_rapid} G43 H{tool_no} M08") # G83 Z-depth R-rapid Q-peck F-feedrate L0 (L0 means it will repeat based on G70) gcode_lines.append(f"G83 Z-{z_depth:.2f} R{z_rapid:.2f} Q{peck:.2f} F{feedrate:.2f} L0") # G70 I-radius J0 L-number_of_holes gcode_lines.append(f"G70 I{pcd/2:.2f} J0 L{noholes}") gcode_lines.append("G80") # Cancel canned cycle gcode_lines.append(f"G00 Z{z_rapid} M09") # Retract to rapid position and turn off coolant gcode_lines.append("M05") # Spindle stop gcode_lines.append("M97 P8000") # Call subprogram for program stop/reset gcode_lines.append("M30") # Program end and reset gcode_lines.append("\nN8000") # Subprogram for program stop/reset gcode_lines.append("G00 G90 M09") gcode_lines.append("G53 G00 G40 Z0") # Move Z to machine zero gcode_lines.append("G53 G00 G40 X0 Y0") # Move X/Y to machine zero gcode_lines.append("M01") # Optional program stop gcode_lines.append("M99") # End of subprogram gcode_lines.append("%") # End of program output_element = js.document.querySelector("#bh-gcode-output pre code") output_element.innerText = "\n".join(gcode_lines) except Exception as e: output_element = js.document.querySelector("#bh-gcode-output pre code") output_element.innerText = f"Error generating G-code: {str(e)}\nPlease check your input values." # Placeholder for the function definition itself, as py-click handles the event. pass











Generated G-code:

Rectangle Pocket G-code Creator

Rectangular Pocket Diagram

This program will create G-code for a simple rectangular pocket based on the parameters you input.

import js from pyscript import display def generate_rect_pocket_gcode(event): try: tool_no = js.document.getElementById("rp-tool-no").value tool_dia = float(js.document.getElementById("rp-tool-dia").value) tool_rad = tool_dia / 2.0 wrk_ofset = js.document.getElementById("rp-work-offset").value spdle_rpm = js.document.getElementById("rp-spindle-rpm").value x_pos = float(js.document.getElementById("rp-x-position").value) y_pos = float(js.document.getElementById("rp-y-position").value) z_rapid = float(js.document.getElementById("rp-z-rapid").value) z_start = float(js.document.getElementById("rp-z-start").value) tz_cut = float(js.document.getElementById("rp-tz-cut").value) z_depth = float(js.document.getElementById("rp-z-depth").value) nosteps = int(z_depth / tz_cut) z_cut = z_depth / nosteps if nosteps > 0 else z_depth x_dist = float(js.document.getElementById("rp-x-distance").value) y_dist = float(js.document.getElementById("rp-y-distance").value) step_over_percent = float(js.document.getElementById("rp-step-over").value) step_over = (step_over_percent / 100) * tool_dia feedrate = float(js.document.getElementById("rp-feed-rate").value) x_cut_inner = (x_dist / 2.0) - tool_rad y_cut_inner = (y_dist / 2.0) - tool_rad if x_cut_inner > y_cut_inner: side_steps = x_cut_inner / step_over else: side_steps = y_cut_inner / step_over side_steps = max(1, int(side_steps)) gcode_lines = [] gcode_lines.append("Welcome to Tony's Basic Rectangle Pocket G-Code Creator") gcode_lines.append("Generating G-code...") gcode_lines.append("\n%") gcode_lines.append("M97 P8000") gcode_lines.append("M05") gcode_lines.append(f"T{tool_no} M06") gcode_lines.append(f"M03 S{spdle_rpm}") gcode_lines.append(f"G{wrk_ofset}") gcode_lines.append("G40") gcode_lines.append("G98 G17") gcode_lines.append(f"G00 X{x_pos + step_over:.2f} Y{y_pos:.2f}") gcode_lines.append(f"G{wrk_ofset} G00 Z{z_rapid:.2f} G43 H{tool_no} M08") gcode_lines.append(f"G01 Z{z_start:.2f} F{feedrate / 2:.2f}") gcode_lines.append(f"G91 G02 I-{step_over:.2f} Z-{z_cut / 2.0:.2f} L{2 * nosteps} F{feedrate / 2.0:.2f}") gcode_lines.append(f"G02 I-{step_over:.2f}") gcode_lines.append(f"G90 G01 X{x_pos:.2f} F{feedrate:.2f}") gcode_lines.append(f"G01 Z{z_start:.2f} F{feedrate:.2f}") gcode_lines.append(f"M97 P701 L{nosteps}") gcode_lines.append(f"G00 Z{z_rapid:.2f} M09") gcode_lines.append("M05") gcode_lines.append("M97 P8000") gcode_lines.append("M30") gcode_lines.append("\nN701") gcode_lines.append(f"G91 G01 Z-{z_cut:.2f} F{feedrate / 2.0:.2f}") gcode_lines.append("F" + str(feedrate)) gcode_lines.append("G90") for i in range(1, side_steps + 1): current_x_offset = x_cut_inner * (i / side_steps) current_y_offset = y_cut_inner * (i / side_steps) gcode_lines.append(f"G01 X{x_pos + current_x_offset:.2f}") gcode_lines.append(f"G01 Y{y_pos - current_y_offset:.2f}") gcode_lines.append(f"G01 X{x_pos - current_x_offset:.2f}") gcode_lines.append(f"G01 Y{y_pos + current_y_offset:.2f}") gcode_lines.append(f"G01 X{x_pos + current_x_offset:.2f}") gcode_lines.append(f"G01 Y{y_pos:.2f}") gcode_lines.append(f"G01 X{x_pos:.2f} Y{y_pos:.2f}") gcode_lines.append("M99") gcode_lines.append("\nN8000") gcode_lines.append("G00 G90 M09") gcode_lines.append("G53 G00 G40 Z0") gcode_lines.append("G53 G00 G40 X0 Y0") gcode_lines.append("M01") gcode_lines.append("M99") gcode_lines.append("%") output_element = js.document.querySelector("#rp-gcode-output pre code") output_element.innerText = "\n".join(gcode_lines) except Exception as e: output_element = js.document.querySelector("#rp-gcode-output pre code") output_element.innerText = f"Error generating G-code: {str(e)}\nPlease check your input values." pass














Generated G-code:

Circular Pocket G-code Creator

Circular Pocket Diagram

This program will create G-code for a simple circular pocket based on the parameters you input.

import js from pyscript import display def fmt(v): return f"{v:.2f}" def generate_circular_pocket_gcode(event): # Renamed function to match py-click try: tool_no = js.document.getElementById("cp-tool-no").value tool_dia = float(js.document.getElementById("cp-tool-dia").value) tool_rad = tool_dia / 2.0 wrk_ofset = js.document.getElementById("cp-work-offset").value spdle_rpm = js.document.getElementById("cp-spindle-rpm").value x_pos = float(js.document.getElementById("cp-x-position").value) y_pos = float(js.document.getElementById("cp-y-position").value) z_rapid = float(js.document.getElementById("cp-z-rapid").value) z_start = float(js.document.getElementById("cp-z-start").value) tz_cut = float(js.document.getElementById("cp-tz-cut").value) z_depth = float(js.document.getElementById("cp-z-depth").value) # Calculate nosteps and z_cut safely if tz_cut > 0: nosteps = int(z_depth / tz_cut) z_cut = z_depth / nosteps if nosteps > 0 else z_depth else: nosteps = 1 z_cut = z_depth circ_dia = float(js.document.getElementById("cp-circ-dia").value) circ_rad = circ_dia / 2.0 step_over_percent = float(js.document.getElementById("cp-step-over").value) step_over = (step_over_percent / 100) * tool_dia feedrate = float(js.document.getElementById("cp-feed-rate").value) # --- Calculate Values --- cut_rad = circ_rad - tool_rad # Ensure cut_rad is not negative if tool is larger than pocket if cut_rad < 0: cut_rad = 0 # Calculate side_steps safely if step_over > 0: side_steps = int(cut_rad / step_over) else: side_steps = 1 # Default to 1 step if step_over is 0 or negative # Ensure at least one step if cut_rad is positive if cut_rad > 0 and side_steps == 0: side_steps = 1 ris = cut_rad / side_steps if side_steps > 0 else 0 # --- G-Code Generation --- gcode_lines = [] gcode_lines.append("%") # Program Start gcode_lines.append("M97 P8000") gcode_lines.append("M05") gcode_lines.append(f"T{tool_no} M06") gcode_lines.append(f"M03 S{spdle_rpm}") gcode_lines.append(f"G{wrk_ofset}") gcode_lines.append("G40") gcode_lines.append("G98 G17") # --- Initial Rapid Move --- gcode_lines.append(f"G00 X{fmt(x_pos + step_over)} Y{fmt(y_pos)}") gcode_lines.append(f"G{wrk_ofset} G00 Z{fmt(z_rapid)} G43 H{tool_no} M08") gcode_lines.append(f"G01 Z{fmt(z_start)} F{fmt(feedrate / 2)}") # Spiral down if multiple steps, otherwise direct cut if nosteps > 1: # Ensure the spiral down command is correctly formatted gcode_lines.append(f"G91 G02 I-{fmt(step_over)} Z-{fmt(z_cut/2)} L{2*nosteps} F{fmt(feedrate / 2)}") gcode_lines.append(f"G02 I-{fmt(step_over)}") else: gcode_lines.append(f"G01 Z{fmt(z_depth)} F{fmt(feedrate)}") # Direct cut to final depth if only one step gcode_lines.append("G90 G01 X" + fmt(x_pos)) # Move to center X gcode_lines.append("G01 Z" + fmt(z_start) + " F" + fmt(feedrate)) gcode_lines.append(f"M97 P801 L{nosteps}") gcode_lines.append(f"G00 Z{fmt(z_rapid)} M09") gcode_lines.append("M05") gcode_lines.append("M97 P8000") gcode_lines.append("M30") # --- Pocketing Subroutine --- gcode_lines.append("\nN801") gcode_lines.append(f"G91 G01 Z-{fmt(z_cut)} F{fmt(feedrate / 2)}") gcode_lines.append(f"F{fmt(feedrate)}") gcode_lines.append("G90") for i in range(1, side_steps + 1): r_step = ris * i gcode_lines.append(f"G01 X{fmt(x_pos + r_step)}") # Original Python had G02 I-(XPos+R_step). This is likely incorrect for circular pocketing. # A typical circular pocketing path would involve moving in X, then Y, then X back, etc. # For a simple spiral, it might just be a single G02/G03 to complete the circle at that radius. # Based on the original Python logic, I'm keeping it as is, but it might need review for actual toolpath generation. gcode_lines.append(f"G02 I-{fmt(x_pos + r_step)}") gcode_lines.append(f"G90 G01 X{fmt(x_pos)} Y{fmt(y_pos)}") gcode_lines.append("M99") # End of Subroutine # --- Program End Subroutine --- gcode_lines.append("\nN8000") gcode_lines.append("G00 G90 M09") gcode_lines.append("G53 G00 G40 Z0") gcode_lines.append("G53 G00 G40 X0 Y0") gcode_lines.append("M01") gcode_lines.append("M99") gcode_lines.append("%") # Program End output_element = js.document.querySelector("#cp-gcode-output pre code") output_element.innerText = "\n".join(gcode_lines) except Exception as e: output_element = js.document.querySelector("#cp-gcode-output pre code") output_element.innerText = f"Error generating G-code: {str(e)}\nPlease check your input values." # Placeholder for the function definition itself, as py-click handles the event. pass













Generated G-code: