jump to navigation

Controladora 32 servos (Open Source) 17 diciembre, 2008

Posted by ubanov in Electrónica.
Tags: , , , , , ,
trackback

Reciéntemente he comenzado a hacer un robot hexapodo, para controlarlo necesito poder gestionar hasta 18-20 servos. Como esto es un proyecto para aprender, he decidido hacer la placa de control yo mismo (en lugar de usar la SCC32).

En principio mi placa usará un procesador Microchip PIC (inicialmente el PIC16F877A, aunque este tiene menos de 32 pines disponibles), y sobre estos conectaré los servos. El control de los servos irá por interrupciones. Para hacer un control muy exacto de las posiciones, todo el programa lo voy a hacer en ASM.

Al funcionar por interrupciones la misma placa podría tener la gestión del robot y el control del mismo (aunque tengo claro que este no es mi objetivo final).

Actualización: Cuando cree el post se me olvidó poner el codigo fuente de lo que tengo… (creo que casi está pero me falta probarlo en chip)

Por ahora no funciona y está en fase de diseño/desarrollo. Pongo el source según lo tengo, por si alguien quiere dar ideas sobre el desarrollo.

Copio la descripción que está en el fuente de cómo va a funcionar:

; Descripción:
;
; La gestión de los servos se hace mediante interrupciones. Dado que queremos conseguir que
; cada 20ms se le envíe una señal a cada servo, lo que se va a hacer es dividir esos 20ms entre
; 8 ciclos de 2,5ms. En cada ciclo de 2’5ms se gestionarán 4 servos.
;
; La forma de gestionar los servos se basará en gestionar el Timer1 del PIC (es un timer de 16bits).
; Para la gestión del grupo de 4 servos lo que se hará es ordenar los tiempos de cada pulso de menor
; a mayor.
;
; Por ejemplo si tuviesemos: Ser0=0,7ms   Ser1=2,3ms   Ser2=0,7ms   Ser3=1,9ms
; Trataríamos primero Ser0, luego Ser2, luego Ser3 y por último Ser1
;
; Lo primero que se hará es poner a 1 cada uno de servos uno detrás de otro. Para ello generaremos
; 4 interrupciones, separadas por 0,05ms (50us) en la que iremos poniendo cada servo a 1 en orden.
; Una vez que acabemos con estas 4 primeras interrupciones, comenzarán las interrupciones de poner
; a 0 cada uno de los servos en el mismo orden.
;
; En nuestro ejemplo lo que se haría es:
;  El primero (Ser0) se pondrá a cero después de Ser0-0,150ms=0,7-0,15=0,45ms (tiempo entre 3 y 4)
;  El segundo (Ser2) después de Ser2-Ser0+0,05=0,7-0,7+0,05=0,05 (tiempo entre 4 y 5)
;  El tercero (Ser3) después de ser3-Ser2+0,05=1,9-0,7+0,05=0,85 (tiempo entre 5 y 6)
;  El cuarto (Ser1) después de ser1-Ser3+0,05=2,3-1,9+0,05=0,45 (tiempo entre 6 y 7)
; Aquí se habrían puesto todos a 0 otra vez. Esperaríamos 2,5-0,05*3-Ser1=2,35-2,3=0,05 (tiempo entre
; 7 y 0) y empezaríamos otro ciclo con otros cuatro servos.
;
; De forma grafica sería según el siguiente gráfico:
;
;

; Int   0   1   2   3                           4   5         6      7    0
;       |   |   |   |                           |   |         |      |    |
;       v   v   v   v                           v   v         v      v    v
;
;       +---------------------------------------+                         +--
; Ser0 _|                                       |_________________________|
;           +---------------------------------------+
; Ser2 _____|                                       |________________________
;               +---------------------------------------------+
; Ser3 _________|                                             |______________
;                   +------------------------------------------------+
; Ser1 _____________|                                                |_______

;
;
; Para que todo funcione hay que establecer algunos límites. El tiempo de cada servo puede estar a uno
; será como máximo 2,3ms y el mínimo 0,3ms (en realidad se podría bajar hasta 0,2 pero creo que no hay
; ningún servo que trabaje en este rango). Esto nos va a dar que el tiempo mínimo entre dos interrupciones
; va a ser 0,05ms (50us). En este tiempo nos tiene que dar tiempo para ejecutar la rutinas de interrupción
: completa. A 4Mhz (que no creo que de tiempo) podríamos ejecutar 50 instrucciones, a 20Mhz 250
; instrucciones. Cuando acabe haré la suma de tiempos para comprobar el procesador mínimo.
;
; Para que el tiempo sea muy exacto lo que se ha hecho es que en cada ciclo lo primero que se hace es poner
; el bit al valor que sea y después calcular el valor del siguiente bit a cambiar (y los tiempos y todas

; esas cosas).;; Por la forma que se ha hecho el control de tiempo va a ser muy exacto (está hecho en ASM para tener
; control exacto hasta el nivel de instrucción).
;
; El “problema” que hay es que el PIC en el que yo estoy pensando (Pic16F877A), no tiene 32 salidas
; disponibles para poner 32 servos :-D  Pero tampoco tengo proyecto para poner más de 20 servos🙂
; Se podría hacer con chips externos o con otro pic más grande utilizando la misma lógica.
;
; Con esta misma idea se podría aumentar el tiempo de cada servo a más de 2,3 (por ejemplo 2,5) bajando
; el número de servos a controlar (por ejemplo si controlamos 7*4=28 servos, tendríamos 20/7=2,85ms para
; cada grupo de servos). De esta misma forma se podría también bajar la frecuencia de reloj (por ejemplo,
; si controlasemos 5*4 servos, podríamos hacer cada ciclo de 4 servos en 20/5=4ms, de esta forma
; podríamos tener (4-2,3)/4=425us para ejecutar las instrucciones de la rutina de interrupción.
;
; No debemos añadir nuevos tipos de interrupciones en este programa (afectaría a la exactitud del tiempo).
; Lo que si se podría hacer es añadir pequeñas gestiones en la rutina de interrupciones. Inicialmente
; pensé en meter la gestión del puerto serie ahí, pero no se puede. A 38400 bps podríamos recibir un
; byte cada 1/3840=260uS, y las interrupciones de 3-4 (la más larga) podría ser hasta de
; 2,3-0,15=2150uS (por lo que se podrían recibir más de 8 caracteres, por lo que nos perderíamos).
En un primer momento añadiré la gestión básica del control de los switches, según lo que he descrito antes. Posteriormente haré cosas como gestionar que el servo se mueva 90º en 1 segundo… (igual que hace el scc32). Creo que es sencillo y la idea es tener guardado de cada servo el punto donde estás, el punto donde quieres ir y el tiempo que tiene que tardar en ir de un sitio a otro. Entonces cada 20ms (50 veces por segundo) calcular la nueva posición… (20ms es el tiempo que se tarda en informar a cada servo de que vaya hacia una determinada posición).

Link al fichero fuente: No se porqué pero me está dando problemas. Probad en el link https://ubanov.files.wordpress.com/2008/12/controlservos_09.doc o sino  mandadme un mail/comentario y os la envío.

Comentarios»

1. Sele - 2 enero, 2009

Ubanov, este comentario va sobre el tema del reconocimiento de voz. Te lo copio aqui para ver si asi lo ves antes. Yo estoy intentando hacer una aplicacion domotica que actue sobre las luces y para ello necesito que linux reconozca comandos muy sencillos, de una sola palabra o dos, y que una vez detectados estos comandos ejecute un script que mandara los comandos on/off al modulo de las luces.
Buscando por internet he encontrado un programa llamado Perl-Box que segun he leido parece que puede ejecutar aplicaciones con palabras sencillas, como “Music” para abrir el reproductor de musica y demas, pero me da problemas al instalarlo. Tambien he encontrado uno llamado Simon que parece muy bueno por los comentarios pero que tampoco puedo instalarlo (tengo serios problemas con la instalacion en linux).
Tu post me ha interesado mucho pero no se si tanta configuracion es algo excesivo para lo que yo quiero hacer ¿¿tu que crees?? ¿Como harias tu para ejecutar script mediante comandos de voz? Es que ando algo perdido en el tema y me vendrian muy bien tus respuestas.

2. Deviker - 18 julio, 2010

Hola, justamente estaba buscando una alternativa libre al scc32, lo has terminado? lo has puesto con alguna licencia libre?

3. asyncronick - 28 diciembre, 2010

hola, estimado pudiste terminar tu placa controladora?

ubanov - 11 enero, 2011

no, al final me he dedicado a otras cosas….

Os invito a que la acabéis alguno de vosotros😀


Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: