Estoy controlando un servomotor usando el PIC12F675. El servo gira en direcciones opuestas.
Controlo el servo de la siguiente manera:
if(GPIO & (1<<3))
{
GPIO |=(1<<2);
__delay_ms(1);
GPIO &=~(1<<2);
}
else
{
GPIO |=(1<<2);
__delay_ms(2);
GPIO &=~(1<<2);
}
__delay_ms(18);
Me gustaría controlar la velocidad a la que el servo llega a los extremos opuestos. Traté de buscar artículos relacionados con el control de velocidad, me pareció demasiado complicado controlar la velocidad de barrido. Estoy buscando sugerencias para el mismo
Los servos funcionan escuchando durante 20 ms y luego ajustando la posición en función de la duración del pulso alto.
El pulso alto ( X
abajo) puede tener una duración de entre 1 ms y 2 ms, con 1,5 ms como posición neutral o central.
|------------20ms-----------| |-X-| ___ ___ _| |_______________________| |___ ...
Dependiendo de su servo, -90° (a la izquierda del centro) suele ser ~1ms, 90° (a la derecha del centro) es ~2ms.
Si está a 0° y le envías una señal de 1 ms, intentará girar a su posición de -90° lo más rápido que pueda. La velocidad máxima varía de servo a servo (las hojas de datos suelen especificar un tiempo de 0-60°), y también depende del voltaje que le des (Hitec HS-422 a 4,8 V tarda 0,21 segundos, a 6 V tarda 0,16 segundos).
Si desea variar la velocidad (no tan rápido como sea posible), debe indicarle que cambie su posición gradualmente.
Puede hacer esto enviando una serie de señales de posición (cada una de 20 ms de duración con un X
pulso alto de ms).
Si enviamos 50 pulsos, lentamente de 1.5ms a 1ms bajando 0.01ms cada vez, X será igual a:
1.50ms, 1.49ms, 1.48ms, ... , 1.02ms, 1.01ms, 1.00ms
luego, suponiendo que pueda girar tan rápido como queramos, tardará 50 (number of 20ms signals) x 20 ms (length of pulse) = 1s
en pasar de 0° a -90°.
Envía un pulso de 20 ms con x ms alto: (psudocódigo)
function send_signal (x):
set output high
wait x ms
set output low
wait (20 - x) ms
Haz que un servo gire lentamente de izquierda (-90°) a derecha (90°)
Psudocódigo:
loop x from 1 to 2, step 0.01
send_signal(x)
O si lo prefieres, en Do (99):
for (float x = 1; x <= 2; x += 0.01) {
send_signal(x);
}
Le sugiero que generalice su sistema a algo como lo siguiente:
int T = 200 // 200*100usec = 20msec period
while(1)
{
u = compute_next_duty_cycle()
servo_output_on();
__delay_100us(u)
servo_output_off();
__delay_100us(T-u)
}
donde servo_output_xxxx()
enciende y apaga el GPIO. Es casi seguro que tendrá que mejorar la granularidad de sus retrasos, si elige usar un software PWM; Los pasos de retraso de 1 ms solo le brindan incrementos del 5% en el ciclo de trabajo PWM para un ciclo de 20 ms.
Tendrás que u
subir y bajar rampas; una velocidad de giro fija debería ser suficiente (un control de trayectoria más complicado también limitaría la aceleración):
pseudocode for ramping u given a position goal ufinal and max slewrate v:
delta = ufinal - u;
delta = min(v, max(-v, delta)); // limit delta to +/- v
u += delta
Si necesita una rampa muy lenta, tendrá que usar internamente un estado de alta resolución para u y luego dividir/cambiar para obtener su comando de salida:
delta = ufinal - u;
delta = min(v, max(-v, delta)); // limit delta to +/- v
u += delta
uout = u >> 8; // or >> 16 or whatever
servo_output_on();
__delay_100us(uout)
servo_output_off();
__delay_100us(T-uout)
jason s
Sai
jason s
m.alin
Sai
jason s
Sai
jason s
Sai
m.alin
Russel McMahon