RobotyPic son proyectos básicos de electrónica con microcontroladores PIC, de aplicación en el mundo de la robótica didáctica, con archivos fuente creados mediante el compilador CCS PIC C COMPILER en lenguajeC.

Control de 8 servos con PIC

Este proyecto consiste en el control de 8 servos por el puerto c del pic. En la interacción para el control de los servos se emplea un teclado numérico y un lcd, ambos controlados por el puero b del PIC.

Esquema control 8 servos con pic


En su funcionamiento, el pic pide introducir el número del servo a controlar. Posteriormente solicita el ángulo de orientación deseado para ese servo ( de 0º a 180º). El valor se acepta con la tecla “*” y el programa vuelve a mostrar un mensaje de presentación para un nuevo control. Si el ángulo introducido es superior a 180º, el pic toma por defecto 180º.

Para la generación de las señales moduladas de control de los servos (bit_pwmx), se emplea la subrutina de interrupción por rebose del timer 0. La orientación de cada servo se establece con el valor que se carga en la variable pwmx, donde x es el número de servo correspondiente. Con cada llamada a la subrutina de generación de la señal por mediación de la interrupción del timer 0, se incrementa la variable control_pwm que comparandose con el valor en pwmx, decide si debe o no cortar alguno de los pulsos de modulación de los servos.

   control_pwm++;   
        
   if (control_pwm==0) bit_pwm0=1; 
   if (control_pwm==pwm0) bit_pwm0=0; 
 
Cuando la variable control_pwm, incrementandose en cada rebose del timer0, llega a su máximo valor y pasa a ser 0, todas las señales moduladas comienzan un nuevo ciclo.

Gráficas control servos con pic

Para interpretar los valores numéricos de varias cifras a partir de números simples introducidos por teclado, primero espera a que se pulse una tecla

x=kbd_getc();

el valor obtenido está en codificación ASCII por lo que habrá que pasarlo a su valor numérico decimal

tecla=x-48;

si se ha pulsado una tecla se descartan las pulsaciones en # y * puesto que solo se necesitan números

if (x!=0&&x!='*'&&x!='#'){

y conforme se van pulsando números el último pulsado será las unidades y los anteriores van pasando a decenas y centenas

centenas=decenas;
decenas=unidades;
unidades=tecla;

conforme se van introduciendo números simples se va mostrando el número completo por pantalla lcd

printf(lcd_putc,"\f Angulo = %ld%d%d\n", centenas, decenas, unidades);

y finalmente se guarda en una única variable el número completo resultante de todos los números simples

angulo=(centenas*100)+(decenas*10)+unidades;


[+/-] Ver / Ocultar programa completo en C



En la simulación bajo proteus se comprueba el cambio en el tiempo de las señales de control de los servos individualmente en función del valor del ángulo introducido.




Todos los archivos del proyecto se pueden descargar en este enlace:

Descargar archivos Control de 8 servos con PIC


El proyecto contenido en el artículo ha sido diseñado y probado con éxito utilizando las siguientes versiones de software:
- Windows xp y windows 7
- Proteus V7.7 SP2
- CCS PIC C COMPILER v4.084

Artículo relacionado>> PIC controlador de servos por I2C


35 comentarios:

ALARQUE dijo...

Hola, Estoy realizando un proyecto para una materia en la universidad en el cual me baso de tu proyecto, pero encuentro el problema de el giro del servomotor para ángulos diferentes de 0, 90 y 180 grados.
Te agradecería si me pudieras explicar como corregirlo.
Gracias de antemano

Alexander Aguirre R.

Chabier dijo...

No entiendo cual es tu problema. El ángulo depende del ancho del pulso de control. Si empleas un ancho de pulso en un valor entre 0,8ms y 1,5ms por ejemplo, obtendrás una giro del servo entre 0º y 90º proporcional al pulso.

ALARQUE dijo...

El problema que tenia era que cuando le daba un giro diferente de 0, 90 o 180 no me la hacia exacto, pero tomando los giros reales con los valores ingresados, sacando una tabla y sacando una ecuación, logre modificar el inicial y lograr que el servo se me mueva en los grados que le indico y que el pwm se mantenga en la ultima posición.......Muchas gracias por tu colaboración.

Camilo Valencia dijo...

hola quisiera saber si el codigo me funciona PIC16f883

Chabier dijo...

Hola Camilo.
El código sirve para ese PIC pero deberás adaptar el programa para que cargue el driver de ese PIC con el #include y emplear las direcciones de los puertos correspondientes.

DxlocuraxD dijo...

la libreria kbd.c y lcd.c podrias colgarlas???

Chabier dijo...

Las he incluido con el resto de archivos del enlace de descarga.

xban dijo...

Hola, me parece muy bueno el programa. Solo tengo una duda. La resolución del ángulo no se puede mejorar? Explico: Desde el ángulo de 169° hasta el ángulo 180°, por ejemplo, no hay variación en el movimiento del servomotor.

Robotypic dijo...

Hola xban.
Sí se puede mejorar la resolución. Depende de la combinación del valor de carga del temporizador, su división de frecuencia, de la variable control_PWM y del cristal oscilador empleado. Al pie del texto tienes un enlace para acceder al artículo "PIC controlador de servos por I2C" donde se ha empleado el mismo concepto con mayor resolución.

Julián Abreu dijo...

que se supone q son esas lineas azules?

Robotypic dijo...

Julian, ¿que líneas azules te refieres?

manuel andree mendoza peralta dijo...

quisiera saber como son las conexiones que emplean en esas lineas azules en la simulacion con proteus
porque pienso presentar este proyecto
te agradeceria bastante

Robotypic dijo...

Hola Manuel.
¿Te refieres a las lineas azules gruesas? Son buses. Agrupan en un único bus varias lineas individuales. En este enlace explican como crearlas en proteus: http://www.youtube.com/watch?feature=player_detailpage&v=iTUj5NOuGhI

Sub Zero dijo...

Muchas gracias por compartir tu proyecto!!!!!

cristian castro dijo...

Hola! Oye tengo una duda cual es el tiempo que tarda el Timer0 en descargarse es que lo tienes configua¡rado setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32); y lo cargas a 255. Entonses no entiendo cada cuanto se esta descargando.
Te Agradesco que me Resuelvas la duda :).
Y enserio Gracias Por Compartir tu Codigo.

Robotypic dijo...

Cristian.
El tiempo que tarda en rebosar el timer0 es:
T=(4/frecuencia reloj)x Preescaler x (256- carga del T0)
osea:
T=(4/4000000)x 32 x (256-255)= 0,00003 seg.
Es el tiempo entre cada acceso a la funciòn de la interrupción. Y cada vez que se accede a la interrupción se incrementa la variable "control_PWM" que es la que controla el ciclo de la señal de los servos.Cuando es 0 comenzara un nuevo ciclo de señal hasta un valor de 256 (es una variable de 8 bits). Cuando rebosa pasa a ser 0 de nuevo. Por tanto el tiempo total de la señal será:
0,00003 seg. x 256 = 8,2 msg.
El problema es que al no programarlo en ensamblador se producen retardos que aumentan este tiempo por lo que se hace necesario ajustarlo y verificarlo midiendo la señal generada.

Susan Bibiana dijo...

Oye, podrias mostrar completo el programa en C? Porq el link de arriba no me deja entrar ni ver nada. Te agradezco de antemano !

Robotypic dijo...

Susan.
El programa lo puedes ver en el enlace desplegable o bien obtenerlo en el enlace de descarga inferior.

jorli jarquin dijo...

Hola que tal?, como hago para modificar el perido y cambiarlo para 20 ms en vez e 25?, desde ya gracias, tu pograma está genial!!!

Robotypic dijo...

Jorli.
Por defecto la variable control_pwm rebosa a 255. Debes limitar el valor de esta variable a un valor inferior. Si no consigues un valor muy exacto a 20 msg. entonces deberas tambien actuar sobre la carga del contador set_timer0 y de la escala del mismo
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32)

Paco Rodriguez dijo...

Hola me podrias explica como le hago para solo controlar un servo en vez de los 8 solo quiero uno y por medio de un POT soy muy nuevo en esto :(

Robotypic dijo...

Paco. Debes elegir una de las variables referenciadas como pwm0 a pwm7, y bit_pwm0 a bit_pwm7 que son cada una para un servo y eliminar las que no desees.
Si quieres controlarlo con un pot, utiliza el conversor AD y transforma el rango del valor leído a un valor numérico de entre 7 y 21 si usas este ejemplo modificado.

Evan dijo...

Hola podra servir este codigo para implementarlo en un PIC18F4550?

Robotypic dijo...

Evan.
Sí que sirve pero configurandolo para el PIC que desees.

Yimy LOPEZ CANDIA dijo...

HOLA QUE TAL TENGO UNA DUDA SEGUN VEO LAS VEO LAS DOS LIBRERIAS (
) TIENEN UNA MISMA SALIDA EL PUERTO "D" ACASO ES POSIBLE HACER ESO. UNA DUDA MAS QUE SIGNIFICA ESTA SENTENCIA: #byte trisb=0x86
#byte portb=0x06
#byte trisc=0x87
#byte portc=0x07... GRACIAS DE ANTE MANO

Robotypic dijo...

Yimy.
Puedes controlar el teclado y el display por el mismo puerto sin problema.

Con #byte trisb=0x86 especificas la dirección de memoria del registro trisb. Lo mismo para #byte portb=0x06 en el caso del registro portb. Estos registros sirven para el control del puerto b del PIC.

Isa9910 dijo...
Este comentario ha sido eliminado por el autor.
Isa9910 dijo...

Hola, necesito ayuda para implementar el código en el 18F4550, ya configuré el puerto c para este pic, y aún así no me funciona
Agradezco cualquier ayuda

Robotypic dijo...

Isa9910. El PIC 18f4550 es diferente al 16f876a. Deberás configurar frecuencia de reloj, temporizadores, etc. de forma que la señal generada corresponda a la frecuencia que necesitan los servos; una señal de unos 20msg. con un pulso de entre 0,8 a 2.1 msg.

Erick Rivera Hernandez dijo...

hola, es un gran aporte en verdad, solo que yo uso el pic16f884 estoy configurandolo para que corra, y queria saber si sabes como puedo cambiar el teclado por otra forma de controlar los grados, tal ves botton switch o algun otro seria de gran ayuda

Robotypic dijo...

Puedes utilizar 3 pulsadores. Manteniendo pulsado uno va aumentando los grados. Con el otro disminuyen y con el tercero se acepta el nuevo valor. Con el switch puedes seleccionar los servos.

navegante7 dijo...

Hola que tal! me podrias dar una idea o un consejo sobre como posicionar un servo
digamos de forma automatica sin utilizar potenciometros ni adc,con pulsadores ya
lo he hecho y funciona bien,lo hice atravez de interrupcion por timer0...En resumen
lo que deseo es jugar con el,valga la palabra es decir que inicie en una posicion x
despues vaya a la pos max. regrese a la pos min o tambien cargar un valor a la variable pos se quede ahi un tiempo,despues cargar otro valor a pos espere un tiempo y se mueva a otro angulo,etc.
...Aqui un extracto de codigo

#int_timer0
void Pwm()
{
set_timer0(150);
cont++;

if(cont>=200)
{
cont=0;
}
if(cont<pos)
{
output_high(PIN_B0);
}
if(cont=pos)
{
output_low(PIN_B0);
}
}

while{

"Aqui tengo pulsadores para cargar el valor de pos y segun ese valor
se posiciona el servo en 0g,+90g,-90g...y funciona ok
ahora lo que quiero hacer es que se posicione en Xangulo sin utilizar pulsadores,
ni pots con adc,simplemente en forma automatica..."


}

Robotypic dijo...

Navegante7. No se si te entiendo bien. Si tu quieres cambiar la posición del servo por programación solo debes cargar el valor en la variable pos. No hay más. El procedimiento según lo que desees. P.ej. en el bucle cerrado while{} cargar en pos un número aleatorio generado con rand() entre 2 límites para que el servo se posicione aleatoriamente, con un retardo.

erick solis dijo...

Se pueden controlar 12 servomotores con este programa usando el pic 16f877A

Robotypic dijo...

Puedes controlar tantos servos como pines de salida libres tengas en el PIC.

Related Posts Plugin for WordPress, Blogger...

CONTACTA - (Haz referencia del artículo sobre el que trata la consulta o comentario)

*
*
*
*
*
contact form faq verification image

Web form generated by 123ContactForm