stepper noise and pid tuning

513 views
Skip to first unread message

cool...@gmail.com

unread,
Jan 23, 2017, 9:19:56 AM1/23/17
to Mechaduino
Hello all,

I just got 2 new mechaduino's and I must say that they are amazing! Never had I thought that a stepper could be used as a 2 phase servo.

One thing that I wanted to mention and I am open to suggestions,

When using the mechaduino firmware PID loop (which i tuned and I am somewhat happy with) I noticed that low speed moves are nearly silent. In fact overall the motors are very quiet compared to standard stepsticks.

What I thought was odd is that when using the NZS firmware from Trampas in simple PID loop, the same move speeds are somewhat noisy. The feedback is responsive, but noisy. I supposed I could do more tuning in sPID, but is that going to help the noise or do I need to switch the controlMode to 3 (current sensing PID)?

Also, the mechaduino firmware has Phase Advance, this allows me to move the motor at somewhat faster speeds than without it. Is the NZS firmware going to get PA?

Another thing, when I power up the mechaduino with the mechaduino firmware the motors jump violently when switching to closed loop mode every time. The NZS doesn't do that. Is there a reason why?

Thanks everyone!


Trampas Stern

unread,
Jan 23, 2017, 4:23:58 PM1/23/17
to Mechaduino
The sPID in the NZS is a bit different than the pPID (positional PID) which is what Mechaduino uses. The sPID should work out of the box with most systems without tuning, but at the cost of noise and a bit more heat. If you want the best noise and heat you can enable and tune the pPID on the NZS which is like the PID in the Mechaduino.  However for people who want a quick fix for missed steps they can install the NZS without tuning and it will work out of the box for most applications using sPID. See http://misfittech.net/2016/11/19/nzs-control-loop-example/

The noise on the sPID is based on the current settings, the lower you set the hold current the less noise you will have when not moving. While the maximum current setting controls the power of the move and hence the noise when moving. 

My dream is to have an automatic tuning for the pPID, however I have not gotten there in the firmware yet. I know Kai has done some relay tuning code for Mechaduino, however I have not got it working good enough to release with the NZS firmware yet.  Again one test I do is the vise grips on the motor shaft. This test is tough on a positional PID loop as the load is not static, hence if you tune for case where vise grips are horizontal it may oscillate when vise grips are vertical or vise verse. However the sPID works for this case. Again not every PID is perfect for every application, hence NZS allows you to chose which one you want. 

Unless the Mechaduino firmware has changed it did not have phase advancement. I was working on phase advancement, and did a video with motor running in vPID mode at
2,000RPMs https://www.youtube.com/watch?v=InT7OON9i94.  The phase advancement is easy enough to do, however most machines don't need that kind of speed, in fact just having 1.8 degrees movement 6,000 times a second, limits the speed to 1800RPMs. 

The NZS code does a few more error checks and handles things a bit better Mechaduino firmware as you might have found. This is part of the reason the NZS does not jump when feedback is enabled. I am not even sure if the Mechaduino firmware has the ability to run "open loop" like the NZS can. 

However the NZS stepper firmware on power up will read the encoder and from this set the current position. For example if motor is 180 degrees on power up it will assume this is the start for all future operations, the last I looked at Mechaduino I think it always assume you start at zero, so if motor is at 180 degrees it will cause motor to jump to zero when power is applied. 

There are a few fixes in the NZS hardware as well as compared to Mechaduino. 





cool...@gmail.com

unread,
Jan 23, 2017, 7:02:43 PM1/23/17
to Mechaduino
Hi Trampas,

Thanks for the response!

I just looked at the firmware code for the mechaduino on github,

Line 40:

volatile float PA = aps; // Phase advance...aps = 1.8 for 200 steps per rev, 0.9 for 400

I see that adjusting this allowed me to get up to 200mm/s which for my size machine is just fast enough since it is 750mm X 750mm X 500mm. 

I do really like the NZS firmware more than the mechaduino firmware, especially the eprom storage option rather than downloading the firnware everytime to store a change.

I need to do more tuning in the pPID loop since sPID is more noisy than I want. Do you have any starting parameters other than Kp 1.0?

The motors are nema 17, 76oz-in, 5mm shaft, 4.2Volt 2.8Ohm biopolar steppers.

Thanks Trampas,
Anthony

Kai Wolter

unread,
Jan 24, 2017, 3:34:09 AM1/24/17
to Mechaduino
Hi Trampas,

you could use the autotune from my firmware and just run it every 10 degree or something like that and then interpolate between the values you get. With that you could get a PID loop that compensates for the different load at different angles.

One PID loop isn't going to work well for that usecase.

- Kai

Trampas Stern

unread,
Jan 24, 2017, 7:13:05 AM1/24/17
to Mechaduino
Kai, 

I was thinking about that, aka "gain scheduling" based on position. However right now I am focused on getting the NEMA23 hardware completed.  

What my ideal would be is a learning system, which learns the PID pole positions verses location over time and dynamically updates them. This way as you run machine it just gets better, and at any point you can graph your load verse position. 
I had originally envisioned the NZS running in open loop when first installed and dynamically calibrating the encoder and the PID. Hence you just install board and let it do the rest... 

Anthony, 

There are lots of methods of tuning the pPID, try starting by increasing Kp until machine oscillates then dropping Kp in half then increase Ki until steady state error is acceptable, then increase Kd for stability.  

After I get the NEMA 23 hardware/firmware running I will work on improving the PID tuning. 

The PA term in Mechaduino is the amount to advance the phase for each step in control loop, and is the same for the NZS.  This phase advancement should be the motor step size and never change. If you make it larger it is really bad as it can make motor run backwards. 

The phase advancement I was looking at was predicting the phase of the motor based on the machine velocity, so for example if you are running motor at 900RPM and it is 1.8 degree motor, with a control loop update rate of 6kHz, then ever control update step the control loop is currently trying to run the following equation phase(t)=phase(t-1)+phaseUpdate().   where phaseUpdate() is the PA term or the desired new phase location. However due the velocity of the motor the equation should be phase(t)=phase(t-1) +velocity+phaseUpdate().. That is if motor is running at 900rpm at time t, the phase(t)=phase(t-1) + 900/60*360/6000 +  phaseUpdate() = phase(t-1) + 0.9 +  phaseUpdate().  
This phase prediction of motor phase location based on the velocity which will allow motor to run much smoother at high RPMs, above around 900RPM on a 1.8 degree motor, or ~450RPM on a 0.9 degree.   However there is more to running the motor at such high speeds than just this...  That is the time it takes to read a step input comes into play. On the NZS the current firmware limits the step pin changing to around 50kHz, this could be increased by using  a timer/counter to count steps. However even at 50kHz, with a 1.8 degree motor and 16x microstepping this is still over 900RPM. 

If you have a 18 tooth 2mm pulley on your motor 900RPM is 540mm/sec. 

Trampas

cool...@gmail.com

unread,
Jan 24, 2017, 12:02:08 PM1/24/17
to Mechaduino
540mm/sec sounds excellent. I think that is a number based on a cartesian coordinate system. The machine I am running is a corexy design which based on this theory: http://corexy.com/theory.html requires double the pulses to move at the same rate as cartesian. That would explain why I am only getting ~200mm/sec. I know ramps (which is the board im using) is limited to ~500mm/sec with the latest Marlin firmware. (All GT2 20 tooth, stepping at 16x)

I have switched to your firmware and did the pPID tuning last night and I have it really quiet at all rpm ranges. My settings are Kp 4.00, Ki .001, Kd 10.00 and it runs like a sewing machine.

In reference to Kai's firmware, I did try it with the autotune pid but the settings didn't work the same probably do to the loop rate on the NZS being 6K and Kai's being different. I suppose I could set Kai's loop rate at 6K and try it again, but Im pretty happy with the numbers I used.

As far as the mechaduino's Phase Advance, I thought it was more dynamic that what you explained. I think adding time to the equation would at least give it a little extra rpm but until it's released I won't know.

Anthony
Message has been deleted

Kai Wolter

unread,
Jan 24, 2017, 4:00:30 PM1/24/17
to Mechaduino
Hi Trampas,

I know that feeling (too much to do all at the same time). I've implemented the phase advancements you mentioned (very rough but it works very well even now)
The PA is 0.9 everytime and will be increased based on the desired velocity. It makes the motors run very smooth and also fast. I can get up to 400 mm/s with my machine without a problem or losing position. (higher isn't possible due to my control board right now)

@ Anthony

you can use my PID values but have to recalculate them to run with the firmware von Trampas (they depend on the loop frequency as you mentioned)
Kp would be the same
Ki = Ki_myversion * f_myversion/ f_trampas
Kd = Kd_myversion * f_trampas / f_myversion

I think trampas uses a higher resolution for the analogWrite, I don't know if this makes much difference for the setting they should be roughly 4 times higher.

- Kai

Trampas Stern

unread,
Jan 25, 2017, 8:55:15 AM1/25/17
to Mechaduino
The scaling will be different on my firmware than the Mechaduino. 

The Mechaduino uses floating point math, while I use fixed point math in the control loop. I did fixed point math as that I have learned, the painful way, that floating point math can be time bomb. Specifically, due to the design of floating point the numerical accuracy of a floating point number gets worse as number gets larger.  So basically if you have the following lines of code:

float deg;

deg=0.1125*step_count;

Where deg is degrees of rotation, ie 360 degrees is one rotation, then after 800 rotations you have up to +/- 0.01 degree error from using floating point after 1500 rotations it is +/-0.025 degrees, see http://misfittech.net/2017/01/12/fixed-point-verse-floating-point-math/
Keep in mind this error is due to floating point representation and can not be compensated for, adjust or removed it will always be there, and it is not consistent. That is for one step_count the error will be zero but add one to the step_count and the error becomes large, then add one again and the error is vastly different. Again this is the nature of floating point and can be reduced by using double precision or you have to go to fix point as I did. 

I have gone through the code and done my best to implement the code in fixed point such that the error does not accumulate.  However for most 3D printers the floating point inaccuracy is not going to be a problem as you may never have 800 rotations on the motor. 

Implementing the code in fixed point is harder than it looks, that is you have to take care of rounding and such manually to make sure everything is correct, as such I have done my best to get it right but might still have some errors. 

So where the Mechaduino uses floating point math for the PID loop I have changed things such that all measurements of angle are 16bits per rotation, that is 360 degrees is = 2^16 =65536.  Hence when you do the math everything is scaled very different and I have not calculated the scaling factor from the Mechaduino to the NZS on the control loop.  

Additionally as Kai mentioned I have used higher resolution for analogWrite() than Mechaduino did  in order to try and make sure I can control the motor to same error limits as the encoder measurement provides.   That is if the encoder measurement  is +/-0.05 degrees but you control motor only to +/-0.1 degrees it does not provide best results as possible. 

Trampas





cool...@gmail.com

unread,
Jan 25, 2017, 12:25:05 PM1/25/17
to Mechaduino
Hi Trampas,

I agree with fixed point myself as I work in the industry (for the last 15 years). I have seen firmwares that have tried using floating point without enough precision and strange anomalies have occurred due to rounding errors. I know people that have spent their entire careers designing programs to use fixed point rather than floating point because the processor requires fewer clock cycles to compute the variances of things like PID loops.

I can say at this point with my large printer that things are looking good. The motors are stable (while not extremely fast) and usable. The print quality is good, even though I can feel slight variances in the motor shaft when sitting idle from the PID loop pushing the magnetic field back an fourth ever so slightly to maintain position.

The motor movements are very smooth and quiet.

I am going to put a local 5Volt supply on the board though as I don't see the need to connect the 5V to the ramps board. The grounds will be common so there shouldn't be any ground loops. Is there any reason that I shouldn't do this? 

The 5v supply is of the typical variety (lm7805) and since the current draw is low, the regulator shouldn't get too hot when considering that 7805's are only 40% efficient. I will use the motor power input (12v) coming from a SMPS into the regulator to produce the 5v.

Trampas, is there anything you would like me to test to help progress going forward?

Thanks!
-Anthony

Trampas Stern

unread,
Jan 25, 2017, 1:27:11 PM1/25/17
to Mechaduino
The 7805 might get a bit warm, but should be fine. You could also use one of these: http://www.mouser.com/ProductDetail/RECOM-Power/R-78E50-10/?qs=T0XSgvH75d4EsZCU9I5HVA%3D%3D

The small motor movements might be fixed by increasing the Ki term such that it integrates the error more. 

Trampas

Trampas Stern

unread,
Jan 25, 2017, 2:01:26 PM1/25/17
to Mechaduino
I will add option to turn on phase advancement/prediction in next firmware build. 

Trampas

cool...@gmail.com

unread,
Jan 25, 2017, 2:06:23 PM1/25/17
to Mechaduino
Excellent, I can see myself using this more and more in the future. I build 3d printers and home brew cnc's as a side job when Im not working. I have a vertical mill that would benefit from an upgrade as the vertical column is very heavy (cast iron). I see you have a nema 23 version of this coming out soon. Once that happens it's game on.

In the mean time I'm going to enjoy the silence, precision and feedback of my large format printer!

Again, if there is anything I can do to contribute please let me know.

--Anthony
Reply all
Reply to author
Forward
0 new messages