Estoy tratando de obtener un control preciso sobre la velocidad del robot basado en rover 5. Tiene cuatro motores controlados por PWM y 4 codificadores de cuadratura ópticos. Estoy utilizando controlador de motor de 4 canales con chasis rover 5 . Estoy usando arduino Nano para el control. Soy capaz de leer la salida INT del codificador y cambiar la PWM en función del ancho de pulso para controlar la velocidad. Pero, como resultado, estoy obteniendo oscilaciones pesadas en la salida de control. Eso hace que el robot se mueva en pasos, ya que PWM cambia constantemente. Necesito un algoritmo que pueda minimizar este timbre y tener un robot que se mueva sin problemas. Aquí está mi fragmento de código arduino.
void setup() {
Serial.begin(9600);
init_motors();
init_encoders();
req_speed[0] = 20;
req_speed[1] = 20;
req_speed[2] = 20;
req_speed[3] = 20;
}
void loop() {
update_encoders();
update_motors();
}
void update_motors() {
int i, err;
unsigned long req_width;
if(micros() - mtime > 2999) {
mtime = micros();
for(i=0; i<4; i++) {
digitalWrite(pins_dir[i], req_speed[i]>0);
if(mtime - change_time[i] > 50000ul && req_speed[i] != 0) {
cur_pwm[i] += 5;
}
if(req_speed[i] > 0)
cur_err[i] = req_speed[i]*10 - cur_speed[i];
else
cur_err[i] = (-req_speed[i]*10) - cur_speed[i];
if(cur_err[i] > 0 && cur_pwm[i] < 255) {
cur_pwm[i]++;
} else if(cur_err[i] < 0 && cur_pwm[i] > 0) {
cur_pwm[i]--;
}
analogWrite(pins_pwm[i], cur_pwm[i]);
}
}
}
void update_encoders() {
int i;
unsigned long w;
enc_new = PINC & B00001111;
unsigned long etime = micros();
for (i=0; i<4; i++) {
if((enc_old & (1 << i)) < (enc_new & (1 << i)))
{
w = (unsigned long)(((etime - change_time[i])));
pulse_width[i] = (w + pulse_width_h1[i] + pulse_width_h2[i])/3;
pulse_width_h2[i] = pulse_width_h1[i];
pulse_width_h1[i] = pulse_width[i];
change_time[i]=etime;
pulse_count[i]++;
cur_speed[i] = (3200000ul / pulse_width[i]);
}
}
enc_old=enc_new;
}
Aquí req_speed está entre -100 y 100, donde el signo indica la dirección. Por favor considere todas las variables indefinidas como globales. Medí experimentalmente que, cuando el motor está funcionando a toda velocidad, el ancho del pulso es de alrededor de 3200 us.
Las salidas INT de los codificadores (XOR de A y B) se conectan de A0 a A3. El motor PWM está conectado a D3, D5, D6, D9.
¿El arduino no es lo suficientemente rápido como para ponerse al día con 4 codificadores? ¿Es PinChangeInts mejor que el sondeo?
Por favor, permítame sugerir alguna mejora a este código y aconsejarme sobre lo que me estoy perdiendo aquí.