Linear advance and M900

edited November 2017 in Repetier-Firmware
I've been trying to experiment with using linear advance. The new Prusa firmware and Marlin apparently make good use of it and people are reporting higher speeds with similar quality.

It's been difficult to find much documentation on how linear advance has been implemented in Repetier. Does it support the M900 command to adjust the K factor value on the fly? Or do you have to recompile the firmware each time you want to make an adjustment or switch filament types?

How do advance and quadratic advance interact? What are sane values for each? 

Given that linear advance appears to be gaining traction elsewhere, perhaps it's time to flesh out the implementation for repetier?


  • edited November 2017
    I just discovered the M233 gcode, which doesn't appear in the gcode wiki. The feature is obviously obscure.

    No matter what value I use, the extruder begins to reverse itself shortly after the start of the print.
  • You can set values permaently in eeprom editor or temporary with M233, M900 is currently not supported.

    Try only using linear advance. That seems to match much better. Make sure to modify L parameter (whcih pruse names K, but K is quadratic term here). K is very sensitive and already smaller values of 0.x have big impact while L can be 30-50 without problems. K=50 will make a retract as that is the compensation. Bigger compensation can lead to retracts on higher speeds.
  • I'll have to do some more testing. Thanks for the info. If I can get it working well maybe I'll write up a tutorial to make it more accessible. 
  • Would be great. I also think I will recheck handling compared to marlin. Especially to make sure it doe snot use advance during retracts. Have already had some corrections here in dev version. Maybe even add M900 for compatibility, but can not say exactly when I find the time.
  • edited December 2017
    I've been completely unable to make it work as expected. The extruder always reverses at some point no matter the value selected with M233 Y0 to M233 Y50. Even with a M233 Y1 value the extruder will reverse after a few seconds and eventually will return to moving forward. 

    I modified a M900 gcode file to test the various values but it always retracts and then when it does start to go forward there is nothing in the nozzle to extrude.

    I only have advance enabled in the firmware. Quadratic is disabled. M233 only echoes back the Y value for L.

    Here is the gcode file I am testing with. Even if I remove the M233 commands and manually set it to a value before a print any value above 0 will reverse the extruder.

    M83  ; extruder relative mode
    M104 S210 ; set extruder temp
    M140 S55 ; set bed temp
    M190 S55 ; wait for bed temp
    M109 S210 ; wait for extruder temp
    M233 Y0 ;set advance to 0 to start
    G28 W ; home all without mesh bed level
    G80 ; mesh bed leveling
    G1 Y3.0 F1000.0 ; go outside print area
    G1 X60.0 E9.0  F1000.0 ; intro line
    G1 X100.0 E12.5  F1000.0 ; intro line
    G21 ; set units to millimeters
    G90 ; use absolute coordinates
    M83 ; use relative distances for extrusion
    G1 Z0.200 F200.000
    M204 S500
    ;20mm/s = F1200
    ;70mm/s = F4200
    ;120mm/s = F7200
    G1 E-0.80000 F2100.00000
    G1 X10 Y10 F7200.000
    G1 E0.80000 F2100.00000
    M233 Y0
    G1 X10 Y20 E0.37418 F1200 ;Prime, travel to first testline
    G1 X30 Y20 E0.74835 F1200 ;Slow part
    G1 X60 Y20 E1.12253 F4200 ;Accelerate - cruise - decelerate
    G1 X80 Y20 E0.74835 F1200 ;Slow part
    M233 Y5
    G1 X80 Y30 E0.37418 F1200 ;Travel to next testline
    G1 X60 Y30 E0.74835 F1200 ;Slow part
    G1 X30 Y30 E1.12253 F4200 ;Accelerate - cruise - decelerate
    G1 X10 Y30 E0.74835 F1200 ;Slow part
    M233 Y10
    G1 X10 Y40 E0.37418 F1200 ;Travel to next testline
    G1 X30 Y40 E0.74835 F1200 ;Slow part
    G1 X60 Y40 E1.12253 F4200 ;Accelerate - cruise - decelerate
    G1 X80 Y40 E0.74835 F1200 ;Slow part
    M233 Y15
    G1 X80 Y50 E0.37418 F1200 ;Travel to next testline
    G1 X60 Y50 E0.74835 F1200 ;Slow part
    G1 X30 Y50 E1.12253 F4200 ;Accelerate - cruise - decelerate
    G1 X10 Y50 E0.74835 F1200 ;Slow part
    M233 Y20
    G1 X10 Y60 E0.37418 F1200 ;Travel to next testline
    G1 X30 Y60 E0.74835 F1200 ;Slow part
    G1 X60 Y60 E1.12253 F4200 ;Accelerate - cruise - decelerate
    G1 X80 Y60 E0.74835 F1200 ;Slow part
    M233 Y25
    G1 X80 Y70 E0.37418 F1200 ;Travel to next testline
    G1 X60 Y70 E0.74835 F1200 ;Slow part
    G1 X30 Y70 E1.12253 F4200 ;Accelerate - cruise - decelerate
    G1 X10 Y70 E0.74835 F1200 ;Slow part
    M233 Y30
    G1 X10 Y80 E0.37418 F1200 ;Travel to next testline
    G1 X30 Y80 E0.74835 F1200 ;Slow part
    G1 X60 Y80 E1.12253 F4200 ;Accelerate - cruise - decelerate
    G1 X80 Y80 E0.74835 F1200 ;Slow part
    M233 Y35
    G1 X80 Y90 E0.37418 F1200 ;Travel to next testline
    G1 X60 Y90 E0.74835 F1200 ;Slow part
    G1 X30 Y90 E1.12253 F4200 ;Accelerate - cruise - decelerate
    G1 X10 Y90 E0.74835 F1200 ;Slow part
    M233 Y40
    G1 X10 Y100 E0.37418 F1200 ;Travel to next testline
    G1 X30 Y100 E0.74835 F1200 ;Slow part
    G1 X60 Y100 E1.12253 F4200 ;Accelerate - cruise - decelerate
    G1 X80 Y100 E0.74835 F1200 ;Slow part
    M233 Y45
    G1 X80 Y110 E0.37418 F1200 ;Travel to next testline
    G1 X60 Y110 E0.74835 F1200 ;Slow part
    G1 X30 Y110 E1.12253 F4200 ;Accelerate - cruise - decelerate
    G1 X10 Y110 E0.74835 F1200 ;Slow part
    G1 E-0.80000 F2100.00000
    G4 ; wait
    M104 S0 ; turn off temperature
    M140 S0 ; turn off heatbed
    M107 ; turn off fan
    G91; relative cooridantes
    G1 Z1 F200;
    G90; set absolute coordinates
    G1 X0 Y170 F5000; home X axis
    M84 ; disable motors

  • Did you test with recent 1.0? Did the same test and could see an improvement until it got worse again with bigger y values. Do not think it reversed on slowdown, but that also depends on acceleration. The higher your acceleration the faster it needs to reverse. After all it needs to undo extra extrusion on the deceleration part
  • edited December 2017
    Yes I've been using the Dev 1.0 built fresh from here:

    Acceleration is 800, which I thought was pretty reasonable.

    My entire configuration.h file can be seen here:

    It was only ever able to deposit filament on the first two segments before reversing and the part of the segments at high speed were only small dribbles.

    Is 120mm/s simply way too fast for my printer setup perhaps? Next chance I get I will try with speeds closer to what I actually print with. Usually 60mm/s. Mind you, if I left M233 Y0 the file would at least successfully print, though the blobbing and over-extruding at the rapid parts was pretty bad as you'd imagine.
  • 800 is in deed not high for acceleration. And fats parts are 70mm/s which is also ok. When I get the time I test with your script instead of mine I created with marlin advance tool and see how it works.
  • Ok tested your code and worked pretty well. Acceleration 1100 and I got a complete zigzag line. Always extruding forwards.

    M232 returned

    11:12:54.869 : linear steps:17 quadratic steps:0, speed=2.62

    meaning at maximum it advanced 17 steps at resolution 147 steps per mm = 0.12mm. That is ok as it is a direct extruder. For bowden you would need much bigger L values and get the risk of reversal.
  • What could be causing the behaviour I'm seeing?
  • Plase try M232 to reset max counter, then run code and M232 again. Then you know speed (should be the same) and linear steps for your system and also check your steps per mm for comparison.

    Do you have automatic retract enabled? I have none enabled.
  • Automatic retract is disabled.

    I wasn't aware of the M232 command before. I should add it to the test file.

    While looking up the M232 command I found this: I'll just leave that there for posterity.

    It will be about a week before I get to test anything again, but I will report back once I have.

    Thanks for your time.
  • I used M232 and reran the file and it printed properly this time. The extruder did not reverse even up to M233 Y50.

    I'm going to test a print now with M233 Y30 which looked to have the best line quality.

    Test print failed. The lines were very thin and eventually the extruder reversed. I canceled the print after the first layer and ran M232 and M233 in the terminal.
    Send: N679 M233*41Recv: ok 679Recv: linear L:30.00[...]
    Send: N680 M232*46Recv: ok 680Recv:  linear steps:65, speed=1.31
    Reran the test print with M233 Y15 and same thing happens. Extruder is slow and eventually reverses itself.
    Send: N876 M233*40Recv: ok 876Recv: linear L:15.00[...]
    Send: N877 M232*40Recv: ok 877Recv:  linear steps:32, speed=1.31
    Another thing I have noticed is that with any L factor set the extrusion rate from a manual extrusion, say through Octoprint to prime the nozzle, occurs very slowly.
  • Strange. Here is the advance calculation:


        if(!isXYZMove() || !isEPositiveMove()) {


            advanceRate = 0; // No head move or E move only or sucking filament back

            advanceFull = 0;


            advanceL = 0;

        } else {

            float advlin = fabs(speedE) * Extruder::current->advanceL * 0.001 * Printer::axisStepsPerMM[E_AXIS];

            advanceL = (uint16_t)((65536L * advlin) / vMax); //advanceLscaled = (65536*vE*k2)/vMax


            advanceFull = 65536 * Extruder::current->advanceK * speedE * speedE; // Steps*65536 at full speed

            long steps = (HAL::U16SquaredToU32(vMax)) / (accelerationPrim << 1); // v^2/(2*a) = steps needed to accelerate from 0-vMax

            advanceRate = advanceFull / steps;

            if((advanceFull >> 16) > maxadv) {

                maxadv = (advanceFull >> 16);

                maxadvspeed = fabs(speedE);



            if(advlin > maxadv2) {

                maxadv2 = advlin;

                maxadvspeed = fabs(speedE);




    You see that retracts and other pure e moves have advanceL computed as 0 so advance has no effect here.

    In updateAdvanceSteps you see

            int tred = HAL::mulu6xu16shift16(v, advanceL);


            Printer::extruderStepsNeeded += tred - Printer::advanceStepsSet;

            if(tred > 0 && Printer::advanceStepsSet <= 0)

                Printer::extruderStepsNeeded += (Extruder::current->advanceBacklash << 1);

            else if(tred < 0 && Printer::advanceStepsSet >= 0)

                Printer::extruderStepsNeeded -= (Extruder::current->advanceBacklash << 1);

            Printer::advanceStepsSet = tred;


    for linear solution. So the added advance is always positive. Only way to get a reverse is if you decelerate so fast that advance reduces faster then E would extrude to gcode logic causing a reverse. But that would then happen on every move not sometimes.

    When advance is enabled, E is not handled in the stepper interrupt but in a extra interrupt for E and that has a limited frequency. What is your extruder resolution and what speed is slow for you? What board are you using. Maybe this gives some explanations. I mean if normal extrusion is too slow it could mean it can not follow advance as well causing unhandled extruderStepsNeeded from delay that could result in reversals.

  • edited January 2018
    Arduino ATMEGA. PICA shield. Extruder stepper is 0.9 degrees, on a Titan V6, DRV8825 with 32 microsteps. This leads to a fairly high e steps per mm of 1800. Could that be saturating the E interrupt?
  • Sure that is an issue. Extruder interrupt is limited to 15000 hz I think, so that would mean max. 8.3mm/s whcih is at least slow for retraction and for advance it might also be too slow. Explains what you experience I think.

    In V2 I will add advance in normal stepper interrupt handling, so I think there it will improve a bit, but the atmega is of course no help with it's low max. stepper frequency. 1800 steps/mm is simply total overkill. I have 147steps per mm, I think 300-500 would be ideal resolution. So if you can reduce microstepping by factor 4 you have 450 and Emax is up to 33mm/s.
  • I'll give 8 microsteps a try. I do quite like the quiet operation of 32 though. 

    Would upgrading to an Adruino Due solve the frequency limit automatically? It may be time to leave 8 bit behind.
  • Yes, on due based boards that timer works with 60khz so ca. 4 times faster. So if it works with 8 microsteps it will also work on due with 32.
  • edited January 2018
    I'll look into it. I use the PICA board instead of ramps which works great but I'm not sure if I can make it work with a 3.3v Due controller. Might be stuck for a while.

    Thanks for all your help figuring this out. I get great prints right now as it is but was interested in advance. Repetier dev 1.0 had been great.
  • I think I may try Klipper to side step the step rate limits.
  • I'm also working on V2 where I can remove this limit. Will add linear advance in normal segment computation so these are added in normal stepper interrupt. Should be much smoother. But is not included at the moment.

Sign In or Register to comment.