Closed loop DC motor control

I am looking for a way to start a "sticky" motor and also to set the speed. I have ordered a small gearbox motor with an encoder to use in a small project and I would like some input on the code. The plan is to use the external interrupt on the UNO to stop the motor as soon as it starts to turn, then returning to the man loop and there set the idle delay until it turns the power back on to the motor. Would this code work?

int motor = 13; // The pin for the motor controller
int pot=A0; // The analog input for the potentiometer
volatile int state = CHANGE;

void setup() {
    pinMode(motor, OUTPUT); // Define the motor pin as an output
    pinMode(pot, INPUT); // Define the analog pin for the potentiometer as an input
    attachInterrupt(0, IRQ, CHANGE); // Define the first interrupt pin of the Arduino UNO as external interrupt
}

void loop() {
    if (pot == 1023) {
       digitalWrite(motor, LOW);
       } // If the potentiometer is set to one if it's endpoint, the pin should be set to LOW effectively turning the motor off
       else
    delay(pot);  // Use the A/D value of the potentiometer directly as a delay making the maximum time between pulses just above 1 second
    digitalWrite(motor, HIGH); // Turning the motor pin ON again
    
}

void IRQ() {  
  digitalWrite(motor, LOW); // Turning the motor off as soon as there is a change in the state of the encoder attached on the motor
}

The plan is to use the external interrupt on the UNO to stop the motor as soon as it starts to turn, then returning to the man loop and there set the idle delay until it turns the power back on to the motor.

That doesn't sound like a good plan to me. What do you mean by a "sticky motor" and what do you think the problem is?

Motors briefly draw the stall current when starting, which can be 10x the normal running current. Your power supply must be able to supply that current for a proper start.

Are you thinking of making a velocity controlled servomotor? Then you need to read the encoder,
compute a velocity estimate from it and feed that into a PID loop and thence to the motor driver.

The actual speed is not important.

The application is a magnetic stir plate and the reason for the "stickiness" is that the magnets hold on to the mounting screws of the motor until the force of the motor becomes large enough, then the speed is so high that the stir bar spins off the magnetic grip. I need to figure out a way to get enough power to turn the motor but keep the speed low enough so that the magnetic coupling between the magnets on the motor and inside the stir bar does not "break".

I should probably have explained that I will use a mosfet transistor to control the motor so the running and stall current will not be an issue.

I have been wondering about that sort of problem (for model trains) and one question in my mind is whether it would be sufficient to send a small number of PWM pulses at full power followed by regular pulses. I just have not had time to experiment with it yet.

The attraction for me is that it avoids the need for feedback equipment where space is restricted.

...R

Robin2:
I have been wondering about that sort of problem (for model trains) and one question in my mind is whether it would be sufficient to send a small number of PWM pulses at full power followed by regular pulses. I just have not had time to experiment with it yet.

The attraction for me is that it avoids the need for feedback equipment where space is restricted.

...R

I have done some basic testing with stepper motor for my application but spinning steppers fast pretty much requires a dedicated driver, and I wanted to use a L298 or similar. I can understand how the limited space in a model train makes it very difficult to use any kind of encoder but the advantage is the it automatically compensates for varying loads etc.

kamelryttarn:
I have done some basic testing with stepper motor for my application

I was not referring to a stepper motor - just very cheap DC motors.

...R

Since the load probably doesn't change much, open loop control might be more appropriate. Just give the motor a 'kick' of, say 50% PWM, for a few milliseconds then drop back to 10-20% and ramp that up to your final speed over a few hundred milliseconds.

Avoid very cheap motors?

MarkT:
Avoid very cheap motors?

I did not mean to imply that the problem (if there is one) is due to the cheap quality of the motor.

...R

MorganS:
Since the load probably doesn't change much, open loop control might be more appropriate. Just give the motor a 'kick' of, say 50% PWM, for a few milliseconds then drop back to 10-20% and ramp that up to your final speed over a few hundred milliseconds.

But wouldn't a closed loop approach work just as well? It's really not much harder to achieve and it would be fun to try.

A speed regulated drive would be the answer. You'll have to get some sort of speed feedback, pulse tach or even a cheap fleepower dc motor to use as an analog tach. Then put a ramp on the speed reference, say 1 sec or so. The PID loop will probably work or you could make your own but the loop gain must be all you can get without going unstable.
It sounds like an interesting project.

kamelryttarn:
But wouldn't a closed loop approach work just as well? It's really not much harder to achieve and it would be fun to try.

I had assumed, because you started the Thread, that you might welcome a simple solution. But, by all means experiment and let us know how you get on. That's what the Arduino is for.

...R

Simple solutions are always welcome and I appreciate all suggestions. I will wait for the motor I just bought on ebay and see how it performs.