1 (edited by Rincewind 2013-03-07 16:14:26)

Topic: Firmware Z wobble compensation

Hello Forum!

I've been working hard on a compensation for the well-known banding problem at a firmware level, and I've made an attempt to write a class that can help with that.

It compensates for uneven layer height generated by a wobble of the Z axis that makes the translation rod movement->bed (extruder) movement nonlinear. Instead of assuming Zactual (the Z coordinate that you get in the bed) == Zrod (the Z coordinate that you multiply by the step size to control the motor), the function assumes that Zaxtual = Zrod + A*sin(w*Zrod + phase). Since the user wants to specify Zactual, we need to invert the formula to obtain Zrod, which is the value that will serve as the input of the motor.

This code is now part of the mlaws repository - If you have a recent version of the firmware (>=February 24 2013) you can directly use this feature. Otherwise just follow the usual instructions for the firmware upgrade and skip to the "Usage" section, or even better check the wiki page: http://www.soliwiki.com/Calibration_of_the_Z_wobble.

Update 1: I've forked lawsy's repository, so if you would like to try the mod, you can download this zip file, install it like you do with the official firmware (howto) and skip all the steps until "Usage" below

Update 3: I included TealVince's modifications (see below) in the github repo and put all the instructions on the soliwiki: http://www.soliwiki.com/Banding and http://www.soliwiki.com/Calibration_of_the_Z_wobble . Please refer to these pages to avoid reading all the posts here below to find the most recent information.

To use it, you will have to place the two files ZWobble.h and ZWobble.cpp in your Marlin folder and do the following changes in your code.

1) In Marlin.pde, at the beginning:

#include "ZWobble.h"

2) In Marlin.pde, after the code:

else if(code_seen('M'))
{
    switch( (int)code_value() ) 
    {

Insert:

DECLARE_ZWOBBLE_MCODES(96, 97)

(this defines the GCodes M96 and M97 as "report ZWobble status" and "set ZWobble status" respectively, you can change the values if you wish)
3) in planner.cpp, at the begining:

#include "ZWobble.h"

4) in planner.cpp, at the beginning of the function plan_buffer_line, ie after:

void plan_buffer_line(const float &x, const float &y, const float &z, const float &e, float feed_rate, const uint8_t &extruder)
{

add:

zwobble.InsertCorrection(z);
Usage:

To use it, set the parameters Amplitude, Period and Phase of the sinusoid function using the M97 code like this:

M97 A<Amplitude_in_mm> W<period_in_mm> P<phase_in_degrees>

This code can be inserted at the beginning of the GCode of the print you are about to do, or can be sent manually (eg from RepetierHost, in the tab "manual control", you can send your own gcode instructions to the printer)

A good value for the period is the thread step of the Z rod (in the Solidoodle2 it is 1.41)
The other two parameters need to be determined experimentally (Amplitude will be <0.1 typically).

In my SD2, this is the result I obtain for A0.03 W1.41 P120 (top uncorrected, bottom corrected, .3mm slicing):

http://img16.imageshack.us/img16/6554/p1280003.jpg

Please keep in mind that this will not fix all your banding problems, it is just the "final touch" when all other sources are removed. I will shortly post something in the general discussion section about what I learned in the last weeks of research and experimentation.

Update 2: I've added a zip file with some test prints that should make the calibration process easy. Download "ZWobble-calibration.zip" and follow the instruction of the README file.

Post's attachments

ZWobble-calibration.zip 203.5 kb, 66 downloads since 2013-02-07 

You don't have the permssions to download the attachments of this post.

2

Re: Firmware Z wobble compensation

Brilliant, well done

3

Re: Firmware Z wobble compensation

Excellent job!  This is very similar to what I had suggested in another post ( http://www.soliforum.com/post/10471/#p10471 ) although I don't have any experience modding the firmware yet and had suggested trying a post-processor for gcode files.  Since the phase is likely to change with any adjustment in bed level, it still might be useful for some to have an option like this in slic3r so it can be easily modified.

Have you tried printing at .1mm?  Most others who have reported banding have really found it noticeable at .1mm, though I'm lucky enough to barely see any even at .1mm, and it's regular but not sinusoidal (a tiny spike at a single layer every 18th inch)

Lastly, I had an idea to make it easier to calibrate either type of compensation.  I was thinking one could create gcode for printing a an extruded octagon, and then having compensation pre-applied at different phase values to the z-height of each face of the model.  The percentage compensation could vary from 0 to .1 along the height of the object, so one could just print it out and look for the best area of the model to determine the proper phase and amplitude values.

I'm not sure if varying the z-level mid-layer would affect printability, or if it's possible to create "universal" gcode that would work for everyone since filament sizes may vary, but it might be worth a try. What do you think?

4

Re: Firmware Z wobble compensation

Hmm, so how again is this working?

It's the morning and I'm a bit tired, but my initial impression is you're taking the angle theta offset from 90 degrees, and multiplying it by the length of the rod, to find the difference between the z it thinks its at and the z it is at when tilted?


I assume my initial impression is wrong because for such a small theta sin(theta)=theta, in all likelyhood, and I doubt much float precision on arduino.   But I see your results are nice! And I'm really impressed by the work.

5

Re: Firmware Z wobble compensation

tealvince wrote:

Excellent job!  This is very similar to what I had suggested in another post ( http://www.soliforum.com/post/10471/#p10471 ) although I don't have any experience modding the firmware yet and had suggested trying a post-processor for gcode files.  Since the phase is likely to change with any adjustment in bed level, it still might be useful for some to have an option like this in slic3r so it can be easily modified.

Ah very nice! I didn't see your post during my research, I apologize for this!

Have you tried printing at .1mm?  Most others who have reported banding have really found it noticeable at .1mm, though I'm lucky enough to barely see any even at .1mm, and it's regular but not sinusoidal (a tiny spike at a single layer every 18th inch)

Yes, i also tried .1 but just small test cubes, not so impressive smile I also noticed the kind of banding that you are describing and found out to be related to the "randomize starting points" feature possibly coupled with XY backlash. Have you tried printing with the feature off?

Lastly, I had an idea to make it easier to calibrate either type of compensation.  I was thinking one could create gcode for printing a an extruded octagon, and then having compensation pre-applied at different phase values to the z-height of each face of the model.  The percentage compensation could vary from 0 to .1 along the height of the object, so one could just print it out and look for the best area of the model to determine the proper phase and amplitude values.

I did in fact use something like that to find the best parameters: I printed a simple cuboid 15x15x50mm3 and inserted a M97 P<phase> command every 5mm or so and then checked for the best option, and then printed again with varying amplitude.

I'm not sure if varying the z-level mid-layer would affect printability, or if it's possible to create "universal" gcode that would work for everyone since filament sizes may vary, but it might be worth a try. What do you think?

6 (edited by Rincewind 2013-01-30 16:26:36)

Re: Firmware Z wobble compensation

Tomek wrote:

Hmm, so how again is this working?

It's the morning and I'm a bit tired, but my initial impression is you're taking the angle theta offset from 90 degrees, and multiplying it by the length of the rod, to find the difference between the z it thinks its at and the z it is at when tilted?

Well kind of I think (not sure what is the theta you are referring to, or what it it supposed to be 90°), but the math is slightly different: what i call Zrod is "the Z where you think the bed is (=the value that is directly proportional to the motor steps)" and Zactual is "the Z where the bed actually is" and I assume that these two are tied by the equation described above (see a plot in attachment, the wobble is exaggerated). In an ideal world of course Zactual == Zrod. When you give a move instruction, you would like to specify Zactual, not Zrod. So when a movement is calculated, before the actual generation of the movement block, the algorithm takes the origin Z and target Z and (numerically) inverts the formula to find out which are the corresponding "rod" values that give you the desired actual Z. Then it calculates the motor steps needed to go from origin to target and it compares the result with the number of steps that would be calculated in the uncorrected case. Finally, it subtracts the difference from the current position so that the movement is actually planned with the number of steps that we want. To give you an idea, the correction turns out to be <=20-30 steps in a typical case, so far above the numerical resolution.

I assume my initial impression is wrong because for such a small theta sin(theta)=theta, in all likelyhood, and I doubt much float precision on arduino.   But I see your results are nice! And I'm really impressed by the work.

Post's attachments

zwobble.png 3.66 kb, 2 downloads since 2013-01-30 

You don't have the permssions to download the attachments of this post.

7 (edited by jefferysanders 2013-01-30 18:26:38)

Re: Firmware Z wobble compensation

Impressive!!! Can you provide a bit better detail as to step 4 please?

8

Re: Firmware Z wobble compensation

Awesome work. Assuming others can get this working, you shopuld put in a pull request to have it merged with the official Marlin.

9

Re: Firmware Z wobble compensation

Your ideas are intriguing to me and I wish to subscribe to your newsletter.

I'm willing to try this out, but I will need a bit more information on the actual steps required to access these files and push them to the printer.  I believe that I should be editting the files that I created via step 2 of this guide with your instructions and upload them by following step3. And then I can activate this function by experimenting with different M97 commands in my start.gcode.

Is that correct and did I miss anything important?

10

Re: Firmware Z wobble compensation

nickythegreek wrote:

Your ideas are intriguing to me and I wish to subscribe to your newsletter.

Do you mean the Solidoodle mailing list? You should check here

I'm willing to try this out, but I will need a bit more information on the actual steps required to access these files and push them to the printer.  I believe that I should be editting the files that I created via step 2 of this guide with your instructions and upload them by following step3. And then I can activate this function by experimenting with different M97 commands in my start.gcode.

Is that correct and did I miss anything important?

That is correct. In the meantime I opened a Github account and forked the repository, so long story short, you can download this zip file and follow the firmware update guide as usual. The link contains the most recent firmware plus my modifications, so you will be able to use M96 and M97 straight away.

11

Re: Firmware Z wobble compensation

jefferysanders wrote:

Impressive!!! Can you provide a bit better detail as to step 4 please?

Thanks! smile I tried to clarify step 4, is it better now?

12 (edited by jefferysanders 2013-01-31 14:28:29)

Re: Firmware Z wobble compensation

I'm positive that will give me plenty to locate the proper location for that insertion, THX!!!  Just noticed the implemented codes section has not been updated to reflect the addition of new M Commands, thought I would let you know so you can add the polish you desire.  Can I correct while printing just by issuing another M97?

13

Re: Firmware Z wobble compensation

Great work Rincewind!  What do you think about generalizing the correction to non-sinusoidal z-axis errors?  Here's my pitch:

For an 18tpi z-axis drive screw, most banding errors should repeat every 1.41mm.  So why not simply have a user step their bed in .1mm increments and measure their actual bed height with a depth gauge for the first 14 steps?  The firmware could then assume a repeating period if 1/18 inch (presumably overrideable) and linearly interpolate between the entered points give nearly perfect correction for any periodic error in z-height.

Not only would this be more flexible than assuming a sine wave, but it would be easier to calibrate if a depth gauge is available.

14

Re: Firmware Z wobble compensation

tealvince wrote:

Great work Rincewind!  What do you think about generalizing the correction to non-sinusoidal z-axis errors?  Here's my pitch:

For an 18tpi z-axis drive screw, most banding errors should repeat every 1.41mm.  So why not simply have a user step their bed in .1mm increments and measure their actual bed height with a depth gauge for the first 14 steps?  The firmware could then assume a repeating period if 1/18 inch (presumably overrideable) and linearly interpolate between the entered points give nearly perfect correction for any periodic error in z-height.

That is very feasible, actually the current implementation already tabulates the sine wave in a lookup table, so it's mostly a matter of providing the right interface. On the other hand, I chose a sine wave because it is what you should get when you have a wobbling of a threaded rod (it is like having an elliptical helix as a thread), and it can be described with few simple parameters.

Not only would this be more flexible than assuming a sine wave, but it would be easier to calibrate if a depth gauge is available.

I have the feeling that doing the measurement that you propose with sufficient accuracy might be trickier than you think. But if you would like to give it a try, I can easily extend the code and have it ready by the beginning of next week.

15 (edited by nickythegreek 2013-02-02 02:32:26)

Re: Firmware Z wobble compensation

You forgot the ; after

DECLARE_ZWOBBLE_MCODES(96, 97)

in your instructions.

Also, if anyone else is trying the manual route, dont forget to save both planner.cpp and Marlin.PDE (once on each tab).  I was having issues uploading until I figured out I didn't save the second file.

16

Re: Firmware Z wobble compensation

tealvince wrote:

Great work Rincewind!  What do you think about generalizing the correction to non-sinusoidal z-axis errors?  Here's my pitch:

For an 18tpi z-axis drive screw, most banding errors should repeat every 1.41mm.  So why not simply have a user step their bed in .1mm increments and measure their actual bed height with a depth gauge for the first 14 steps?  The firmware could then assume a repeating period if 1/18 inch (presumably overrideable) and linearly interpolate between the entered points give nearly perfect correction for any periodic error in z-height.

Not only would this be more flexible than assuming a sine wave, but it would be easier to calibrate if a depth gauge is available.

I wrote the additional code: I tested it yesterday and it seems to work, but I was not able to make reliable measures with my indicator... However, here how it works:

1) Set the period with the same command as before:

M97 W1.41 P0

2) Add sample points with the following syntax

M97 Z<theoretical_z> H<measured_z>

Be sure to measure all the points when compensation is deactivated (you can do so by sending M97 A0)!

If you want to switch back to sinusoidal compensation, give a M97 A<amplitude> command.

You can find the latest code on github: https://github.com/fsantini/solidoodle2-marlin/.

17

Re: Firmware Z wobble compensation

nickythegreek wrote:

You forgot the ; after

DECLARE_ZWOBBLE_MCODES(96, 97)

in your instructions.

It is a macro, so the ; is not needed (but it doesn't harm either)

Also, if anyone else is trying the manual route, dont forget to save both planner.cpp and Marlin.PDE (once on each tab).  I was having issues uploading until I figured out I didn't save the second file.

Thanks for the tip! Have you already tried to print something with the compensation on?

18 (edited by nickythegreek 2013-02-05 17:27:19)

Re: Firmware Z wobble compensation

Rince,

I tried it out but did not get the results that I wanted and got pretty confused on the correct procedure to do some trial-and-error.

I started by sending a manual command in RH with the same info that you used:

A0.03 W1.41 P120

This seemed to increase the thickness on my band.  Which led me to the next question.  When this fix applies itself, does it increase the thin area of the band to be the width of the of the thick section of the buldge or does it decrease the buldge to be the thickness of the thing area?

The above code seemed to be applying the amplitutde adjustment  right on the thicker threads but it was increasing them.   

Can I get an explanation of the steps that I need to fine tune the M97 command?

19

Re: Firmware Z wobble compensation

nickythegreek wrote:

Rince,

I tried it out but did not get the results that I wanted and got pretty confused on the correct procedure to do some trial-and-error.

I started by sending a manual command in RH with the same info that you used:

A0.03 W1.41 P120

This seemed to increase the thickness on my band.  Which led me to the next question.  When this fix applies itself, does it increase the thin area of the band to be the width of the of the thick section of the buldge or does it decrease the buldge to be the thickness of the thing area?

The above code seemed to be applying the amplitutde adjustment  right on the thicker threads but it was increasing them.   

Can I get an explanation of the steps that I need to fine tune the M97 command?

Ok this is a good start actually smile This means that you have the phase of the oscillations wrong. See the attached picture: if you have a compensation that is "in phase" with the wobbling, the wobbling will be enhanced. You should go from the first picture to the last, where the oscillations are out of phase and cancel each other. The phase is measured in degrees, so a phase of 180 is completely opposite with respect to a 0 degree phase. In your case, I would try a value of 300 for the phase (=120+180) in order to reverse the effect that you are obtaining.

I did it like this: I found out the approximate phase that I needed by printing a a few objects (1.5cm cubes, no infill, no randomize starting points) with P=0, P=90, P=180 and I found a good initial estimate for the phase, that is a phase that reduced oscillations instead of increasing them. I found something between 90 and 180, then I sliced a tall test cuboid (1.5cm width, 5cm height) and every 20 layers or so I inserted in the Gcode a command M97 that would change the phase, with increasing steps. So at the beginning I had M97 A0.03 W1.41 P90, then at layer 20 I had M97 P100, at layer 40 I had M97 P110 and so on...  I printed it and found at which height the surface was smoothest, and I found out that the optimal phase value was 120.

Finally I printed another cuboid with fixed phase but changing amplitude from 0.01 to 0.05.

Would it be helpful if I provided the GCode for these test objects so one can just import it in Repetier or Pronterface?

Post's attachments

wobble_compensation.png
wobble_compensation.png 50.37 kb, 3 downloads since 2013-02-05 

You don't have the permssions to download the attachments of this post.

20

Re: Firmware Z wobble compensation

Makes sense, thanks.  Let me try and apply this technique as I think the gcode wont use my filament diameter/extruder multiplier info.

21

Re: Firmware Z wobble compensation

I have been paying attention to this issue and I have noticed that the motor moves around quite a bit where it connects to the thin metal base. Isn't this where the problem lies? The rod seems to be straight but I've never taken it out to check.
Would it help to wedge an insert on each side of the motor in between the rods?
Would it help to somehow stiffen the base, perhaps with some kind of plate?
I'm currently unable to update my bios through the Arduino utility (apparently I have a bad one) so I don't think I can try any of the firmware hacks mentioned above but I will try anything else.

22 (edited by jefferysanders 2013-02-06 00:02:29)

Re: Firmware Z wobble compensation

FatalDischarge wrote:

I have been paying attention to this issue and I have noticed that the motor moves around quite a bit where it connects to the thin metal base.

It is for some, but not all.  I would contact SD support if your unit does this as you likely have a bent rod.

Rincewind wrote:

Would it be helpful if I provided the GCode for these test objects so one can just import it in Repetier or Pronterface?

  I could use it for sure! I didn't get it to work properly either, my wobble marks are so faint from mechanical fixes it was hard to see the effects with it on, but I do recall seeing fat layers...so maybe I should try what you suggested to Nicky.

23

Re: Firmware Z wobble compensation

Rincewind wrote:

I wrote the additional code: I tested it yesterday and it seems to work, but I was not able to make reliable measures with my indicator... However, here how it works:

Excellent!  Thanks for adding this.  I haven't tried updating the firmware before, so I apologize if there is a delay before I can get back to you on how this works.  I'll try after I finish the project I am currently working on. 

Regarding taking measurements, any idea why the depth indicator doesn't work?  Since we only need to estimate the nonlinearity in the bed movement, I'm thinking I'll try to measure it by bouncing a laser off a small mirror suspended between the bed and a stationary object.

24

Re: Firmware Z wobble compensation

tealvince wrote:
Rincewind wrote:

I wrote the additional code: I tested it yesterday and it seems to work, but I was not able to make reliable measures with my indicator... However, here how it works:

Excellent!  Thanks for adding this.  I haven't tried updating the firmware before, so I apologize if there is a delay before I can get back to you on how this works.  I'll try after I finish the project I am currently working on. 

Regarding taking measurements, any idea why the depth indicator doesn't work?  Since we only need to estimate the nonlinearity in the bed movement, I'm thinking I'll try to measure it by bouncing a laser off a small mirror suspended between the bed and a stationary object.

Thank you for giving it a try!

The depth indicator should work in principle, but I couldn't get a reliable reading because of backlashes, mostly given to the fact that I don't manage to attach it firmly enough to the extruder, so the gauge ends up wobbling more than the bed! But probably it's just me.

25

Re: Firmware Z wobble compensation

Would these corrections be speed-dependent?  That is, would you have to change the corrections if you changed your print speed significantly?

I know of one (non-SD) printer where most of the printing noise disappears as the printing speed increases.  This implies that there is a lot of mechanical resonances (on that printer).