Control de servos en paralelo con PIC

boton_bombilla.pngHace tiempo que tengo en mente hacer mi propia controladora de servos. Aunque existen soluciones interesantes en el mercado, el reto no era solo tenerla simplemente, sino hacerla, y aprender un poco más de programación de PICs. Un pequeño reto.

La idea sobre la que voy a comentar aquí es aparentemente sencilla de entender, pero no tanto de realizar, sobre todo dependiendo de las posibilidades del PIC que vayamos a utilizar.

Lo primero que tenemos que tener en cuenta, es que para controlar un servo, hay que enviarle cada 20ms un pulso de duración entre 1ms a 2ms. Es decir, que dentro de esos 20 ms, dedicaremos entre 1ms a 2ms de tiempo de nuestro procesador a atender al servo y a poner/quitar el pulso que necesita. Con lo cual tendremos en el peor de los casos ( cuando hay que enviarle al servo un pulso de 2ms de duración), tendremos 20 ms – 2 ms = 18ms el procesador libre para hacer otras tareas.

Buscando por internet, las soluciones más sencillas que se encuentran para controlar más de un servo, son las que los atienden de modo secuencial. Es decir, que si el PIC tiene que controlar 4 servos, va a dedicar entre 1 y 2 ms para el primer servo, entre 1 y 2ms para el segundo servo, etc… hasta atender a los cuatro servos. Con lo cual, en el peor de los casos (2ms por servo) tendremos que emplear 2ms X 4 = 8 ms para atender a los 4 servos. Y nos quedan 20ms -8ms = 12ms para que el PIC pueda dedicarse a otras tareas.


De este modo la cosa se complica cuantos más servos queramos controlar. Y si además queremos que nuestro PIC reciba las ordenes de posicionamiento de los servos de un dispositivo externo, tenemos que añadir un margen, o tiempo mínimo para que el PIC se dedique a esta tarea de recepción de información (y quizá a otras tareas).

Los 20 ms divididos entre 2 ms para cada servo, nos darían un total del 10 servos que se podrían controlar como máximo, y esto sería  sin dejar tiempo libre el procesador para ninguna otra tarea. Luego para tener un mínimo de margen, lo máximo serian 8 servos para controlar y nos restan 4 ms para otras tareas del procesador.

Es cierto, que podemos utilizar interrupciones para que durante esos 2ms de duración del pulso que enviamos a un servo, el procesador se dedique a otras tareas, pero para eso necesitamos esas otras tareas fuesen «interrumpibles» , cosa que las rutinas de TX RX Serie no lo son. Por tanto, tampoco parece demasiado viable.

Es por eso que se me ocurre la siguiente idea : ¿ Por qué no procesar todos los servos a la vez ?…

Esto sería no de manera secuencial, sino dentro del margen de 2 ms de tiempo que necesitamos para cada servo. Y de este modo se procesarían todos los pulsos de todos los servos a la vez.

Así tendríamos 18 ms enteritos para que el procesador se dedicase a hacer cualquier otra tarea, que no sería interrumpida, y durante 2 ms, estuviese pendiente de X servos. Siendo en paralelo, no debería de ser demasiado problema que esa cifra fuese mayor que 8…quiza 16 …ó 20?

Ahora la cuestión está en como hacer que el se procesen todos los servos a la vez con los recursos que nos da el PIC.

Aunque tenemos algunas pistas para hacerlo:

  • Todos los servos deben recibir el cambio de pulso de 0 a 1 en el milisegundo 0.
  • A partir del milisegundo 1 y hasta el milisegundo 2, todos los servos deberán ser cambiados de estado de 1 a 0 de nuevo, individualmente. Excepto en el caso de que dos o más servos requieran el mismo ancho de pulso. En dicho caso esos dos o más servos deberán ser cambiados de estado a la vez. Ese milisegundo será el intervalo donde el PIC se emplee a fondo para quitar a cada pin asignado a un servo el nivel alto.

Entonces atendiendo a esto se me ocurre una rutina que:

  • Ponga a nivel alto todos los pines asignados a todos los servos en el milisegundo 0.
  • Para procesar los anchos de pulso de cada servo, debería crear una tabla con todos ellos (llamemosla «tabla-servos»). Estando quizá ordenada de menor a mayor, la podría consultar desde otra rutina que se ejecutase dentro del milisegundo 1 a 2. Esta se encargaría de ir poniendo a nivel bajo a los servos correspondientes en sus momentos correspondientes.
  • Por qué no utilizar el milisegundo de 0 a 1, para ordenar esa «tabla-servos». Habría que utilizar un algoritmo que lo permitiese en función de la cantidad de servos.

Entonces, estaría todo lo relativo al procesamiento de los servos entre el segundo 0 y 2, y el único interfaz de la rutina con cualquier otra rutina, sería la «tabla-servos».

¿ A alguien se le ocurre alguna otra mejora ? …

Autor: Sphinx

Robotics enthusiast

4 opiniones en “Control de servos en paralelo con PIC”

Deja un comentario