# How to change the extrusion value (E parameter) in G-code?

Before I ask you my question I want to summarize my problem.

I am trying to build my personal 3D Printer and I can send the controller of my Extruder (Motor) only integer values. Slicer (Cura) produces fractions. I try to interprete these values as RPM. That means for example that I can't send 282.040 RPM (as calculated value), but I can send only 282 RPM.

My problem is that I got the E parameter as integer and decimal form like below:

G1 X534.729 Y195.96 E144.96538
G1 X664.869 Y195.95 E161.48942
G1 X666.538 Y196.042 E161.70166


Is there any way to get the E-parameter only in integer form?

Is there any program or is there any opportunity to set the slicer in order to have that goal?

• There is a difference in units, E value in G-code is length (typically in mm, but can be volumetric also), you are referring to RPM (revolutions per minute). The latter is not a length (or volume), but a speed. You need to explain why the difference is as such. otherwise, no slicer will help you out. – 0scar Jan 29 at 14:16
• After re-thinking I supplemented the answer with suggested approach: alter the firmware to support smaller units. Post-processing sliced G-Code will still be necessary, and I explained how to do it. So, this is straightforward answer on how to achieve integer Ennn values for real printing, with or without help of slicer. (Also some extra explanation about RPM.) I hope you will take many useful information from it. Finally, very much will depend on your hardware, firmware and selected approach. (Deleted previous redundant comment.) – octopus8 Jan 31 at 2:41

## 1 Answer

Yes, it is possible to influence values of the E-parameter, even to make them integers.

I see three possibilities:

• force firmware to support units smaller than mm - suggested approach
• force slicer to produce integer-like values - most of below explanation
• change meaning of E - custom approach, including RPM interpretation

Each of above needs post-processing of the G-Code output. There are some tools available, but required logic would need to be added (programmed). Some are simple scripts and this won't be difficult task. The rest of solution is much more difficult.

By the book, the E value is new coordinate on the E (extruder) on axis, in current units. Unfortunately, the only position units reflected in standard G-Code are millimeters (see G21) or inches (see G20). Therefore using integer values would mean very limited resolution, at least 1 mm of filament pushed at a time. Introducing smaller unit into firmware seems to be most reasonable approach.

# Tools to post-process G-Code files

The G-Code generated by slicer would contain Ennn values as fractions in millimeters (or millimeters). Generated file may be post processed line by line to alter these values. There are many examples of scripts or tools doing similar job.

One example is simple python script metric-gcode-truncator stripping numbers to 4 decimal places. Simple changes to this scirpt could be sufficient in simplest cases.

I found this script listed between other G-Code Utilities. Also, I found source code of grecode, which seem to be much more comprehensive G-Code transformation tool, but with no similar functionality out of the box.

Next improvement would be to use the script as slicer plugin, to streamline the everyday process. Maybe some existing Cura plugin could be a basis or example.

# Support for smaller units in firmware

First task is to select smaller unit (like micrometre, nanometre, or even non-metric abstraction).

Source code of existing firmware must be the supplemented to properly intereprete such values. In Marlin focus should be on parser.h and parser.cpp, following keywords INCH_MODE_SUPPORT, LINEARUNIT_MM and LINEARUNIT_INCH. Respective changes must be also added to configuration files.

Key inspiration in parser seems to be following part:

static inline void set_input_linear_units(const LinearUnit units) {
switch (units) {
default:
case LINEARUNIT_MM:   linear_unit_factor =  1.0f; break;
case LINEARUNIT_INCH: linear_unit_factor = 25.4f; break;
}
volumetric_unit_factor = POW(linear_unit_factor, 3);
}


The main difficuly would be to refine parser and the rest of code to ensure that new units are only used for E movements, not for other axes or G-Code commands related to speed or other settings.

Then, each G-Code file must be post-processed with prepared tool, which will recalculate and alter Ennn values (or others), only for selected G-Code commands (this must relfect). For metric units it could be simple multiplication by 10n (visually it is shifting a decimal point).

Summarizing, possibly the simplest would be to just introduce new unit for all, and re-process G-Code files accodingly changing each value X, Y, Z, E. I cannot advice how such changes would affect F (feedrate), speed and acceleration settings.

# Slicer producing integer values of E parameter

Long story short: decrease steps/mm (firmware/printer), decrease filament diameter (slicer), then Ennn values in G-Code will shoot up and could be rounded to integers without drastical loose of quality. Units for extrusion become then fake (scaled).

Software may not be ready to support adequately low values (configuration, rounding) or high values (calculations). So in practice the values configuration could not by as minimal as wished, which would more or less impact the quality. There are is speed setting trouble, beacuse extrusion speed is correlated with movement speed.

Detailed theoretical explanation and example calculations are below.

### Steps/mm

However this is still useful, because each printing firmware has configurable steps/mm setting (or some analogous constant value). Steps/mm is basic and known characteristic of extruder, representing number of (micro)steps of extruder's stepper motor to push this 1 millimeter of filament (traverse E axis). If this steps/mm constant will be set to 1, then extruder will make only 1 (micro)step for G1 E1. This change could be done in firmware configuraton, temporarily with G-Code M92 E1, or stored to EEPROM.

### Volume

Filament is a long cylinder, and extrusion length is height of short cylinder (segment of whole): $$l= \frac {4 V} {\pi d^2} R$$, where:

• V - volume necessary to pring path, internally calculated by slicer software
• d - diameter of filament configured in slicer
• R - customized extrusion multiplier setting (R) a.k.a. flow rate. (It was introduced for fine tuning, in runtime or when chaniging filaments, to avoid workarounds like manipulating steps/mm or diameter to untrue values. This parameter is not really important for this discusion, included only for completness.)

### Printer configuration

1 mm of filament translates to actual volume of material (mm3). The correct steps/mm is very important, so the rotation of motor (travel along E axis) will really extrude the expected amount. If value of steps/mm configured in printer is reduced, then interpreted G-Code commands will be translated to too short distances (less steps). To ensure the needed volume, either more millimeters would have to be ordered (G1 Ennn) or filament would have to be thicker. Filament is what it is, so only the first choice is possible.

For example, using 1,75 mm filament and having extruder which needs to make 760 steps to push 1 mm (a fact, determined hardware characteristics), then to extrude 1 mm3:

• if printer is set for 760 steps/mm (correctly), then G-Code must contain correct E0.415752 mm for adequately long cylinder being pushed throught the nozzle
• if printer is "misconfigured" for 1 step/mm, then G-Code must contain edaquately scaled value E315.9713 for the same cyllinder to be pushed (760x bigger number). The value is actually an exact number of (micro)steps. And it is big. Decimal part is negligible. It can be safely rounded to integer.

For practical use, the printer's speed settings and limits would need to be also multiplied for extrusion and retraction. Otherwise extruder moves would be slower by scaling factor, with negative side effects of hot filament behaving on its own.

### Right place of scaling

So how to obtain this scaling? Simplest way is to increase flow rate in the printer (e.g. to 760%). This will scale Ennn values form G-Code in runtime. An original G-Code is needed for this, with tiny numbers. So this is not a solution for integers.

Then how to force slicer to produce G-Code with scaled numbers?

### Slicer configuration

Slicer calculates volume required to print some fragment and coverts it to millimeters of filament, basing on configured diameter. So this diameter is also very important. Everything must match. If very small diameter is set in slicer, this will drastically increase length of filament pushed.

For example:

• For 1.75 mm filament, to extrude 1 mm3 volume, slicer will order to push E0.415752 mm.
• After changing configured filament diameter to 0.01 mm, slicer would order to push E12732.4 mm. This is big number. But not even similar to the above needed length E315.9713.

Slicer usually adds speed (feedrate) information to G-Code. So any speed settings and limits for extrusion and retraction would need to be multiplied also in slicer. There are also other settings to modify, like retraction distance.

### Matching equation

Change of diameter must reflect the change of steps/mm. The proportion could be derived from cylinder volume formula. Diameter to configure in slicer is $$d= D \sqrt { \frac L l}$$, where:

• D - real diameter of filament
• L - standard extrusion distance: height of cylinder having some referenced volume and D diameter, if steps/mm reflect actual hardware
• l - scaled extrusion distance: height of cylinder having the same referenced volume, if steps/mm reflect actual printer configuration

Values for calculation need to be determined for some example volume. This was already done. Following previous examples, diameter required in slicer is: $$d= 1.75 \sqrt { \frac {0.415752} {315.9713}} = 0.063479$$. Then still providing 1.75 mm filament to the same extruder, slicer will produce big values like E315.9713, but printer will perform olny one (micro)step for one milimeter in G-Code.

### Remove fractional part

The generated G-Code would still include fractional part in Ennn values. The file should be post processed line by line to remove it. Simple script will do the job. It could be simple metric-gcode-truncator, after changing pattern to ([E][0-9]*)([.][0-9]+) (not tested). An improvement for quality would be to use rouding instead of truncating decimal part.

### Cumulative discrepancies

There is serious disadvantage of such simple post-processing approach. The total of extruded material will vary, depending a bit on rounding approach. The fractional part is lost, so there may be impact on accuracy with over- or under-extrusion here or there. Post-processing could instead collect these rounded fractions and try to equally compensate for it in following moves, to minimize the total aberration.

I believe that the same could happen inside printer's firmware program, when it traverse floating-number distances, but this is only an assumption. Wihout fractional part, firmware will no have data to compensate anything.

### Even more accurate?

Because firmware can accepts fractions below 1 for steps/mm (Marlin would accept 0.01), then theoretically the scale could be even bigger - and so Ennn values. Slicer must support adequately low diameter. (In extreme cases this could trigger unexpected overflows or errors or be blocked by software.) Printer will then multiply E values by fraction (steps/mm). Extruding resolution is still limited to 1 (miro)step. But if firmware acumulate rounded fractional parts in runtime and compensate, then total amount extruded per layer would be more precise.

### Real-live attempt to slice

It was possible to set 0,01 filament diameter in Cura, after tweaking the extruder profile for such very thin filament. Nozzle diameter must be set to real size, becuase it affects many parameters of slicing. The total use of filament in my sample G-Code was >52km. File contains entries like:

G1 X72.976 Y63.428 E2623.66351
G1 X74.498 Y61.523 E2607.85791
G1 F1500 E-608
G0 F1800 X107.344 Y85.452
G1 F1500 E608
G1 F1200 X107.583 Y85.642 E326.54744
G1 X107.988 Y85.938 E536.51282


Estimated print time is >5 days. The F parameter is presumably used also by extruder, then the whole print will still slow down. To make the print really happen, possibly all speed settings in slicer would need to be tweaked (i.e. print speed for walls, top/bottom skin, infill, etc.). Then only hard speed limits in firmware would block rapid movements. Outcome quality will be most likely compromised.

# Custom approaches (own G-Code flavor)

Slicer will always calculate length (travel distance), otherwise it would be against the G-Code standard. At least I did not hear of any slicing software, which would output something else then length for extrusion.

In some own custom firmware value of E parameter could be defined in any own way. For example, the E value could be defined exaclty as number of (micro)steps for extruder's stepper motor, angle of rotation refleced as integer, etc. Distance calculated by slicer would need to be re-calculated in G-Code post processing, to match requirements of this firmware.

Own piece software would be then needed to perform re-calculations (simple or not) and overwrite the original E values. The code could be possibly inspired by some of listed above, but the calculation logic need to match specification from firmware. Possibly this could become own plugin to Cura or other slicer.

## RPM approach (critique of the idea)

An attempt to interprete E value as RPM (rounds per minute) is of no use, until it is synchronized with real speed of printing head movement, i.e. other motors performing movement along owne vectors to print the effective path. It is probably possible to calculate, but sounds like creating own G-Code flavor, which would ignore many other important parameters.

One of them is F parameter defined in several G-Code commands (including G1). It determines movement speed for traversing the path. It may change from move to move, making use of acceleration settings. What is worse then, it is expected to be remembered between commands and used for consecutive printer moves. Therefore focusing on single line of G-Code won't tell the whole plan of slicer, and the sophisticated plan reflected in G-Code file would be only partially executed.

RPM approach could seem interesting, if it could ensure constant speed of extruder. This would be ideal for the pressure control. But it would also come at cost of printing speed, with no accelleration control.

• Supplemented the answer with clear overview and better suggested approach: alter the firmware to support smaller units. – octopus8 Jan 31 at 2:45
• Thank you for your reply. I really spent the last two days reading the information that you supplied. Theoretically, it should work but really I need to understand what you meant with "Each of the above needs post-processing of the G-Code output"?? Should I write a python script for this job or is there already such a script? Hint: Iuse the Cura slicer – Otto_Scho Feb 2 at 7:28
• Yes, I think you should create own logic basing on some existing script. I doubt there is something exactly matching your needs, but maybe close enough. I just found quickly googled ProcessGCode, search there for "Ecoordindates". Personally I did only limited post-processing so far, mostly with existing Cura plugins (injecting extra lines) or manually. Selecting Python could be most future-proof if you think about Cura, because it uses Python engine for plugins. – octopus8 Feb 2 at 7:45
• Otto, I would also like to really thank you for reading my text. I appreciate it a lot, believe me :) As you could see, I started with a backbraking idea of re-scaling E stepper movement, only to propose much simpler change of unit. I suppose the latter is also of your preference. I hope you will get good results with your project. – octopus8 Feb 5 at 4:31