From RepRapWiki
Jump to: navigation, search


M104 & M109 Deprecation, G10 Introduction

No issues with deprecating M109, as this is an equivalent to M104 & M116. But M104? [heated bed (M140) example deleted]

I consider G10 head/tool offset a good idea, but temperatures should be set by it's own command. Also, one often sets a temperature only, keeping the geometrical offset.

If the L value is ignored, why is it part of the specification?

Last not least, Marlin people already defined M206 for the head offset. These two should be aligned.

--Traumflug 11:28, 19 July 2012 (UTC)

M140 seems unaffected, Traumflug, so you can set the bed temp without changes. That said, I don't like any of this one bit. I don't like that the fast temp setting is gone, and I don't like that mysterious temperatures come out of nowhere when switching tool. I'd much prefer G10 to deal with spatial offset only, and use M10{4|9} [T0] S200. It gives the gcode generator much more control over the process. Having an OPTIONAL temperature setting in G10 would be acceptable for me, but definitely not deprecating M104/M109


I don't quite see why temperature offsets are different from spatial offsets - it's just another dimension in which the machine operates. It seemed neater to me to set them all in one place. And temperatures don't come out of nowhere - they are values you have previously explicitly set...

Jean-Marc pointed out that it would be useful to have an option to save and load this stuff from eeprom like Marlin with M500 - that way you could have slightly different offsets for different machines and still run them all off the same G Code file.

I agree that M104 is useful as it allows you:

  1. to set temp and return
  2. to do stuff you know doesn't involve extruding
  3. to set same temp and wait

Which speeds things up a bit at the start of a print. I'm not quite sure what we should do about that.

As there is a standard (G10) for setting offset that pre-dates the invention of 3D printing, I think that's preferable to M206.

Finally - remember that the time interval between something being deprecated and something going away altogether can be arbitrarily long, and is entirely in the hands of people writing firmware :-)

- Adrian

I have no problem introducing a new command which is a superset of existing functionality, and even better if it is more standard compliant, but I can't see a good reason to remove the previous commands, as there is no conflict in functionality. Presumably if G10 returns an error, then the host must fall back to previous commands.

I don't know which standard you are looking at, but in mine (the official NIST standard) G10 does not set tool offsets. It appears some software out there is using a different, non-standard meaning for G10. I don't think non-standard use by one or more applications creates "a standard". Our use of G10 also has quite different parameters. This proposal would appear to be replacing non-standard command(s) with a new non-standard command, which doesn't help standardization and breaks compatibility.

--Bobc 21:41, 30 July 2012 (UTC)

If this has been addressed, I apologize; but, having worked at, and with, NIST, they don't just 'make' standards, they ensure universal implementation. This means, if new standards are implemented, and usually for a good reason because of need, they will adopt them. If RepRap wants a new GCODE that is unique in some way, and different from existing, often just informing the person at NIST responsible will see that it gets implemented in the Official Standard. This is not a willy nilly process, and if the industry is using that standard, and it is unique, even meaning stand alone, incorporation of the code in another G code in this case is irrelevant; they will probably, and I feel confident in this, add that to the list of standards, they just need to be aware of it. They don't exist to enforce code implementation, but like dictionaries and word usage which changes, they're there to ensure everyone knows the standards, new use is expected, new codes are expected, additions happen. --Cyberchipz (talk) 17:45, 27 June 2015 (PDT)

Thanks for the comments so far. I see we agree on M109 being obsolete, so I've removed the discussion tag.

Regarding the NIST standard, G10 is described there as setting a coordinate system, so it's similar to setting a tool offset.

Not a word there on what L does, though. So I reduced it's description.

What's left is R and S, the standby and work temperatures. How about making them optional?

  • Without R and S, both default to zero, so we have the (former) behaviour without G10.
  • With R and/or S, temperatures are set at tool change time (T, M6 command).
  • M104 always sets the temperature of the current extruder. So it matches traditional behaviour in case R and S weren't used. In case R and/or S are used, M104 overrides the extruder's work temperature, but doesn't change the extruder's S setting.

--Traumflug 22:22, 31 July 2012 (UTC)

I don't see the same agreement on M109 that you do, unless you are ignoring specific objections.

I did a little digging, it appears the L parameter selects a "parameter number". So in NIST, L2 means "set coordinate system". FANUC systems use versions of G10 as "set tool offsets", sometimes L1, L10 or L12, sometimes omitted. Other L numbers may set other parameters, depending on machine. LinuxCNC appears to support several values of L. If we are using the parameters to mean something different (e.g R parameter is not used to define cutter radius), we should probably pick something like L3.

Ref LinuxCNC G Codes

--Bobc 08:02, 4 August 2012 (UTC)

Did I miss something? I see no vote for M109, just a combined one for M104/M109. How to replace M109 by M104 is described.

So, the L parameter is sort of a sub-command on a number of other, non RepRap G-code interpreters. Thanks a lot for the digging. Does that make the current description of the RepRap G-code flavour wrong? I think it's sufficient to describe what a RepRap firmware does, elaborating on what others do should go to something like a "G-code in General" wiki page.

--Traumflug 10:45, 4 August 2012 (UTC)

Has anyone implemented G10 in either a slicer or a firmware in the way described on the wiki? I am depending on M109s and M104s in prontserve to send the target temperature events but I can add G10 as well if this is actually used somewhere. Marlin seems to use it as a retract command (see ) and I guess I can just go off that.

TL;DR This is very unclear to me. This needs documentation.

--TheOtherRob 03:37, 27 June 2013 (UTC) (d1plo1d on github)

Just to be clear, industry can set standards and they do get published by NIST for universal reasons. I'd agree that total non-unique or duplication for proprietary reasons breaks standards, and for the community shouldn't be done; but, it happens all the time. And my personal opinion is 'BOO' on them. Industry leaders get away with this all the time, and often new standards are adopted to retain compatibility for this reason. Still, if one wants to ensure compliance ensuring one retains the standard is good; but, if there's a real need for it, to reduce instruction sets I believe is a good reason to have a code stand alone for one action. Definately intermixing instructions of non related activity should have a good reason, like it's used a lot, and only those two commands would be a consideration, again for simplifying and reducing instruction lengths. The bottom line is that NIST will adopt and publish meaningful changes; as long as they're aware of them. They're great guys, and I would say extremely rational and logical in what does and does not get implemented. The process is not so complicated that changes can't happen; just be sure to let them know, so they are aware of it. I know a lot of this is due to CNC, and for that reason because I believe a day will come where we'll have a multi-tool type printing device extrusion and cnc, etc. These code sets have more in common than not, and should be made, implemented, and recorded as standards accordingly each in their own subset as related to fitness of purpose and function. NIST is a reasonable entity.--Cyberchipz (talk) 18:07, 27 June 2015 (PDT)


"These are the line number and the checksum. The RepRap firmware checks the checksum against a locally-computed value and, if they differ, requests a repeat transmission of the line of the given number. "

Surely the firmware must request resending of the expected number, not the given number in the line. If the checksum is wrong, then the firmware should not rely on the line being correct, including the N value. The same goes for valid checksum but line number out of sequence, the algorithm as stated will keep requesting the same line!

--Bobc 21:41, 30 July 2012 (UTC)

Other stuff

Ah excellent, I've been waiting for this! I've been working from the gcode and mcode pages in the old wiki which have a few holes.

The line number and checksum stuff is new to me- I'll implement that into my firmware in the coming days. So are some of these M-codes for that matter.

Can we add some sort of reference for what the host expects in response from the firmware? So far, I'm sending back OK when the command is queued or executed and T: nnn every second when the heater is on, which as far as I can tell is all that's needed.

ps: why are G20/G21/G90/G91/G92 specified to block? ("The following commands are not buffered. When one is received it is stored, but it is not acknowledged to the host until the buffer is exhausted and then the command has been executed.") they simply alter the conversion factors for the next command received in my firmware, and so can respond OK immediately.

Only G4 (dwell) and M101 (start extruder when up to temperature, apparently superceded by the new M109) block in my firmware at the moment, and I'm seriously considering making even these queue-able so they block the queue instead of the command download stream.

-- Triffid Hunter

I agree. It's great for this to be documented.

I had one suggestion on the checksum -- it should perhaps use a stronger CRC checksum, and should also encorporate the length as well? Is the N and * part of an external standard, or a RepRap special sauce?

If they are RepRap specific, I'd suggest changing the N code to include line length as something like "N101.50" for line 101, consisting of 50 characters.

I use the following CRC algorithm, which I believe I stole from the CCITT standard:

static inline uint16_t GetCRC( uint16_t crc, char ser_data )
  crc  = (unsigned char)(crc >> 8) | (crc << 8);
  crc ^= ser_data;
  crc ^= (unsigned char)(crc & 0xff) >> 4;
  crc ^= (crc << 8) << 4;
  crc ^= ((crc & 0xff) << 4) << 1;
  return crc;

The logic to compute checksum would then become:

uint16_t cs = 0;
for(int i = 0; i < cmd.length(); i++)
  cs = GetCRC( cs, cmd.charAt(i) );

computedCrc = cs;

So, the full logic for accepting or testing a line, encoded with full N and CRC checksum would be something like:

// was line number and checksum provided?
bool value = true;
if( lineNumber != 0 )
  valid = lineNumber == expectedLineNumber
    && cmd.length() == providedLength
    && computedCrc == providedCrc;

// accept or reject the line based on valid flag

This does add a few bytes of overhead (3-4 for length, 2-3 for 16 bit crc), but may be worth it allows you to run a higher baud rate with reasonably low error rates -- the odds of a false positive are near enough to zero to make any statistician happy.

-- BeagleFury

Just wanted to chime in - Thanks Adrian! This answers many questions for me! -- Wade

what part of the line does cmd.length() refer to?

Just trying to implement the checksum logic, and realised that it makes no sense for the checksum to include itself or things get very recursive. What point is considered end-of-line? is it the asterisk? the space before the asterisk? the last non-whitespace before the asterisk?

My firmware doesn't buffer the line, rather processes it character by character so this has to become another special case.

-- Triffid Hunter

The checksum includes all characters in the string up to and including the character before the asterisk (i.e. up to but not including the asterisk). -- neilrqm

Future-proof M-codes?

Adding new M-codes for extra sensors/heaters seems a little non-future-proof to me. My firmware uses P parameter to know which sensor/heater is being referred to eg M104 S100 sets heater 0 to 100c, but M104 P2 S100 sets heater 2 to 100c. Same for all the temperature sensor readback stuff. Future proofing protocols is always a good idea :)

G91: Set to Relative Positioning

Example: G91 All coordinates from now on are relative to the last position.

Question: does this include the feed rate?

-- User:Pietr

M203: Record Z adjustment

which firmware does this?

Sprinter Main does not have M203 implimented Sprinter Experimental has M203 as "M203 Temperature monitor for Repetier" Repetier has M203 as Temperaturmonitor. Marlin has M203 - Set maximum feedrate that your machine can sustain (M203 X200 Y200 Z300 E10000) in mm/sec Teacup has no M203

Does any current or experimental firmware have the z adjustment implimented?

eMAKER Sprinter used this. but is now deprecated in favour of Marlin.

-- jmgiacalone

M92: Set axis_steps_per_unit

M92 Sets the number of steps per unit, this is GREAT to fine tuning the extruder head, where even different colors of the same filament act differently, even when the measured diameter is measured precisely. It's simple enough to calibrate this using a simple cube alternating layers between 100% infill and 95% infill and adjusting the E steps per mm to not show gaps on the 100% layers and to just barely show gaps on the 95% layers.

M92 is much better for compensating for different filament than putting it in the slicer program, because you might want to run the same program with different colors.. even within the same job, perhaps one would want to pause the program during a non critical infill, remove the filament, put in a different color, and then continue.. if you had previously calibrated all your filaments and got accurate steps per mm of those filaments, you can simply issue a M92 for the filament you just installed, then when you continue the program, the extruder will be working correctly.

The problem I find is that I don't know what number to start putting in there.. it is listed in config.h, however that can be overridden if the eeprom is activated. I notice that M99: Set axis_hysteresis_mm has a corresponding M98: Get axis_hysteresis_mm why not have an M91: Get axis_steps_per_unit. Then there would be no mucking about in code trying to figure out what the extruder is currently set at, and it would make it MUCH easier for people who bought kit machines who really don't understand the code to be able to calibrate the extruder head.

EEPROM gcodes

It would be great if there were such a gcode function since still at the time of writing the retailer at least aught to point the client in the right direction for resources on the subject. Which unfortunately very few seems to actually do and the client remains restrained as a consumer instead of as advertised an step towards a emancipated maker through educational resources on settings/calibration, but also inspirational homage dito, to use the tool efficiently as well as with heart. Thankfully there are initiatives such as FSF's "Respects Your Freedom hardware product certification", which one can easily endorse especially in times were companies reap but, more importantly do not sow.

Anyhow, there are some Proposed EEPROM configuration codes which marlin, sprinter, teacup et al firmwares uses. But needless to say, all of these depend on that one enabled the feature in the configuration pages and beyond that a friendly GUI, which repetier host is the only alternative (so far) when it comes to "easy to use point and click"-settings.

For Teacup firmware EECONFIG is enabled by default, so there is no need for enabling anything. And you guessed it, quite some retailers have no idea of what they're selling. This is a consequence of RepRap putting so much emphasis on being open source ( = zero pay for developers) and cheering commercial shops ( = all money goes to the shops). So, I see no point in complaining about "retailers". It's what RepRap asks for. --Traumflug 12:07, 6 December 2012 (UTC)

Time for G-code V2

Is it time to rewrite this G-code specification, maybe call it version 2, or a more creative naming variant? The current specification is a kludge going back many years and authors. The ACK specification is inconsistent. There is no formal language specification, so new language features get added and "do their best to follow existing standards" - standards which aren't actually defined. Different firmwares provide variants on the specification here, but again there's no standard for them to follow, or way to define their variant so control software programmers can adjust easily and confidently.

  1. Let's discuss a roadmap and milestones for such an effort.
  2. Let's create a specification in a formalized notation so non-english speakers don't need a translator to read it.
  3. Let's formalize our 3D printer G-code variant by writing it in Backus–Naur Form. Indeed this may scare some cooks out of the kitchen...I doubt it...but if they are, maybe that's good.
  4. Let's get a standard and consistent ACK
  5. Let's discuss and find ways to improve the ACK to make things easier for control software
  6. Let's not leave slots for "forwards compatibility". Instead, let's recommend (or specify) how to extend the specification we create.
  7. Let's create a consistent ACK specification. The current one is inconsistent. Take, for example, the wait commands. Rather than send an OK as response to the command, the spec. allows firmwares to send other data - such as the current temp readings (w/targets) - and it can easily take up to 600 seconds for control software to receive "OK" while it was processing kilobytes of response data.
  8. Let's address how commands are buffered. For example, it might make sense to specify that upon receiving a buffered command, an ACK is sent in response that indicates the command was buffered - or more importantly which command was buffered.
  9. Let's create a standard way for firmwares to identify themselves, and their capabilities.

Here's a G-Code example per this spec. from Marlin that exposes fundamental issues:

Send: M104 S1900
Recv: ok T:28.1 /1900.0 B:59.8 /60.0 @:127 B@:0
Recv: ok T:29.2 /1900.0 B:59.9 /60.0 @:127 B@:0
Recv: ok T:31.3 /1900.0 B:59.9 /60.0 @:127 B@:0
Recv: ok T:32.0 /1900.0 B:60.0 /60.0 @:127 B@:0
: Extruder switched off. MAXTEMP triggered !
Error: Printer stopped deu to errors. Fix the error and use M999 to restart!. (Temperature is reset. Set it before restarting)

A similar scenario is encountered when setting the bed temp. According to the spec we expect a similar result for a target < MINTEMP - possibly permuting this (poor) specification outcome to at least 4 use-cases.

The command M104 S1900 asks the printer to destroy a typical reprap hotend. It would be trivial to specify how to respond with an error msg. for an out-of-range temp. request immediately, not when hitting MAXTEMP. Same for MINTEMP if that's the case. However, the current spec. does not provide a way to ACK with a standard error msg. In fact, it does not provide a standard ACK format, it just illustrates what certain firmwares do in their ACKs.

(Anonymous user?)

I am still waiting for a G-Code V1!
The problem is not lack of a standard, but that people just don't want to follow specs. There is a good NIST G-code spec, but no one followed that. New G-code features are hacked in arbitrarily, and this is the case from Day 1, where the "spec" was whatever the first firmware written happened to do. By it's nature, a wiki based spec is a free for all.
There are some elements of what you suggest already, but getting an encompassing spec written is unlikely to happen, unless someone volunteers to do it. You might get further if you make some specific suggestions regarding ACKs say, and add that as a "Proposed .." section. Really, the only thing you can do is to design something better and hope people will use it.
Also please sign so we know who we are talking to :)
--Bobc (talk) 08:05, 30 December 2013 (PST)

M160 Syntax

The Syntax proposed was

M160 S4
G1 X90.6 Y13.8 E22.4 0.1 0.1 0.1 0.7
G1 X70.6 E42.4 0.0 0.0 0.0 1.0
G1 E42.4 1.0 0.0 0.0 0.0

However whitespace delimiters do not work well(at all) in most gcode implementations, I have updated these to ":" delimiters.

In addition I think the complexity is best left in the slicer so the G1 command should indicate distance to move for each extruder drive rather than a total distance and a mixing % This allows for multiple different drive types with varying esteps/mm to be used easily - the slicer decides the volume of each material to extrude based on the diameter input by the user.

for the example give the syntax now looks like this:

M160 S4
G1 X90.6 Y13.8 E2.24:2.24:2.24:15.89
G1 X70.6 E0.0:0.0:0.0:42.4
G1 E42.4:0.0:0.0:0.0
I think that is better, however it subtly changes how the mix ratio is applied, the mix ratio would be constant for the duration of the move. The last line now has no effect.
It would seem more logical to use comma (,) to separate items in a list. Now that distances are used instead of ratios, the M160 seems to be redundant. The printer just extrudes whatever is in the E list.
--Bobc (talk) 16:35, 15 March 2014 (PDT)

Rewriting the Wiki Page to Not Sucktm

Yep, making it easier to read and understand the Gcodes. It might be all the years of writing JavaDocs, or paging through the Arch Wiki, but for a technical wiki page, it sucks at conveying any information efficiently without rereading or questioning. I already did a good chunk of the top of the page (down to Gcode G2 & G3) and the contrast is night and day. It also gives me something to do while I part together my i3 Rework.

--HACKhalo2 (talk) 23:28, 27 December 2014 (PST)

Nice job! Thanks! And good luck with the i3 Rework. :-) --AndrewBCN (talk) 15:26, 28 December 2014 (PST)
I've added firmware compatibility boxes for all gcodes, as it was getting confusing which firmware supports which gcode. A lot needs updating, though, but at least they're there now! --Droftarts (talk) 07:24, 19 January 2015 (PST)
The support boxes are a great idea to get an overview. I made a template from it and colorize them. I also updated many of these ??? with current information, and add some codes that have been missing. --Stefan8410 (talk) 07:59, 3 April 2015 (PDT)

Renumbering unused commands

The following M-commands appear to be not used in any firmware.

M207: Calibrate z axis by detecting z max length 

Does anyone know a firmware that have implemented the commands using these code number?

One or more well-known firmwares already use this code numbers for a different function.

In order to rescue the original function and to avoid a clash, would it be profitable to assign them a new code number? -- Stefan8410 (talk) 08:41, 13 April 2015 (PDT)

How to add GCodes that are supported in the firmware, but only if certain conditions are met at compile-time?

Example: M600 in Repetier. Checking the GitHub source file, I can see that M600 is supported, but only if the condition "FEATURE_CONTROLLER != NO_CONTROLLER && FEATURE_RETRACTION" is met.

Would that be "partial" support? Or simply "yes", because the firmware does support it, but not all hardware does?--Rejutka (talk) 00:28, 20 March 2016 (PDT)

Removal of BFB/Rapman idiom

The BFB/Rapman G-codes are nearly undocumented, this is old stuff, 3D systems closed its consumer site and removed a lot of available documents, so I think it may help readability to remove this idiom from the template. Anyone want to maintain (and so document) it ? PRZ (talk) 12:28, 9 April 2016 (PDT) - removed PRZ (talk) 10:40, 9 May 2016 (PDT)

Adding new and experimental GCodes, not yet incorporated into an official version

I am adding some GCodes to improve the calibration and alignment of my 400mm diameter by 320mm high, four extruder delta machine. I am facing and compensating for the various mechanical build errors, with some success so far. Because I am adding CGodes, I have edited the GCode list to include them, hopefully reserving the G and M codes in the process. If this is not the right procedure, please comment or email me. When this works, I will do another merge with the appropriate branch of the RepRapPro firmware, and then I think the thing to do is make a pull request, although I am new to git and the appropriate etiquette. If there is a FAQ I have missed, I will not be offended by a kind suggestion to go read it.--Foxkid (talk) 19:21, 21 June 2016 (PDT)

Considering addition of named variables to G-Code

I'm finding that it would be helpful to have names for various values that can be referred to in macros and configuration files. My use is for the exact offsets between extruders in my 4-extruder delta machine. I need to use the values both for the G10 commands to define the tools, and in the tfree#.g, tpre#.g, and tpost#.g macros.

I'm tempted to follow the lead of Fanuc and make variables be introduced by the sharp sign ('#') character, but allow them to be strings (reg-ex m/[0-9a-zA-Z_]+/), and perhaps add in Fanuc-style numerical expressions later.

I'm sure this must have been debated before. What is the current best practice?