Shop OBEX P1 Docs P2 Docs Learn Events
Using an encoded DC motor as a stepper equavalent. CNC. - Page 2 — Parallax Forums

Using an encoded DC motor as a stepper equavalent. CNC.

2

Comments

  • Basic setup would be like this:

    quadrature decoder cog maintains a hub variable with the current position, measured in
    encoder steps (sense every transition, you want as much precision as you can get).

    You need to output PWM drive signal (for DC motors use synchronous rectification mode,
    not any of the decay modes, you need symmetrical and linear response to drive level)
    This means you are at all times driving the motor winding, switching direction at the PWM rate. This
    is equivalent to controlling with a DC voltage source (assuming PWM frequency is high enough,
    since the inductance of the motor smooths out the current). Bit more loss in the motor,
    but stable control needs this.

    Then you need another cog to read step/direction pins to write a desired position hub ram
    variable.

    Use PID where the error is difference is the two variables (desired/current position) and
    PID output is the PWM drive.

    Always start with just P term, find the max gain that is stable. Then add D until it gets
    noisy, back off the D, advance the P as far as stable, repeat. There is always compromise
    between speed of response and noise (position and audible, typically).

    The I term has to be tamed - if the output saturates you must stop incrementing the
    integration value (and even let it decay to zero). The I term will otherwise windup
    and lead to overshoot. Its only valuable when close to the target position, ie when the
    demanded change isn't too sudden. I term increases instability so you normally have to
    backoff on the P term to accomodate it.

    Normally for motor control you'd run PID loop at 1kHz to 10kHz rate, and if you were
    doing current control (if measuing phase current in a 3-phase bridge for instance), that
    loop should be as fast as you can drive the output if possible (ie PWM frequency x 2 for
    phase-correct PWM).
  • BTW one thing that's not often mentioned is that overshoot on a step-change in input isn't
    necessarily a problem - you won't be giving a step change bigger than one encoder step,
    so a 20% overshoot is 0.2 encoder steps big! So long as the step pulse train has bounded
    acceleration you should find you can use less D term and get faster slew-rate. Experiment
    is needed (and with the real-world load attached to the spindle, you have to re-tune for
    different loads...)
  • This is the first that I've see of this thread and I'm glad that you have resurrected it.

    Harprit hasn't been around for a good while. The last time I communicated with him, he was off to work on some locomotive project or other.

    Unfortunately, the thread never did provide the answers that he was looking for:

    *He was simply wanting to know how to control a closed loop motor
    *He didn't care about brushed/brushless commutation
    *He didn't care about various mechanical transmissions
    *He didn't care about his existing low-resolution encoders
    *He didn't care about muti-axis interpolation
    *James, T Chap and Graham understood but didn't provide “how-to” details in layman's terms.

    First off, we need to forget any references to stepper motor control, we are talking apples and oranges, here.

    A servomotor command comes in the form of either direction/PWM or analog +/- 10v. PWM is often filtered to provide this analog signal.

    The PID loop simply provides the sign/magnitude of this motor command signal to attempt to eliminate the difference between where the motor needs to be and where it actually is (aka: Error), based on the position feedback provided by say, an incremental encoder, resolver, LVDT, potentiometer, etc., etc.

    The Kp (P-term) coefficient is an adjustable multiplier (gain) that determines the magnitude of the motor command relative to the magnitude of the position error.

    If one likens the P-term to a spring, the D-term is the shock absorber/damper. Imagine a car with spring-only suspension.

    The Kd (D-term) coefficient is also an adjustable multiplier.

    The Ki (I-term) coefficient is also an adjustable multiplier for the integrator. The integrator's purpose is to eliminate position error but can play havoc with loop stability during motion as it attempts to kill following-error (servo-lag). This is best applied just as the axis comes to a standstill:
    IF MotionIsComplete AND PositionError = Reasonable
      Apply Ki
    ELSE
      Kill Ki
    ENDIF
    

    This is all well and good but how to command a move from A to B?

    It's all very well issuing a new command position to the PID loop but the PID will instantly generate a motor command signal (command_position – actual_position) as large as its Kp setting will allow, resulting in a very abrupt change of position.

    In actual fact, we typically would like to make a move involving the following:

    *Target Position (encoder counts)
    *Axis Velocity (encoder counts/sec)
    *Axis Acceleration (encoder counts/sec²)
    *Axis Deceleration (encoder counts/sec²)

    To achieve this, we “discretize” the position command based on the loop sample time.
    Forgetting Accel/Decel for now, in the same 1KHz PID loop, instead of dumping the whole command_position in there, divide it by the loop frequency. In this case 1000. For each iteration of the loop, increment the command_position accordingly.

    To move 3000 encoder counts in one second, each iteration of the loop would add 3 encoder counts to the command until reaching 3000. Assuming the PID loop is doing its job, the axis will arrive at 3000 counts at a velocity of 3000 counts/second.

    Accel/Decel can be added quite easily.

    Nowhere near as complicated as some would have us think and all of the above can be handled without the need for floating point math.

    I have seen some crude "ramping" techniques used by the stepper guys, maybe the attached document could be of interest there also
  • Thank you Mark_T I really appreciate your answer it explains a lot.
  • oh and thank you Mikster! just noticed your post now.
    that has really made it much clearer for me. Thank both of you for actually reading my question, putting thought into it and giving an answer from your experience that has helped me a lot. that's the whole point of help forums!
    Often I'd get a reply like 'google it', that can only get someone so far.
    And I'm glad I've not received the negativity towards this question that Harprit undeservingly received.
  • so, to summarize:
    I was attempting to use a PWM mode not well suited to this type of problem. I'll drive my h-bridge as suggested by Mark_T, which has the added benefit that it only requires one PWM output from the controller, per motor.
    50% PWM is my holding position, here the P and D terms would not contribute to output, because error is 0, 'I' is the only term contributing to the output.
    When the target position changes error becomes non-0 and the P and D terms can kick in.
    during this time prevent 'I term windup'.
    And from Mickster I learnt to not give it the target location as a step, rather feed it in incrementally at each loop iteration... (this also helps preventing 'I' from running away too fast?)

    hope i got all that right... at least i feel like it makes sense

  • Personally, I would leave the I-term out of it to start with. If the steady state error is not within acceptable tolerance, introduce the I-term but prevent wind-up via a not-to-exceed I-limit.
    Furthermore, if the steady state error is always the same direction, no matter which way the may the motor turns, you can add an offset AFTER the PID filter.

    I would be interested to follow your project, BTW. Please keep us updated.
  • Agreed :) yes hopefully I can upload a video of it working
  • ErNaErNa Posts: 1,751
    A stepper motor is a "P"-controller. That means: under zero load, the stepper rotor is only at stand-still, when there is no torque applied. Otherwise the rotor would accelerate. In other words: the motor draws current, but created not torque. In terms of a dc-motor: q and d-axis of the fields are colinear. But whenever you apply an external force, the rotor turns a little and starts to create a back driving force, because now p and q axis diverge. The torque reaches his max value when q und P are orthogonal, in the moment the stepper is overloaded and loses steps.
    If now you command a step to the motor by switching phase currents, that mean, the q axis changes and the d axis tries to follow, resulting in a damped oscillation to reach the new zero torque position.
    If you try to replace a stepper by a dc-motor your task is to emulate the p-behavior by measuring the error and applying a current to create the torque. But: if a stepper has 200 steps per revolution you measuring the error +-5 means 2000 steps resolution of the sensor. And +- 5 certainly results in a poor performance of the P-control loop. And more: stepper motors generate high specific torque compared to dc-motors. That means, a gear box is needed to generate appropriate torque in the same volume.
  • MicksterMickster Posts: 2,691
    edited 2016-03-26 13:22
    The beauty of the PID loop is that it can be adjusted to adapt in real time. If holding torque is an issue, the I-term can be increased accordingly or a post-filter offset applied. To avoid oscillation, a deadband can be introduced of +/- X counts.
  • ErNaErNa Posts: 1,751
    Just to clearify: if holding torque is an issue, nothing can be done but having a stronger motor.
  • Oh, sure. Components need to be selected to suit requirements.
    For a given load/speed/acceleration requirement, I spec my components such that I remain within 30% of ratings. For most industrial servo drives, this means I never exceed stall torque/current limits and therefore never experience nuisance drive tripping. I prefer my following error traps and torque monitoring to pick up on abnormal load conditions, allowing me the opportunity of recovery instead of scrapping a workpiece.
    Furthermore, wherever I have potential transmission backlash, such as a gearbox, etc., I implement dual-loop feedback in the form of an encoder or linear scale attached to the actual load.
  • i_love_PICi_love_PIC Posts: 13
    edited 2016-03-26 21:51
    Yeah I have good quality DC motors with gear-box, these are from medical devices. not large but i'm only building a small machine....to start with ;)
  • Wait, what? In no way, shape or form can stepper motors compete with closed loop servos except on price.

    Real machine tools and robots don't use stepper motors. Only cheap knee-mill retrofit kits use steppers.

    Servo control is not difficult at all. There are hobby projects on this forum that are infinitely more complex.

    Please stick with it, bud :-)
  • ah i edited the post cause i realized ErNa was not against it, only pointing out difficulties, for that particular application.
    ok that's actually good to hear, to be honest I have not made a thorough comparison for one technology or the other, all that would be pointless cause I intended to stick to the DC motors regardless.
    Don't worry I ain't given up!
  • The following link is for a product manual but contains lots of information that you might find useful/interesting:

    https://www.dropbox.com/s/fddejxpad92ha9w/man41x3.pdf?dl=0
  • Thanks for that :)
    here's a quick simulation on a spreadsheet, it's a PD controller using quantized maths..
    left graph shows the controller settles on the target in 31 loop iterations, and the right hand graph shows the pwm offsets to the 50% steady value.
    just waiting for my h-bridge chips to arrive and put all this together!
    1093 x 321 - 16K
    pwm.png 15.7K
  • MicksterMickster Posts: 2,691
    edited 2016-03-31 19:25
    Are you using LMD18200s?

    A few more hints and tips:

    Mark_T's servo-tuning method is identical to mine but there are others that do similar but swap the Kd and Kp (I never tried this).

    I have come across many cases of hobbyist projects where loop-tuning has been a challenge. In many cases, they have the I-term running full-time. In 35 years of working with all types of servo systems (including hydraulic), this has never worked for me.

    Another possibility is limited encoder resolution. I run between 2048-4096 line (8192-16384 quadrature count)/rev encoders which give good stability at even very low motor velocity. However, I have 500 line (2000 quadrature count) encoders on my desktop development system which can produce an erratic response at very low velocity. In this case, I incorporate a "servo rate divisor" (SRD). If the SRD=1, the D-term takes the position error from the previous sample, as normal. However, if the SRD=3, the D-term uses the position error from 3 samples previous, which smooths things out nicely.

    Error Killing:
    In case the motor/load has been disturbed due to the amplifier being disabled (switched off), It's a good idea to kill the error prior to restoring power to the motor to prevent sudden unexpected motion:
    CommandPosition = ActualPosition
    


    Soft Limits:
    IF CommandPosition > PositiveLimit OR CommandPosition < NegativeLimit
    	(either make the CommandPosition = Limit or prevent motion altogether)
    ENDIF
    


    Torque Limiting:
    An application might require that the motor dead-heads (stalls out) but maintains a particular torque. Just prior to outputting the motor command:
    IF MotorCommand > TorqueLimit
    	MotorCommand = TorqueLimit
    ENDIF
    
    Kill the error prior to removing the torque limit


    Deadband:
    Typically used in the case of amplifier deadband or static friction:
    IF ABS(Error) <= DeadBand
    	MotorCommand = 0
    ENDIF
    


    Offset:
    Rather than have the PID fight an external influence such as gravity, superimpose a bias directly on the output of the PID.
    MotorCommand = MotorCommand + Offset
    
  • Can't thank you enough!
    I'm using NJM2670D2. Right you are my PD seems to be suffering from all those problems. I took some precautions like setting limits on the POSITION.
    I have a DELTA variable that toggles polarity when the POSITION hits a limit, every 2s I add DELTA to my TARGET.
    The step size (or DELTA) is large because as you say, my encoder has a very low resolution and i found something like 5 steps just was not happening.
    So the setup almost works! there's clearly a large STEP occurring at the expected rate, but the motor twitches a lot around the setpoint. P and D values are the best I could find by tuning.
    I'll go shopping for a better encoder, and in the meantime I'll play around with introducing a deadband.

    I recorded the twitching motor onmy phone after work hours I'll upload it on youtube and put a link here :)
  • Just had to edit my previous post because I had Mark_T confused with T_Chap. :blush:
  • MicksterMickster Posts: 2,691
    edited 2016-03-31 20:21
    The deadband will take care of the steady-state jitters and there's no reason not to vary the Kp/Kd based on velocity during motion.
  • Yeah I knew who you meant :)
    OK, I was under the impression that playing around with the loop too much was unacceptable in the PID community, basically what I've been hearing is that a properly tuned loop will run itself. The way I see it I'd do whatever it takes to just get the thing to run!, all's fair in love and war. So, can you implement little cheats like that into your loop, and still please the PID purists out there? :/
  • ErNaErNa Posts: 1,751
    PID-Control only works in well behaving systems perfectly. Real systems are mostly far from that state. So every control strategy that solves the problem is allowed and ok. Even PID ;-)
  • Yeah, we're not stuck with potentiometers anymore :D

    http://m.machinedesign.com/sensors/motion-control-meets-adaptive-control
  • ErNaErNa Posts: 1,751
    stone age doesn't end the moment, your hammer is made from iron. Progress in communication was possible not be replacing R-C-L circuits by computing, but by implementing filters that don't have electronic equivalents. In motion control state of the art is still based on PID with a lot of "improvements"
  • kwinnkwinn Posts: 8,697
    i_love_PIC wrote: »
    Yeah I knew who you meant :)
    OK, I was under the impression that playing around with the loop too much was unacceptable in the PID community, basically what I've been hearing is that a properly tuned loop will run itself. The way I see it I'd do whatever it takes to just get the thing to run!, all's fair in love and war. So, can you implement little cheats like that into your loop, and still please the PID purists out there? :/

    Do what you have to do. You can't please everyone so you might as well please yourself. ;-)
  • i_love_PICi_love_PIC Posts: 13
    edited 2016-04-03 01:28
    Ok, seems like I'm getting somewhere! Thanks so much for your help, ill build an axis and test it on that asap
  • It's alive!

    Cool...did you try longer, higher speed moves? Looks like limited encoder resolution from the video.
  • If its any indication why encoder resolution is so important, note than many industrial servo motors
    use 18, 19, 20, 22 bit absolute encoders, that sort of accuracy, because that's how you reduce jitter and
    improve performance. Its one of the reasons servomotor systems are very expensive. Older designs
    uses resolvers and sine/cosine analog encoder signls to give analog position feedback with as much
    resolution as possible.
  • Oh, the other thing, the PID loop needs retuning for the load inertia - what works on a bare
    shaft will probably oscillate with a real load.
Sign In or Register to comment.