I'm trying to code a motor control function with PID, however I'm having trouble when it comes to invert the direction the motor spins, It spins to one direction but to the other the output is 0, it seems to not be a hardware problem as I inverted the code and it spun just alright to the other side (If there is something like a variable/function in the code that you don't know where it's comming from/value, feel free to ask and I will complete the information)
const float LIMIAR_ATIVACAO = 5.0; //This is the allowed "error"
// Variáveis do PID
double Setpoint, Input, Output;
double Kp = 2.0, Ki = 0.0, Kd = 1.0; // Ajuste esses valores conforme necessário
//function to calculate the shorter way used in the ModoPrincipal function
float diferencaDeAngulo(float angulo1, float angulo2) {
float diferenca = fmod(angulo2 - angulo1, 360.0);
if (diferenca > 180.0) {
diferenca -= 360.0;
} else if (diferenca < -180.0) {
diferenca += 360.0;
}
return diferenca;
}
// I added those serial prints when I was trying to debug
void ModoPrincipal() {
float anguloAtual = readMagnetometerAngle();
float angleDifference = diferencaDeAngulo(referenceMagnetometerAngle, anguloAtual);
if (abs(angleDifference) > LIMIAR_ATIVACAO) {
Setpoint = 0;
Input = angleDifference;
myPID.Compute();
controlMotor(Output);
Serial.print(Output);
Serial.print(" | ");
Serial.print(Input);
Serial.print(" | ");
Serial.print(Setpoint);
} else {
Serial.println("Motor desligado");
desativarMotor();
}
}
//Motor control function
void controlMotor(double Output) {
int motorSpeed = map((Output), 0, 100, 0, 255);
motorSpeed = constrain(motorSpeed, -255, 255);
analogWrite(enablePin, motorSpeed);
if (Output > LIMIAR_ATIVACAO) {
digitalWrite(motorPin1, HIGH);
digitalWrite(motorPin2, LOW);
Serial.println("Motor ativado no sentido horario");
} else {
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, HIGH);
Serial.println("Motor ativado no sentido anti-horario");
}
}
You can't analogWrite a negative number. Well you can put a negative number there, but it won't spin anything the other direction. It just misinterprets the number as some positive number.
What type of motor driver do you have? Usually there is a pin to control the direction.
This looks like the part that swaps the directions. But it is strange. It only swaps the direction if the output is larger than the allowed error.
I think you should analogWrite the absolute value of output and then use the sign of the output to determine which direction to go. This if statement should check if Output is greater than 0 or not. Go one direction for positive output and the other direction for negative output.
I actually was just reading about analogWrite only reading positive numbers.
The input that is working is Negative, I'll paste a sample of the serial monitor
Output | Input | Setpoint (setpoint is always 0)
0.00 | 11.92 | 0.00Motor ativado no sentido anti-horario
0.00 | 8.61 | 0.00Motor ativado no sentido anti-horario
0.00 | 8.61 | 0.00Motor ativado no sentido anti-horario
0.00 | 7.51 | 0.00Motor ativado no sentido anti-horario
0.00 | 5.87 | 0.00Motor desligado
Motor desligado
Motor desligado
Motor desligado
Motor desligado
Motor desligado
Motor desligado
Motor desligado
Motor ativado no sentido horario
5.84 | -5.84 | 0.00Motor ativado no sentido horario
5.84 | -6.15 | 0.00Motor ativado no sentido horario
6.26 | -6.26 | 0.00Motor ativado no sentido horario
Please explain this line. Why do you think you need this line and what do you think it is doing for you?
I removed it just now when I was thinking xD
Explain in words how an input value should relate to an output value and how you determine which direction to spin the motor.
Before I was trying to add PID to my code, the control of the motor direction was pretty straight foward, but now things started to add up. About the Input being negative, I was just brainstorming
in order to slow the motor down, the PID output may be negative. analogWrite() only provides a uni-polar PWM output. the h-bridge in the motor driver circuit needs to change direction in order to support a negative PWM output to reverse the direction of the motor
I fixed it, maybe I did what you guys said but I didn't quite understand for some translation issues hehe I'm gonna paste the final code here so anyone who has the same issue can see what I did(probably there's a way easyer solution xD)