Granulosidad de ángulo PWM servo ATtiny85

0

Actualmente estoy trabajando en el control de los servomotores con un ATtiny85 . Me cuesta entender cómo lograr una granularidad fina para los ángulos del servo.

Estoy utilizando una técnica similar a la indicada por KyranF .

Un ángulo de servo se determina por el ancho de pulso entre 1-2ms de un PWM de 50Hz.

Estoy usando el temporizador 1 con un prescaler de 1 con un reloj de 8 Mhz. Esto significa que un desbordamiento del temporizador (tick) toma (1 / 8MHz) * 256 = 32 microsegundos.

Un periodo de 20ms lleva 625 desbordamientos. Esto significa que mi granularidad de 1 ms es 625/20 ms = 31,25 = ~ 31 ticks por ms.

Debido a que el ángulo del servo se controla al configurar el ancho del pulso en algún lugar entre 1 y 2 ms, solo puedo tener una precisión de 31/180 ° = ~ 6 grados.

¿Hay alguna manera de lograr una precisión de 1 °?

    
pregunta AronC

2 respuestas

2
  

Debido a que el ángulo del servo se controla al configurar el ancho de pulso   En algún lugar entre 1 y 2 ms, solo puedo tener una precisión de 31/180 ° = ~ 6   grados.

     

¿Hay alguna manera de lograr una precisión de 1 °?

La mayoría de los servos solo mueven ~ 120º con 1-2ms. Sin embargo, suponiendo que 1-2ms = 180º necesita 180 conteos de 5.55us por conteo.

El Attiny85 tiene un generador PWM de 8 bits que puede hacer hasta 256 conteos, pero no tiene una relación de división preescala que puede realizar 5.55 pasos a 8MHz. El más cercano es 8 us por conteo con un preescalado de 1/64, que corresponde a 125 conteos en 1 ms para una resolución de 1.44º por conteo (si 1 ms = 180º). Para obtener esto, puede configurar Timer0 para que produzca un pulso PWM de 125-250, que equivale a 1-2ms, y usar el timer1 para repetir el pulso a intervalos de aproximadamente 20ms. La mayoría de los servos deberían tener una resolución cercana a 1º con estos 8 pasos.

Si 8us no está lo suficientemente bien, tendrá que usar un retraso de software. A 8Mhz 44, los ciclos de la CPU toman 5.5us, que es el 99% de los 5.55us deseados y proporciona instrucciones suficientes para realizar un bucle de tiempo variable preciso de 1-2ms. Puede intentar escribir el código para esto en C (con algunos NOP para ajustar el tiempo) pero podría ser más fácil hacerlo en el ensamblador.

Para generar un cuadro completo, primero debe configurar un temporizador para interrumpir a intervalos de ~ 20 ms. En el ISR del temporizador, debe iniciar el pulso del servo, esperar una variable de 1 a 2 ms con el temporizador del software y luego finalizar el pulso del servo. Durante este tiempo, la CPU no puede hacer nada más, pero todavía tienes ~ 18-19 ms disponibles por marco de 20 ms.

    
respondido por el Bruce Abbott
0

algunas de tus matemáticas están en mal estado.

si configura prescaler 1: 1, prescaler 8Mhz crystal + 8: 1, timer1 puede tener un máximo de 20,000, y de 1ms a 2ms, tiene 1000 cuentas o 180 grados / 1000 cuentas = 0.18 grados / cuenta.

mucho más de lo que necesitas.

aquí hay un enfoque para el mismo problema que puede encontrar útil: enlace

editar: uno de los enlaces anteriores mostró el enfoque básico - > carga repetidamente el objetivo, o en este caso, avanza el registro de coincidencia de comp hasta que se alcanza la longitud deseada.

Los ejemplos a los que he vinculado anteriormente usan las interrupciones de desbordamiento, pero lo mismo se aplica para comparar la coincidencia también.

//TIMER 2 COMPARE match A
ISR(TIMER2_COMPA_vect){
    //check for _OCR2A exhaustion
    if (_OCR2A) {                   //target exhaused?
        _OCR2A -= 0x100;            //decrement
        OCR2A = 0;
    } else {                        //compValue has been exhausted
        //do user stuff
        positiveTimeoutCheck = false;
        digitalWrite( DEBUG_PIN, LOW );
        //timerOneCompADisable();
        TCCR2B = 0;                     //stop timer2
    }
}

el código anterior sigue la lógica básica y borra DEBUG_PIN una vez que _OCR2A (un tipo de 16 bits establecido por el usuario) se haya agotado.

Este es un ejemplo de su implementación en TIMER2 de un ATMEGA328p (que ejecuta 1MIPS) donde el preescalador del timer2 se establece en 1: 1, y _OCR2A a 25000 - > con un retraso de 25 ms para DEBUG_PIN en cada transición en PCINT0.

diferentes formas de hacer lo mismo.

    
respondido por el dannyf

Lea otras preguntas en las etiquetas