I have linear drive motor that I drive with a PWM signal of frequency 1kHz. The minimum duty cycle for the linear motor to start moving without any load is 30 %. Now I am trying to design and tune a PID controller to control the position (ranges from 0 - 10000 counts).
My difficulty in understanding is: do I change the duty cycle of the motor, or do I set it to a constant value? My thought process is the further away it is, the faster it should move and the closer it is to the setpoint, the more it should slow down. The minimum duty cycle is 30% and maximum is 100%. If so, how do I go about doing so?
I have written some code that works, but only because I have set the duty cycle to 60%. I currently do not have any requirements for settling time and overshoot %, I am just trying to get something to work.
My difficulty in understanding is: do I change the duty cycle of the motor, or do I set it to a constant value? My thought process is the further away it is, the faster it should move and the closer it is to the setpoint, the more it should slow down. The minimum duty cycle is 30% and maximum is 100%. If so, how do I go about doing so?
I have written some code that works, but only because I have set the duty cycle to 60%. I currently do not have any requirements for settling time and overshoot %, I am just trying to get something to work.
C:
// PID
#define KP 0.05
#define KI 0
#define KD 0
//Variables
double setpoint = -3000;
double input = 0.0;
double output = 0.0;
double error = 0.0;
double integral = 0.0;
double derivative = 0.0;
double last_error = 0.0;
C:
void PID_Controller()
{
// Calculate error and integral
error = setpoint - distance_um; // distance_um is read from encoder
integral += error;
// Calculate derivative and output
derivative = error - last_error;
output = (KP * error) + (KI * integral) + (KD * derivative);
// Update last error
last_error = error;
// Set PWM signal and direction based on output
if(output > 0)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_RESET); // Motor direction: Low goes "out"
htim3.Instance->CCR1 = 100;
}
else if(output < 0)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET); // Motor direction: High goes in
htim3.Instance->CCR1 = 100;
}
else
{
htim3.Instance->CCR1 = 0;
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_SET); // Stop the motor
}
}