Smoothly Controlling DC Motor

Hello all,

I'm building a midi controller with 8 faders. Everything is fine and well with the interface but my issue is moving the motor smoothly. I've used a couple of tests to move the fader to different values. One test simply increases position linearly +-5 units in a loop, the second test selects random values to jump to. It moves fairly well under these cases however when I use a DAW to send midi messages, (to which the fader will respond) , small increments of position cause the fader to move in a jerky motion. I suspect that it is overshooting and then the next request causes it to go backwards, rinse, repeat. However I can't find a reliable way to move the motor quickly and accurately. Currently the code I'm using is as follows which has evolved many times while trying to solve this problem:

void Fader::SetFaderPosition(int position)
{
  if(mTouched) return;
  int target = position;
  target = constrain(position, mMin, mMax);
	int pos = GetFaderPosition();
  int deadband = 5;
	int dist = target - pos;
  if(abs(dist) <= deadband) return;

  int pin1 = -1, pin2 = -1;
	if(dist > deadband)
  {
		pin1 = mUpPin;
    pin2 = mDownPin;
  }
	else if(dist < -deadband)
  {
	  pin1 = mDownPin;
    pin2 = mUpPin;
  }
  else return;

  int speed = 0;
  long t = millis();
  digitalWrite(pin1, HIGH);
  while(1)
  {

    pos = GetFaderPosition();
    dist = target - pos;
    if(abs(dist) <= deadband) { break; }

    if(millis() - t > 1000) break;//Don't speed too much time
  }

        digitalWrite(pin1, LOW);
        digitalWrite(pin2, LOW);
  error =   abs(target - GetFaderPosition())/(float)target * 100;

  //  Serial << "End Pos: " << pos << " " << error << "% error" << "\n";

}

I have tried some things with PWM and even setting a pin HIGH with a microsecond based delay then setting it low (by measuring the time it takes for the fader to reach it's maximum position). I'm using an SN75441 H-Bridge and a 9volt power supply. Any Ideas?

Most electric motors have a bit of 'stiction' that needs to be overcome to get it to start moving. Give it a high PWM value for the first few tens of milliseconds, then drop back to your PID value. I use a very similar control mechanism in one of my projects so that any time the deadband is exceeded, it starts moving with this extra kick.

Also make sure you're using the braking function of your motor controller. That will help making smaller movements.

To test the braking effect, take a motor that's not attached to anything. Try to spin it. It moves easily. Now pinch the bare ends of the motor's power wires together. Try to spin it again. It's surprising how much braking force this generates.