G-code Basics for 3D Printing
If you are in a foreign country, it's immensely helpful to understand some of the spoken language. And just like on your summer vacation, if you're regularly working with 3D printers or other CNC machines, understanding how G-code is built up and what some of the instructions mean can enable you to not only fix problems but also easily customize prints to your needs.
G-code is how we tell our machines what they need to do. It has been around since the late 1950s and is the most widely used Computer Numerical Control programming language. Though, don't be scared if I say programming language because it's one of the most simple languages you can think of because in the form it's used on most 3D printers, there are no loops, no if statements, no brackets, or any other fancy stuff. If you prepare a model in your favorite slicer and open the generated G-code in a text editor, you can see that it's simply a list of commands that our 3D printers' firmware reads and then executes – one line after the other. We'll look at the most common G-code flavor for 3D printers, which is compatible with the marlin firmware. If you're running a printer with RepRap firmware or maybe a CNC router with Mach 3 the overall look of the file will be the same though some commands might do slightly different things. In this video I'll cover the most common commands that will enable you to understand 95% of your 3D printing G-Code but if you want to learn more, there are references of all commands and how G-code needs to look for a specific firmware. I've linked a couple of these resources down in the description.
So let's look at Marlin-G-code. As I said before, each line of code is processed one after the other – from the beginning of the file till its end. The files are usually build up with a header that includes some general information. Next follows the start g-code that you can customize in your slicer, then the print commands with the end G-code. There is also often a block of text that contains all of the slicer settings that were used. This settings section is sometimes very helpful if you forgot to save a profile or received a g-code file from somebody else that printed really well. Some slicers will allow you to import the G-code file and generate a profile out of the settings, though usually only if the G-code was also created with the same slicer.
Comments
If we look at the header or the settings block, we can already see something important. Those lines usually start with a semicolon. Having a semicolon at the beginning of a line means that this is a comment, so it will be ignored by the firmware. You can't only comment out a whole line but also add a comment after a regular command to make the code better readable. Slicers will also frequently add comments so that it's easier for you to find a certain layer or a certain feature. Just for completeness – some firmwares support comments in brackets as per CNC G-code standard, though this style gets rarely used.
Syntax
Let's now take a look at the syntax of G-code commands. Each command starts with a letter. G stands for preparatory commands and is usually used for movement related tasks. M commands or Miscellaneous commands are often used to change settings or perform actions. The following number references a specific command. Next follow the parameters for that G-code command with a descriptive letter followed by the value. Really simple.
G0 & G1 - Linear Movement
Let's start with the most common commands which are G0 and G1 and are used for the movement of the axes. The XYZ parameters define the location where it needs to move, E defines the amount of material extruded, and F defines the federate, usually in mm per minute. G0 and G1 don’t require values for all axes and also the federate only needs to be set once and will persist until it gets changed. G0 was used in the past for rapid moves where precision wasn't needed, G1 on the other hand, was a coordinated linear move from one to another position. On today's 3D printers G0 and G1 do practically the same and there is only the convention that G0 shall be used for travel movements and G1 for movements where also material gets extruded.
G90 & G91 - Positioning Mode
A very important command pair in context to G0 and G1 is G90 and G91. These set the positioning mode to absolute or relative. If G90 is set, all movements are to absolute positions in the printers coordinate system. So G0 X50 Y50 will move the tool head to X50, Y50 a following G0 X100 Y100 will move the head to X100 Y100.
If G91 is set, all movements are relative to the last position. So if we start at the origin X0 Y0 and send G0 X50 Y50, we will move to X50 Y50 though if we then send G0 X100 Y100, we'll perform an incremental move and end up at X150 Y150.
Most of the movements in your GCode file will be achieved using absolute positioning. Where relative positioning might be useful is, for example, for your end G-Code, where you want to lift your nozzle from the print and move away. So regardless of your model height, G91, then G0 Z10 will always lift the printhead by 10 mm. Right after that, we switch back to absolute positioning with G90 and can move the nozzle to the edge of the printbed.
M82 & M83 - Extruder Positioning Mode
Also related to the print moves is the command pair M82 and M83. Even though it might seem a bit weird in the beginning, but our filament extruder is the 4th axis of our 3D printer and can be switched separately from absolute to relative positioning, just like our movement axes. M82 sets the axis to absolute mode, M83 to relative. This setting is mostly a preference of the slicer that you're using. CURA mostly puts out extrusions in absolute coordinates, so M82, whereas PrusaSlicer, for example, defaults to relative extrusions with M83. There are discussions on whether one or the other is better or worse for accumulated relative error, though in my experience it doesn't really matter and is more a question of what style you prefer.
G28 - Homing
Most of our 3D printers use simple stepper motors for the axes without any positional feedback. This means that when you turn your machine on, it doesn't know its at. This is why basically every G-code file that we run on our printers contains G28 right at the start. G28 initiates the homing routine, where the machine moves to end stops with known positions. This can be as simple as just issuing G28 where all axis get homed one after the other. By adding the X, Y or Z parameter or a combination of them, we can tell the firmware to only home one or two axes.
G29 - Bed Leveling
More and more 3D printers start shipping with bed leveling probes where G29 is used to start the leveling process. G28 and G29 usually come in successive order because the axes need to be homed before you start bed probing.
G92 - Set Current Position
In a way similar to homing, using the command G92 lets us set the current position to a specific value. So regardless of where you are, sending G92 X0 Y0 Z0, for example, will tell the printer that the current location is the new origin of the coordinate system. In 3D printing, G-code G92 is most commonly found when absolute extrusions are used, and the extruder axis is reset for better readability.
M104 & M109 + M140 & M190 - Temperatures
Let's now talk about temperatures and, in particular, nozzle and bed temperatures. With M104 and M109 plus the parameter S, the nozzle temperature gets set. But what's the difference between this pair of commands? M104 simply sets the nozzle temperature, and then the execution of the G-code will continue as usual. M109, on the other hand, sets the temperature and then pauses the G-code execution until the temperature is reached. This is exactly the same when setting the bed temperature. M140 will simply set the intended temperature, M190 will set it and pause until the temperature is reached.
By the way, the two pairs of commands are really easy to remember because the numbers 4 and 9 are just shifted by one digit.
You'll basically find them in any start script where you want to wait until the proper temperatures are reached and only then start the print. If your printer starts heating the bed and nozzle simultaneously, you'll find M104, M140, M109, M190.
Some machines first heat the bed and then the nozzle to avoid material oozing. In this case, you'll usually find M140, M190, M104, and M109 in the starting script.
So if you're tired of waiting for bed and nozzle to heat up one after the other, you now know what to change in your start script! In my case, I often manually add M104 commands into my G-codes at certain heights to customize my temperature towers. I don't use M109 because the new temperature usually gets reached within one layer, so pausing the print causes more problems than it helps.
M106 - Set Fan Speed
Another important command is M106 which is used to control the cooling fan. The parameter S, which can range from 0 to 255, lets you adjust its speed. Full power is 255 and half power is 128 for example. If you want to turn it off completely, M106 S0 or the dedicated command M107 gets used.
M84 - Disable Steppers
The last command I want to talk about is M84. The stepper motors will remain powered after moving an axis using the printer's control to avoid losing their position. If you want to disable the motors so that the axes can be moved by hand, you can use M84 for all axes or M84 with the X, Y, Z, and E parameters to turn off individual axes.
And that's it! If you remember these 10 commands or pairs of commands, you will understand most of the G-Code that your slicer generates and customize printing routines to your liking. Of course, there are many more commands, but the ones I presented to you are the most important ones, in my opinion. Let me know in the comments which command you think is the most important to remember and when the knowledge about G-code is most practical?