Control de velocidad del servomotor con PIC

2

Estoy controlando un servomotor utilizando el PIC12F675. El servo gira en direcciones opuestas.

Yo 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 alcanza los extremos opuestos. Intenté buscar artículos relacionados con el control de velocidad, me pareció demasiado complicado para controlar la velocidad de barrido. Estoy buscando sugerencias para el mismo

    
pregunta Sai

2 respuestas

7

Los servos funcionan escuchando 20 ms, luego ajustando la posición según la duración del pulso alto.

El pulso alto ( X debajo) puede tener una longitud de entre 1 ms y 2 ms, con 1,5 ms como posición neutral o central.

 |------------20ms-----------|
 |-X-|                
  ___                         ___
_|   |_______________________|   |___ ...

Dependiendo de su servo, -90 ° (izquierda del centro) es generalmente ~ 1ms, 90 ° (derecha del centro) es ~ 2ms.

Si está a 0 ° y le envía una señal de 1 ms, intentará girar a la posición de -90 ° lo más rápido posible. La velocidad máxima varía de servo a servo (las hojas de datos a menudo especifican un tiempo de 0-60 °), y también dependen del voltaje que se le dé (Hitec HS-422 a 4.8V tarda 0.21 segundos, a 6V toma 0.16 segundos).

Si desea variar la velocidad (no solo lo más rápido que pueda), 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 largo con un pulso alto X ms).

Si enviamos 50 pulsos, lentamente de 1.5 ms a 1 ms, reduciendo 0.01 ms cada vez, X será igual:

1.50ms, 1.49ms, 1.48ms, ... , 1.02ms, 1.01ms, 1.00ms

entonces, asumiendo que puede girar tan rápido como lo queremos, tomará 50 (number of 20ms signals) x 20 ms (length of pulse) = 1s para obtener de 0 ° a -90 °.

Envíe un pulso de 20ms con x ms alto: (psudocode)

function send_signal (x):
    set output high
    wait x ms
    set output low
    wait (20 - x) ms

Haz un servo despacio de la izquierda (-90 °) a la derecha (90 °)

Psudocode:

loop x from 1 to 2, step 0.01
    send_signal(x)

O si lo prefiere, en C (99):

for (float x = 1; x <= 2; x += 0.01) {
    send_signal(x);
}
    
respondido por el Alex L
3

Le sugeriría 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 decide utilizar un software PWM; Los pasos de retardo de 1 ms solo le brindan incrementos del 5% en el ciclo de trabajo de PWM para un bucle de 20 ms.

Tendrás que subir y bajar u ; una velocidad de giro fija debería ser suficiente (un control de la 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)
    
respondido por el Jason S

Lea otras preguntas en las etiquetas