Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Stepper Motor control - Bug???
Airic, I've moved onto testing the motor control. All connected up and it works, except that I noted some strange behaviour when playing with various ramp and steps configurations. I'm now wondering if there is possibly a bug - I have been looking at the code but it's not entirely clear whats happening in there. It will take me some time to work out. But if I explain behaviour:

- If Ramp Steps are less than or equal to half of the Motor Steps all works well. To illustrate - Ramp Steps were initially set to 400. As long as Motor Steps are no greater than 800 (half a turn in this case) the motor starts up and stops after the prerequisite number of motor steps. I've currently got Ramp Steps set to 1000 and Motor Steps at 1600. The motor is happily doing 1 revolution each step-shoot cycle - nice and smooth throughout and accurate.

- However, if Motor Steps are more than twice Ramp Steps, strange behaviour. Motor ramps up for the pre-requisite number of Ramp Steps and then buzzes (stalls?) for a very short period and then starts moving again for the ramp down steps. So if I leave Ramp Steps at 1000 and set Motor Steps to 3200 I get a movement for about 1000, buzz, movement for another 1000. Total movement of one and a bit turns;not 2 expected from Motor Steps value.

- It seems that the Ramp Steps is the governing factor. If I set Ramp Sets to shorter numbers (in fact all the way to 0) same behaviour and movement of about twice the Ramp Steps value irrespective of the Motor Steps value.

Seems a bit strange to find a (possible) bug here at this length of time distance but I just wonder if most users go for smooth configurations of long ramps by default but relatively short numbers of steps! I have been using relatively large Motor Steps just to see how it all worked.

(If it's not a bug but something I have done or misunderstood, my apologies in advance.)

I think I've tracked down the issue.  I spent a fait bit of time understanding the motor control routines (set up, ramping calcs etc) and then finally got to the motor phase function itself that looks deceptively straightforward.  However, I think my problem is in there.

It's not a code error as such but related to the doMotorPhase function activity of making one step at a time.  In the original code there is a 5 microsecond delay after setting High but NO delay after setting LOW (unless in the ramp phases).  For me, this seems to cause an issue because it seems that too many HIGH signals can be sent in very quick succession.  This seems to have the effect of many/most of the steps not actually getting performed at the motor.  I kludged up the code a bit as below:

   // Move stepper one pulse using the delay just calculated
   digitalWrite(MOTOR_STEP_PIN, HIGH);
   digitalWrite(MOTOR_STEP_PIN, LOW);
   // RB: Put in a minimum delay on LOW so as not to confuse motor with too frequent steps!
   // RB: And compensate calculated step delay by subtracting that min delay above!
   if (step_delay > 75) delayMicroseconds(step_delay - 75);
   step_count ++;

Not so elegant as I've just hard coded that min delay value but you get the picture!

This now works fine with a good smooth ramp up, smooth and complete action through the max speed phase and a good ramp down.  75 microseconds was found purely by trial and error.  50 prove too small, 60 a bit choppy and 100 was good always.  75 seemed as good as 100.  

I wonder if this required delay time is a function of the time that it takes the motor to physically move a step and that if it receives a step pulse while in progress of moving that it somehow ignores / stutters on it.  This is purely speculation on my part but I raise it because I was a little surprised with how long that delay had to be (I started at 5 then 10 microseconds while trying to figure this out).  The order of 15 times seems to be more physical than electronic!

You will also notice that I put in a min delay of 75 in all cases; even if the calculated step delay was itself < 75.  Reason for this was that I still got a slightly stutters on performance on the ramp phases without this.  I'd also noticed that in the original code with ramps up/down but no max speed phase (e.g. Motor Steps 800, Ramp 400) the motor spindle tended to slightly under rotate on the expected half turn.  (i.e. over a largeish number of  cycles the motor spindle would gradually but noticeably recess a little).  In retrospect, I suspect that some of the small gap (e.g. <75 microsecond) delay steps were being lost with the result that the full 800 would not get actuated by the motor.

For info I'm testing with a NEMA 17 1.7A motor which I realise is a bit higher than the 750mA driver but it was all I could find quickly and fits my track (when I get around to moving the setup off the 'test bench'). Perhaps with a more powerful driver or smaller motor the effect is less obvious as the motor might step faster.

I now have this part working nicely for my setup, if this has more wider value to others, I pass it on.  I hope this helps and would be interested in your thoughts / comments as I couldn't see anything else like this on the forum.
More replying to myself - must stop doing that!

Having worked out and written all the above, I thought to look at the Continuous drive section and I immediately see that there is a "delayMicroseconds(200);" command after setting LOW on the step section. So, I'm thinking I'm on the right track!!!

Also for those who had queried on the forum, could they get faster movement on the continuous drive, the answer may be perhaps. Tuning that delay factor could help. The 125 (difference between 200 and 75 delays) microseconds adds up over one revolution to 0.2 seconds per revolution. It is noticeable on my setup even if it's not great.

thanks for looking into the software and for trying to improve it. I'll check if I can replicate what you wrote in the next couple of days.


OK. Look fwd to your thoughts.

In the meantime, I started doing a bit of tidying up and have a bit more insight. To explain:
- I hadn't really realised the role that "motor_step_delay_min" should play. It's set to 0 by default and the manual doesn't really highlight that this is an important tuning variable that could affect the fundamental performance of the motor. It really just implies you can use this to slow the motor down. Most of us are probably going to want to have the max speed so a default of 0 is not something you rush to change! This is what gave me the problem because had it been set to a higher default value I probably would not have noticed. For me there certainly is a value somewhat > 0 needed here and I'm using a pretty typical stepper.

- In any case, there is a bit of a logic hole. When motor_step_delay_min = 0 the code in doMotorPhase does not inset a delay at all (well, that makes sense; if you have set zero, you expect zero delay). However, it also allows the calculated value to drop below any pre-defined motor_step_delay_min value - this is probably bad if you (like my setup) always needs a min delay, especially for the max speed phase but also in the extremes of the ramp phases.
Current code:
// Move stepper one pulse using the delay just calculated
digitalWrite(MOTOR_STEP_PIN, HIGH);
digitalWrite(MOTOR_STEP_PIN, LOW);
if (step_delay > 0) delayMicroseconds(step_delay);
step_count ++;

- I put in the changes as described in previous post and this fixed things for me but it was a bit of a 'kludge'.

- I think there is a better fix to use the motor_step_delay_min as it probably should be in all cases. Changes noted below.

Change code in doMotorPhase to always use the calculated step delay:
// Move stepper one pulse using the delay just calculated
digitalWrite(MOTOR_STEP_PIN, HIGH);
digitalWrite(MOTOR_STEP_PIN, LOW);
delayMicroseconds(step_delay); //RB: Altered to remove 'if' clause
step_count ++;

Change code in calculate_ramp_delay final 'return' statement to add an 'if' statement:
// RB: Now return greater of the minimum step delay or calculated step delay
if (motor_step_delay_min > motor_step_delay_max - res)
return motor_step_delay_min;
return motor_step_delay_max - res;

Finally, just because we can, in doMotorContinuous, change the fixed 200millisec delay statement.
// RB: changed from 200 to motor_step_delay_min to use global variable!

This is all now working reliably and the user can, of course continue to tune that min value parameter for both step and continuous use.

I hope this is a useful contribution.
(02-21-2015, 07:56 PM)RichardB Wrote: [...] I hope this is a useful contribution.

Hello Richard,

this is definitely a useful contribution and I am going to add it to the code. This will cause the first update on the miniE v1 in a long time Wink
Thank you!


I'm very pleased that you found it a useful contribution - I saw the 1.2 update which is great and hope others will find it useful too.

I've now completed assembling the hardware slide. I'm using one of the MakerSlide kits so it wasn't so hard! MiniE is now installed and it's working! I was a little worried from the outset that the easy driver was underpowered for the motor (750mA vs 1.7A) but it seems fine. Took a little tuning though. A few tips for others who may be on this journey:
- The trim potentiometer on the Easy Driver seems to work the opposite way round to the board marking on my one (max is turn clockwise). Helps if it really is set to max!
- Using a decent Ramp setting (e.g. 200 steps) and not too high a max speed (e.g. 150) also seems to help with smoothness of steps and apparent torque delivered. I guess that means don't try to be too greedy on speed (it's not really needed anyway for step-shoot-step).
- For anyone else using the Makerslide kit, it looks like the motor gives (approx) 44 steps per mm or 438 steps per 10mm

I now have to do a final few bits on the hardware (attach ball head to the slide, add limit switches, find a power supply, end stops and legs / tripod attachments for the slide and a box for the electronics) then I will be good to go. I'll post some pics to the other threads when it's neat and tidy.

In the meantime... Airic, many thanks for your dedication to this project and the support you provide. Great piece of work.
I chaged the easy driver to drv8825 or bis easy driver, it works fine.
On the drv8825 you have no sleep mode, i couldnt figure it out that quick.
The big easy driver works fine bute costs also 5 times more than the drv8825

On the motor driver, I decided to try the easy driver because it was a) cheap, b) fitted Airic's shield without any modification, and c) should have worked because Airic had done all that development with it. I though I might need to upgrade but it seems fine when fed with a 12V supply and 'tuned' with settings that suit. So for present I'll probably stick with it!

Forum Jump:

Users browsing this thread: 1 Guest(s)