Proportional Only Control /Stepper/Potentiometer

I'm needing some guidance. I've got a project driven by stepper motors, they must be controlled via feedback from potentiometers located at the main joints. It has been recommended to me to use proportional only control to alter the speed of the stepper, due to the arms structure integral and derivative probably won't be needed. The stepper movement should stop when the potentiometer feedback equals the set point.

I've been unable to find any examples online or in any books to help me with this. All examples online always use the PID library, but I just want to use proportional control code only.

Any help would be appreciated. I'm new to programming in general and want to learn how to code with the arduino. Thanks.

Think about what proportional control means for just a minute. You don't need any library for that. You need one or two lines of math.

error = setpoint - actual;

output = error * someFactor;

Or use PID with the I and D terms set to zero.

+1 for the simple approach proposed by @Delta_G

And it has the advantage that you can easily find out if it is sufficient before getting embroiled in any library

...R

Okay had a think about it, think this is on the right lines. Thanks for the help.
Using a Unipolar stepper, in this setup from;

const int ActualValue1 = A0; // Potentiometer
const int Threshold1 = 500; // setpoint for the potentiometer position
int Pin1 =8;
int Pin2 =9;
int Pin3 =10;
int Pin4 =11;
int Kp =1; // gain for the proportional control
int error = (threshold1 - ActualValue1); // this is to gain the error value
int drive = error*Kp // this is to calculate the drive value of the proportional control

Void setup

Serial.begin(9600); // communication between Arduino & PC
pinMode(Pin1, OUTPUT);
pinMode(Pin2, OUTPUT);
pinMode(Pin3, OUTPUT);
pinMode(Pin4, OUTPUT);

Void loop

int error =(Threshold1-ActualValue1);
int drive = (int error*int Kp);
AnalogWrite() = (Pin1,Pin2,Pin3,Pin4);
Serial.print(A0)// Shows the actual value
Serial.print(int Drive)//Shows the drive value used

After this I've no idea how to adapt the drive into a pulse width modulation to control the speed of the stepper motor.
I know PWM is the amount of time a digital pin sends out an ON/OFF signals to control the duty cycle.

SCOT177:
After this I've no idea how to adapt the drive into a pulse width modulation to control the speed of the stepper motor.
I know PWM is the amount of time a digital pin sends out an ON/OFF signals to control the duty cycle.

You don't use PWM to control the speed of a stepper motor (or analogWrite() )

You just need to vary the interval between steps.

For a unipolar motor generating a step is a bit more complex than if you were using a bipolar motor with a specialize stepper motor driver board. The simplest thing is probably to use the AccelStepper library which will handle all the complexities.

...R

Thank you for your quick response Robin2.
Are you aware of any examples of this type of control online to review and learn off. I’ve had no luck finding any.

SCOT177:
Thank you for your quick response Robin2.
Are you aware of any examples of this type of control online to review and learn off. I've had no luck finding any.

Start with the examples in the AccelStepper website. When you are familiar with how to control your stepper motor to do simple things you will probably be able to figure out how to implement your project.

In very crude terms, the further you are from your destination the faster you will want to move - and vice versa.

...R

Besides the obvious syntax errors, you have a LOT of problems in that code:

const int ActualValue1 = A0; // Potentiometer

ActualValue1 is probably a misleading name and it's throwing you off. What that variable actually holds is the pin number that you have the pot connected to. The pin number, not the value read from the pot.

So this:

int error =(Threshold1-ActualValue1);

is obviously wrong. The error would be the threshold value minus the actual value you read. Subtracting the pin number (14 in this case) from the threshold value doesn't really tell you anything.

int drive = (int error*int Kp);

I would use the error value you just calculated a couple lines before this line. Creating a NEW variable named error with some unknown value and using that seems counterproductive. Same with Kp. Just use the ones you already have.

AnalogWrite() = (Pin1,Pin2,Pin3,Pin4);

I don't even know what you were meaning for this to do. But it is definitely an error.

Serial.print(int Drive)//Shows the drive value used

Again, use the Drive variable you already have. It was actually spelled with a lower case d. Creating a new variable here with some unknown value and printing it doesn't seem productive.

You actually have two drive variables, one at global scope and one that is local to loop. Two variables with the same name in the same scope is ALWAYS a bad idea.

Okay thanks, but I've no idea as to how to make the drive calculation effect the stepper motor speed, how do the two combine and how do I accomplish this. Very slowly making progress, thanks for the help.

Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Thanks.. Tom.. :slight_smile:

The AccelStepper library is probably the most useful for this task. Use the speed-command controls in that library to set the speed of the motor according to your drive calculations.

SCOT177:
Okay thanks, but I've no idea as to how to make the drive calculation effect the stepper motor speed, how do the two combine and how do I accomplish this. Very slowly making progress, thanks for the help.

With such a small amount of information I have no idea what your problem is.

Post your program and tell us what it actually does and what you want it to do that is different.

Have you studied the Accelstepper library that I mentioned in Reply #5 ?

...R

Hi,
Can you fill in what voltages and stepper type you are using please?


Also have you written your code in stages, have you code that just turns the stepper.
How do you set the stopping point for the stepper?
I would suggest two pots, one on the stepper shaft and one to set your stopping point.

Can you please post a picture of your project.

Thanks.. Tom... :slight_smile:
Please repost you code in code tags please, see post #10.