The problem
I received my new Smoothieware capable Azteeg X5 mini board last friday, hoping to make my 3d printing experience much smoother. I started to configure everything and I stumbled on a very odd movement from the motors, something like this:Thinking that this should be a known problem, I started searching for a solution, but surprisingly I found none. The folks at the #smoothieware IRC channel were very helpful, but still we didn't find an explanation to the jerky movement. While talking about it, the topic of the different decay modes of the DRV8825 appeared in the chat. I read about it in the datasheet and decided to give it a try.
I changed the decay mode to "fast decay", the movement now was much smoother, but the motors were making a really horrible and high pitch noise. Looking at the datasheet revealed that the PWM frequency of the driver was 30kHz, not audible even for the finest ear. This was clearly a sign that something was wrong and lower frequency, audible, subharmonics were being generated.
I make a living as an electronic engineer, as such I have to deal with these sort of problems everyday and I have grown to have very little tolerance to these kind of suboptimal behaviors. So I had to find out what was going on, that noise is just pain to my ears!
The culprit
Let's see what we have, the DRV8825 is a stepper driver with some nice microstepping capabilities as the following graph shows on its datasheet:
Nice, I say, but then why is my motor either skipping steps or making the noise of hell? Let's dig deeper.
So there is a "Current regulation" section, which says basically that the output current is regulated in small steps to do the microstepping, as shown in the waveform above. But when reading the details you can see that it is actually doing.... PEAK CURRENT control... oh, no!
Peak current control is known to have the problem of presenting subharmonic oscillation when you require duty cycles of more than 50%. That would explain the noise when I configured the "fast decay" mode. In this case, it would be logical to have subharmonics at 15kHz and 7.5kHz which are audible even for the coarsest ear...
I needed to measure these currents to see what was going on, so I brought home the nice Tek current probes that I use at work.
First measurement, fast decay and subharmonic oscillation
Ok, here is our nice sinewave, or is it not so nice? We said that peak current control could have subharmonic oscillation, which would explain the noise. let's look deeper.
Oooooh, isn't that a nice tipical little subharmonic oscillation? Even more, there are some microsteps that are done continuously at 15kHz instead of 30kHz, like in the next scope capture. No wonder there is noise...
Then, hopefully, in the negative half of the sine wave, it will not oscillate because we have duty cycles less than 50% right?.... WRONG, because it turns out that in the negative part it does valley current control. And guess when does valley current mode control present subharmonic oscillation.... exactly, with duty cycles less than 50%. So it will always be oscillation except for the brief period near the zero crossing where it does something different.
Second measurement, mixed decay and the dreaded blanking time
Avoiding the oscillations in the fast decay mode will be very hard, if not impossible. So I decided to go back to mixed decay mode. Let's see how the current looks like:
AAAAAAGHGH!!! What the hell is that?? pain in my eyes!!
OK, let me explain what is shown in the scope. The yellow and pink traces show the currents of each phase of a motor. And the blue and green traces are the voltages on each terminal of the phase with the yellow current.
As per the datasheet, mixed decay mode is:
This is good, because it minimizes the possibility of subharmonic oscillation that we had in fast decay.
This is good, because it minimizes the possibility of subharmonic oscillation that we had in fast decay.
Well, at least it is clear why the motor doesn't move smoothly. What should be a nice sine wave is actually a square-sine hybrid. The question is why does it step directly from zero to about 600mA of current? Lets zoom into the problematic square region to see what is happening:
There we have, a lonely voltage pulse measuring about 4us. 4us is about 12% of the 33us period of the PWM signal. So that means that we should be getting a voltage of 12% of 12V across the motor phase, which is around 1.4V. My steppers have a resistance of 2ohm aprox. So that would mean a current of 1.4V/2ohm = 700mA... everything seems to match. But then, why is the pulse so wide? So, after a deeper read at the datasheet, I notice the following:
Oooh, that makes total sense. It needs the blanking time to allow the measurement across the shunt to settle after the transition in the H-Bridge.
But we found out what is the problem, in mixed decay mode, the driver cannot do any voltage lower than 12% of the supply voltage. So the small currents needed for the microstepping will not be possible.
Still, we want to use mixed decay mode because it has an interesting way to do fast and slow decay at the same time which reduces the subharmonic oscillation problem, although it still doesn't completely solve it.
Still, we want to use mixed decay mode because it has an interesting way to do fast and slow decay at the same time which reduces the subharmonic oscillation problem, although it still doesn't completely solve it.
So then, the problem is that it cannot effectively do small steps in the rising part of the sine wave because the minimum voltage it can do is 12% of the supply voltage (1.4V in my case) my motors are rated for 3.1V, so 1.4V is half of the nominal voltage, that is a very big minimum step.
The solution, a dog
The conclusion is that this problem will happen to any motor with nominal voltage much lower than the supply, because for those, 12% of the supply will already be a big deal, and achieving small currents will not be possible.
The first try is obvious, let's lower the supply!, the problem is that the minimum supply is 8.2V, so that doesn't quite fix it yet. And also it would have an effect on other parts of the printer, so its not a good solution.
OK, we could add some resistance in series with the motor winding so that the 1.4V produces just about 100mA!
Yes, that could work, but if we do some numbers we'll see that we will have a power loss of around 12W on each resistor (we would need 12ohm resistor in addition to the 2 ohm of the motor to turn 1.4V into 100mA. And at a current of 1Arms that would create 12W per resistor), and we need one per phase, that means six resistors for three motors.... 72W.... oooh thats crazy. No way.
Well, it seems like the minimum 700mA step is fixed, so if we increase the current of the sine wave, 700mA will be less significant, right? Yes, right, but you need to go to very high current to make it neglectible, and that will create heating and other problems, so also not a solution really.
Well, it seems like the minimum 700mA step is fixed, so if we increase the current of the sine wave, 700mA will be less significant, right? Yes, right, but you need to go to very high current to make it neglectible, and that will create heating and other problems, so also not a solution really.
What can we do?, we need to find a way to make small current levels to have smooth microstepping. Not finding a solution, and knowing that every good idea I've had was always while walking the dog, I decided to take her out for a while.
OK, this time it didn't work, but an interesting idea appeared on my head while taking a shower (another great inspiration place) the next day. The idea is the following, the driver has a "pseudo-dead zone" near zero where it is not able to produce low currents, something like this:
You can see that if we ask for anything higher than 12%, "What you get" is "What you want", but if you want something lower than 12%, you will always get 12%. So, we have to avoid getting into that 12% area at all cost.
So, if we had a way to modify the motor so that with a voltage of 1.4V there would be no current flowing, then the driver would be able to generate all the currents because it would always be spitting out more than the minimum voltage. And it turns out that 1.4V is about the voltage drop of two diodes.... Aha!
So then, if we connect this circuit in series with a phase of the motor:
We will be subtracting 1.4V from each side of the sine wave, and the driver would be able to drive low currents. Let's test it!
To see the effect of only one diode, I tried first to add only two diodes in antiparallel, instead of four and compare it with the original phase with no diodes. This is the result:
Well, it looks like we have something! The pink is with no diodes and the yellow with two antiparallel diodes, nice! Lets place the four diodes.
Now the pink one is with the four diodes... sweet! thats exactly what we wanted!
What about losses?, this game of the diodes is similar to the resistors idea we had before and there were a lot of losses there. Let's calculate it with the same 1Arms that we had before. It is simple, lets say we use a 1N5404 diode, which can stand up to 3A. In each diode we have about 0.9V and with 1A current that would make 0.9W losses, such diode has a Rthja of 15K/W, so it will heat 15C above ambient temperature, pretty safe. If you had 3A, it would mean a temperature of around 45C above ambient temperature.
If you want to use a different diode, make sure you calculate the power losses correctly, and in general, be careful when you work with electricity, you don't want to set anything on fire.
To see the effect of only one diode, I tried first to add only two diodes in antiparallel, instead of four and compare it with the original phase with no diodes. This is the result:
Well, it looks like we have something! The pink is with no diodes and the yellow with two antiparallel diodes, nice! Lets place the four diodes.
Now the pink one is with the four diodes... sweet! thats exactly what we wanted!
What about losses?, this game of the diodes is similar to the resistors idea we had before and there were a lot of losses there. Let's calculate it with the same 1Arms that we had before. It is simple, lets say we use a 1N5404 diode, which can stand up to 3A. In each diode we have about 0.9V and with 1A current that would make 0.9W losses, such diode has a Rthja of 15K/W, so it will heat 15C above ambient temperature, pretty safe. If you had 3A, it would mean a temperature of around 45C above ambient temperature.
If you want to use a different diode, make sure you calculate the power losses correctly, and in general, be careful when you work with electricity, you don't want to set anything on fire.
Conclusion
If you have a board with a DRV8825, a motor with lower voltage rating then your supply, and when you move the 3D printer slowly (100 mm/min feedrate) it does not move smoothly. Then you need to put this circuit between your motor and your controller board using 1N5404 to 1N5408 diodes:
You can see the result in the video:
If this fix helps you, leave a comment below, it will be great to know!