“CONTROL DE UNA CÁMARA MEDIANTE JOYSTICK”148.206.53.84/tesiuami/UAMI10577.pdf · • La...
Transcript of “CONTROL DE UNA CÁMARA MEDIANTE JOYSTICK”148.206.53.84/tesiuami/UAMI10577.pdf · • La...
DIVISIÓN DE CIENCIAS BÁSICAS E INGENIERÍA
DEPARTAMENTO DE INGENIERÍA ELÉCTRICA
REPORTE DE PROYECTO TERMINAL
“CONTROL DE UNA CÁMARA MEDIANTE JOYSTICK”
Asesor: Alejandro Martínez González
Alumno: Enrique García Carbajal
1
OBJETIVOS
• Controlar el movimiento de una cámara por medio de un joystick.
• Habilitar un botón de disparo.
• Transmitir en forma serial el estado del botón de disparo y las coordenadas del
joystick.
INTRODUCCIÓN
Hoy en día, con los avances tecnológicos tenemos muchas libertades en lo que
respecta a medios realización, lo único que nos limita es nuestra propia inventiva.
Cuando nosotros pensamos en una cámara de vigilancia nos imaginamos una
cámara rígida como las que utilizan los bancos que solo tienen cierto campo de
visualización; también existen ya, cámaras que tienen movimiento, con las cuales se tiene
mas campo de visualización, sobre todo para poder seguir objetos en movimiento.
Es así como empieza la idea de nuestro proyecto: manejar el movimiento de una
cámara por medio de un joystick de tal manera que la cámara siga el movimiento de la
palanca casi de forma simultánea y con un buen nivel de precisión, haciendo esto, talvez,
de forma remota por medio de telemetría.
Los requisitos anteriores invitan al requerimiento de microcontroladores, debido a la
orientación a puertos. De éstos debemos escoger los más adecuados en cuanto a versatilidad
y tamaño, y los microcontroladores de la empresa Microchip, “los PIC”, cumplen a la
perfección con lo anterior.
Los PIC están ocupando un lugar de privilegio dentro de la industria electrónica,
gracias a la facilidad de implementar programas con un set reducido de instrucciones y a la
importancia que poseen sus características.
Características del PIC
Esta familia de microcontroladores PIC se destaca por las siguientes prestaciones:
• Sólo se necesitan 35 instrucciones de una sola palabra para usarlo.
• Todas las instrucciones son de un solo ciclo con excepción de las ramificaciones del
programa que son de dos ciclos.
2
• La velocidad de funcionamiento es de DC a 20MHz a la entrada del reloj y de DC a
200ns (nanosegundos) en el ciclo de instrucciones.
• La memoria del programa generalmente tiene capacidad 1024 palabras (1kB).
• La memoria RAM de datos es de 68 bytes.
• La memoria de datos EEPROM es de 64 bytes.
• Las palabras de instrucciones tienen una extensión de 14 bits.
• Los bytes de datos tienen una extensión de 8 bits.
• Posee 15 registros de hardware de funciones especiales.
• Tiene una pila de hardware de 8 niveles.
• Procesa modos de acceso directo, indirecto y relativo.
• Tiene por lo menos cuatro fuentes de interrupciones.
- Pata externa RB0/INT.
- Exceso del temporizador TMR0.
- Interrupción al cambio PORTB<7:4>.
- Al completar la escritura del EEPROM de datos.
• Fuente de alta corriente para excitación directa de LED’s.
• Watchdog Timer (WDT).
• Modo SLEEP para economizar consumo.
Los PIC16F62X disponen de un módulo USART capaz de soportar la comunicación
serie síncrona y asíncrona; de los dos modos de funcionamiento del USART, la
comunicación serie asíncrona es la más utilizada.
El USART, llamado SCI (Serial Comunications Interface), puede funcionar como
un sistema de comunicación full duplex o bidireccional asíncrono, adaptándose a multitud
de periféricos y dispositivos que transfieren información de esta forma. También puede
trabajar en modo síncrono unidireccional o half duplex para soportar periféricos como
memorias, conversores, etc. Es decir el USART puede trabajar de tres maneras:
• Asíncrona (Full duplex, bidireccional).
• Sincronía-maestro (Half duplex, unidireccional).
• Sincronía-Esclavo (Half duplex, unidireccional).
3
La transferencia de informaciones realiza sobre dos líneas TX (transmisión) y RX
(recepción), saliendo y entrando los bits por dichas líneas al ritmo de una frecuencia
controlada internamente por el USART.
En la forma de comunicación serie es común usar la norma RS-232-C, donde cada
palabra de información o dato se envía independientemente de los demás. Suele constar de
8 o 9 bits y van precedidos por un bit de START (bit de inicio) y detrás de ellos se coloca
un bit de STOP (bit de paro), de acuerdo con las normas del formato estándar NRZ
(NonReturn-to-Zero). Los bits se transfieren a una frecuencia fija y normalizada.
Los cuatro módulos que configuran la arquitectura USART, modo asíncrono, son:
• Circuito de muestreo.
• Generador de Baudios.
• Transmisor Asíncrono.
• Receptor Asíncrono.
Protocolo estándar En el protocolo estándar se transfieren 10 bits, un bit de inicio, 8 bits de datos y un
bit de paro, formando una palabra de 10 bits.
Para saber si hubo errores en la transmisión puede utilizarse un bit de paridad el cual
indica el error. Por ejemplo: en el byte 00111100 se tienen 4 unos por lo que al bit de
paridad se le asigna un 0 y se dice que tiene paridad par y en el byte 10111100 se tienen 5
unos por lo que al bit de paridad se le asigna un 1 y se dice que tiene paridad impar.
Registro de configuración del hardware
• TXSTA. Registro de configuración de la transmisión serial.
• RCSTA. Registro de configuración de la recepción serial.
• SPBRG. Contador programable digitalmente que configura la velocidad de
transmisión.
Generador de baudios
En el protocolo asíncrono RS-232-C, la frecuencia en baudios (bits por segundo) a
la que se realiza la transferencia se debe efectuar a un valor normalizado: 330, 600, 1200,
4
2400, 4800, 9600, 19200, 38400, etc. Para generar esta frecuencia, el USART dispone de
un Generador de Frecuencia en Baudios, BRG, cuyo valor es controlado por el contenido
grabado en el registro SPBRG.
Además del valor X cargado en el registro SPBRG, la frecuencia en baudios del
generador depende del bit BRGH del registro TXSTA<2>. En el caso de que BRGH = 0 se
trabaje en baja velocidad y si BRGH = 1 se trabaja en alta velocidad. Según este bit se
obtendrá el valor de una constante K necesaria en la determinación de la frecuencia de
funcionamiento.
Frecuencia en Baudios = FOSC / ( K * (X + 1) ).
X es el valor cargado en el registro SPBRG (valor expresado en decimal y que debe
ser un número entero entre 0 y 255).
Si BRGH = 0, baja velocidad y K = 64.
Si BRGH = 1, baja velocidad y K = 16.
Transmisor asíncrono
El dato que se debe transmitir por el USART transmisor se deposita en el registro
TXREG y a continuación se traspasa al registro de desplazamiento TSR, que va sacando los
bits secuencialmente y a la frecuencia establecida. Además, antes de los bits del dato de
información incluye un bit de inicio y después de sacar todos los bits añade un bit de
parada. El USART receptor recibe, uno a uno, los bits, elimina los dos de control y los de
información una vez que han llenado el registro de desplazamiento RSR los traslada
automáticamente al registro RCREG, donde quedan disponibles para su posterior
procesamiento.
Receptor asíncrono
Los datos se reciben en serie, bit a bit, por la patita RX y se van introduciendo
secuencialmente en el registro desplazamiento RSR, que funciona 16 veces más rápida que
la de trabajo.
Cuando un procesador maestro intenta enviar información a uno de los esclavos,
primero envía un byte de dirección que identifica al destinatario. El byte de dirección se
identifica porque el bit RX9D que llega vale 1. Si el bit ADDEN = 1 en el esclavo se ignora
5
todos los bytes de datos. Pero si el noveno bit que recibe vale 1, quiere decir que se trata de
una dirección y el esclavo provocará una interrupción, y se transferirá el contenido del
registro RSR al buffer de recepción. Tras la interrupción, el esclavo deberá examinar la
dirección y si coincide con la suya poner ADDEN = 0 para poder recibir datos del maestro.
Si ADDEN = 1 como los datos son ignorados, el bit de parada no se carga en RSR,
por lo que este hecho no produce interrupción.
Controladores (Drivers)
En realidad no es indispensable usar controladores de motor de pasos de circuitos
integrados, que son muy importantes cuando se quiere obtener un espacio reducido. Se
puede obtener un buen funcionamiento usando un puerto digital de un computador o del
PIC y una interfaz de potencia.
Como ejemplo básico, para controlar un motor de paso con el puerto de salida de
una computadora, se asume que la resistencia de la bobina es la suficiente para limitar la
corriente, si no fuera asi necesitaremos resistencias en series, o aun mejor, transistores de
potencia como limitadores.
Fig 1. Circuito de manejo de motores unipolares con tap
Cada bobina en el motor de pasos requiere un transistor Darlington, un diodo, una
resistencia y uno de los 6 buffers del integrado TTL 7406.
Para motores pequeños o de bajo consumo de corriente (cientos de miliampers por
bobinas), existen chips como el ULN2003 que contienen transistores Darlington integrados,
y pueden ser manejados con lógica TTL o CMOS.
6
Si el motor tiene 4 (3) bobinas, generalmente presenta 5 (4) cables porque un cable
es común a las demás bobinas y puede ser de reluctancia variable. El cable común va a la
fuente de alimentación.
Si el motor tiene dos bobinas con tap central y 6 cables, es probable que se trate de
un motor de imán permanente, donde el tap central va conectado a la fuente de
alimentación (a veces a través de un limitador de corriente).
El manejo de los motores de imán permanente bipolares que tienen 2 bobinas sin tap
central es más complicado.
Según el siguiente circuito, las entradas A y B pueden ser manejadas por salidas
TTL de colector abierto. La bobina del motor se energizará si una de las entradas esta en
alta y la otra en baja. Si ambas entradas están en baja, los transistores pull-down Q1 y
Fig 2. Circuito de manejo de motores bipolares sin tap (circuito H-bridge)
Q4 estarán en corte, si ambas entradas están en alta, ambos transistores pull up Q2 y Q3
estarán abiertos. Se puede notar los 4 diodos que conectan los terminales de la bobina del
motor hacia la alimentación y tierra. Normalmente están inversamente polarizados, pero al
7
apagarse la bobina o al cambiar el sentido de la tensión, se polarizan directamente mientras
demore extinguir la corriente de la bobina.
Configuración de los motores a pasos
Los motores a pasos (PaP) difieren en gran medida de los motores que todos
conocemos de CC (corriente continua). Al aplicar a sus bobinas un conjunto adecuado de
impulsos eléctricos éstos giran sobre su eje un ángulo fijo, este ángulo recorrido que
depende de las características del motor, se le llama paso, de forma que se puede controlar,
mediante un circuito electrónico, la cantidad, velocidad y sentido de los pasos.
Hay dos tipos básicos de motores PaP, los bipolares que se componen de dos
bobinas y los unipolares que tiene cuatro bobinas.
Fig 3. Esquema Motor BIPOLAR Fig 4. Esquema Motor UNIPOLAR
Externamente se diferencian entre sí por el número de cables. Los bipolares solo
tienen cuatro conexiones dos para cada bobina y los unipolares que normalmente presentan
seis cables, dos para cada bobina y otro para alimentación de cada par de éstas, aunque en
algunos casos podemos encontrar motores unipolares con cinco cables, básicamente es lo
mismo, solo que el cable de alimentación es común para los dos pares de bobinas.
Otra característica son los pasos que da el motor para girar una vuelta completa, los
más comunes son de 48, 100 y 200 pasos, depende del tipo de husillo y la precisión que
queramos obtener elegiremos un motor u otro.
Un problema que se nos puede plantear es como saber cual es cada polo de la
bobina, ya que los colores no están estandarizados. Así que tomamos el tester y leemos el
valor (resistencia) de todos los polos (supongamos que las bobinas son de 30 Ohm.), el
8
común (alimentación) con cada polo de bobina leerá 30 Ohm y entre polos de la misma
bobina 60 Ohm., por eliminación nos será fácil encontrar los polos de las bobinas. Si nos
equivocamos no pasa nada, solo que el motor no girará. Cambiando el orden de dos de los
polos de una bobina cambiamos el sentido de giro. Si el motor solo tiene cinco cables, el
común de alimentación se puede conectar a cualquiera de los lados.
Motores unipolares
Son relativamente fáciles de controlar. Su característica principal es tener un tap
central, de manera que es esquema de cableado es tomar el(los) tap(s) central(es) y
conectarlos a la fuente de alimentación positiva. El circuito controlador se encargará de
poner cada bobina a tierra para energizarla de manera secuencial. El número de fases es el
doble al número de bobinas, ya que cada bobina es dividida en dos por medio del tap
central.
Fig 5. Paso estándar de un motor a pasos
La tabla siguiente muestra con más claridad el funcionamiento del motor al ser
excitado mediante la secuencia anterior.
9
Fig 6. Polarización de las bobinas del motor a pasos mediante la secuencia estándar
En adición a la secuencia de manejo estándar, una secuencia de manejo a medio
paso y otra de gran torque son posibles. En la secuencia de gran torque, 2 bobinados están
activados al mismo tiempo para cada paso del motor. En este caso el torque es 1.5 veces
mas que el entregado en una secuencia estándar, pero maneja el doble de corriente. La
secuencia de manejo a medio paso es la combinación de las 2 anteriores. Primero una
bobina es activado, luego dos bobinas, luego una, etc. Esto hace que le número de pasos por
revolución sea el doble y el ángulo por paso se reduzca a la mitad.
!
11
ESTADO DEL ARTE
Esta sección muestra algunos equipos y desarrollos encontrados.
#1
• CONTROL DE SOBREMESA • CONTROL DE UNA CAMARA • POSICION PARA AUTO-PAN • CONTROL POR MULTICABLE • CONTROL POR JOYSTICK
El CPM-Z es un controlador de sobremesa para una cámara, y controla directamente los motores del posicionador (220 Vca) y la óptica (12Vcc). A través de este equipo podemos controlar los movimientos del posicionador (arriba, abajo, derecha e izquierda) a través del joystick integrado en el panel frontal, donde también podemos encontrar el switch de Auto-pan. También en el panel frontal se hallan los controles de zoom, foco e iris para el control de ópticas. Es especialmente indicado en instalaciones con poca distancia al punto de control. En distancias largas debe tenerse muy calculada la perdida de tensión, pues es baja tensión (6-12 Vcc)
12
#2
Fabricante: Inframetrics
Características:#"%$'&%( $)#"%$'&%( $)#"%$'&%( $)#"%$'&%( $)+*,-.,/'/+0 123*,4+567/'8:958'-.5; <=?>@+5,6.25+A,8B958'-.5CED;=?>@EA,9F /+GH 8958'-.5CI=?>KJL,6.8?M2+58B958'-.5N='>
Historial:O 5QPSRUTWVYXZR[95\*M0 8,]+5*Q67,/+0 ,M2'-.,>B,2?-.,\*8^/?_>B56758-7`6a>0 /'58b*,cH 56.de5H /?52+/',T 2'a675>B,+-%6a0 /'8TRfg !!MhO *,-%0L?i0 2'a6756a6.kj7@L+5675H 5;/'>;L+5]F 5*,0 2?-.,H 0 d,M2/+0 5l O 58m*8/?_>B56758n-.`6a>:0 /?58n8?2^*,Ho-%0L?p0 2'a6756a6.qj%@S8?2^/?5L+5/?,8n*,e*,-.,/k-.56Z5\8?H *5*8n5G25i*0 8E-752+/0 5*,rNCs>@A+,9F/GH 85:s#>;@5,6.25+A+,85'Dts>uJ4+567/E85 <Cs>lv H?80 8'-.,>B5;8,;/'M>LM2+,;*,;*8B,H ,>B,M2'-w8@H 5rL6.ML0 5/?_>B5675;xG+,:A5i>m2'-75*58?M467,G2Q-%6yFWL*,z/'M2KH 5uL?80 40 H 0 *5*z*,z8?,60 2?8'-.5H 5*5K8?M467,G2K>B_8'-%0 HU,H ,A5*6,M2|G2A,9F /+GH @J*,H~>31*GH n*,>35M2?*n/'2G2>3M20 -.6*,ckmL+5675H 5b4+8?,6A5/+0 12t*,HM4ja,+-%0 AJG2>35M2?*-%0 L+ErL+5675,H>3+A0 >0 ,2?-w*,nH 5/?_>35675JG2L+52+,H*,/'M2?-%6.MH l v 8E-758/?_>B567583aG2/+0 25M2;/E24+5-.,6yF58xG+,tH ,CL67ML67/+0 25M2G2+55G?-.M2>F 5*,tk9M6758I*,:4+8?,6A5/+0 12l
14
#5
Una vez más, se presenta un reto a la oscuridad para la aplicación de la ley tanto en tierra como en navegación marítima. La Cámara NightSight 4000B es la última solución en imagen térmica para aplicación de la ley, seguridad y operaciones especiales de vigilancia. Como sucesor de la cámara Nightsight 200, la cámara Nightsight 4000B consta de una cámara de vídeo infrarroja y un posicionador. La cámara y el posicionador funcionan por medio de un controlador joystick permitiendo al operador orientar la cámara modificando el azimuth y la elevación. La imagen de vídeo infrarroja y la información del posicionador se muestran en un monitor de vídeo. El sistema está diseñado interna y externamente para utilizarse como una unidad móvil y para resistir condiciones climatológicas adversas. Su arquitectura está diseñada para permitir futuras actualizaciones opcionales tales como posibilidad de grabación en vídeo y escaneo.
Eoo 3~ o Eoo 3~ o Eoo 3~ o Eoo 3~ o 7¡+¢
£¤ ¥y¦ §%¨ª©« ©«¡ª©©y¬+ 7¡yE®¥¢¯¡yE®¥+©y¬M° ±% ²«¨+¢
¯¥«¨³ ¤ ¥«´%©y¬° µ ©ª¬y¥q¶ %¥«¨³ ¤ ¡y±« ¬+¢£¥«´ ¡y¤ ©«¡ª© ¨ª¦ ¤ ¡y¤ ¤ ¥ ·W¡+¢¸®¡y´ ©«¡+©y¬° µ ©y¬y¥+¢
¹º ¬«¨y±% ¥«¨ª¬«±?©y¬?´ ¡ 7»y¡y¤ ¡+¢£¬«±a¥+©y¬?´ ¡ 7»y¡y¤ ¡+¢
¼ ¨y 7 ¥q½¡y¤ ¡ +¡7¾®¬«¨+©ª¬M° µ ©y¬y¥¼ ¿¢¹º ±« ¡y¨ª 7 ¡+©ª¬©y¬ª ¬y % 7 ²«¨¢¿º¬«±«¥«´ §a 7 ²«¨©y¬? +¡7¾®¬«¨+¢
À%¥«´ ¡ ·¬+©y¬¦ §%¨ª 7 ¥«¨y¡y+ ¬«¨³ ¥+¢¿º¥ª ¡ª 7 ²«¨¢
Áª¡³ Ây ´ ©«¡ª©¢¼ ¨³ ¬«¤ ¦ ¡ª %¬«±?©y¬¦ §%¨ª 7 ¥«¨y¡y+ ¬«¨³ ¥
à ©y¬«±a©y¬+¬«´ ·¥.¶ª±« 7ÄÅq¢¼ ¨ª¦ ¥«¤ +¡ª 7 ²«¨+©y¬«´®¥«±% % ¥«¨y¡ª©y¥y¤½¢
Æw¬«k®¬«¤ ¡³ §%¤ ¡©y¬¦ §%¨ª 7 ¥«¨y¡y+ ¬«¨³ ¥¢¸®¥7®¥«¤ ¬©y¬+ 7»y+¡y¤ ¡E½¡y¤ ¡ ¬y 7Ǫ¥+¢
¹ ¬«¨y±% ¥«¨ª¬«±'¢£¬«±a¥ ¢
ÈaÉ ÊaË ÌͪÎ+ÏyÐ ÑyÒÓaÔyÒ7Õ ÔѳÖ7Ð ×7Ø Ð ×yÐ Õ ÙÊ.Í«Ú½ÛÜaÚÝqÞ%Õ Ù³ß?à«Õ Ð á%ÙâÖ Ô³×aá%Ùyã äºÔ³Ö Рѳ×%Õ Ñåæ ÝèçéãWÊ7êyÌͪë?á«ß+ì Ô³×aá«ÓaÙyíªÛͪî?á«ßì Ô³Ö Õ Þyï ÔyíªÛͪî?á«ßì Ïyï Ù«Ø Þy×að³Ð ðyÔyðyíñò½ó Î+ô7õöË÷yÌ?Ò%Ѫõ³Þy×aðyÙyÒì ×aÙ³ï ß'Ô³Ö íøÑyÕ Ñyá7Õ ÔÞª×aÔÏaѳï Ò%Ù³×aÔÓaÔyÒ7Õ ÔÊ7ÎyÌyÌÏyÐ ÑyÒÊ7÷yÌEÛÊ.ͪÌÏyÐ Û«Ñ³Ö ÒøÑÜÔÊ7÷'ùkøä~ì Ê7Í'ùkøä~×aÙ³ß+Ð ×aÔ³Ö íîy÷yÌaÚðyÑ'Ø Ù³ï ß'Ô+á%Ù³×%Õ Ð ×yÞaÔ+á%Ù³×%Õ ï Ù³Ö ÔyðyÙÏaÙ³ï.ú Ù«û«Ò7Õ Ð á«ôã Ê7÷aÚ É ü ò ÌaÚðyÑyÒaðyÑÖ ÔÓ«Ù³ï Ð ýaÙ³×%Õ ÔöÖwá%Ù³×%Õ ï Ù³Ö ÔyðyÙÏaÙöï.ú Ù«ûaÒ%Õ Ð á«ô
þ?ÿ®É þ?ÈöÈ ó áaÙ³×%Õ ï Ù³ÖwðyÑÏaÙyÒ«Ð á«Ð Ù³×aÔ³ß+Рѳ×%Õ Ùæ ×að³Ð á%Ôyá«Ð ³×?õ³ï àaØ Ð áaÔѳ×?ѳÖ7ß?Ù³×yÐ Õ Ù³ïøѪÒ%ðyÑã ò ÌaÚÓaÔyÒ7Õ Ô+ÎyÎaÚ äë ó Í+á«ßì Ô³Ö Õ Þyï ÔyíªÛͪîá«ßì Ïyï ÙaØ Þy×að³Ð ðªÔyðyíÝq×aá«ÓaÙÔyðªÔ³Ï%Õ ÔyÖ Ñ+Ô³ÖaÑ³Ó á«ÞyÖ ÙÎ+ô.õöË
15
DESARROLLO DEL PROYECTO
Debido que los objetivos no son en demasía restrictivos, podemos optar por una
combinación de componentes que, según criterios y razones, son elegidos. Por ejemplo, si
se desean implementar servomotores, necesitamos una modulación por ancho de pulso, sin
embargo, la referencia es ya implícita en éstos; que por el contrario, al elegir motores a
pasos son necesarias dichas referencias. Consecuentemente, se debe elegir un PIC
compatible con la elección (que tenga convertidores analógico/digital o comparadores y
además, puerto serial dúplex y puertos necesarios que se pretenden utilizar, así como un
tamaño de memoria adecuado).
Haciendo un balance entre costo, reducción de diseño y efectividad; la alternativa
que optamos grosso modo fue utilizar dos motores a pasos, de 200 pasos por revolución;
dos temporizadores NE555 en modo monoestable y dos PIC16FX628. La figura 8 muestra
el diagrama a bloques:
pic1 pic2
Fig 8. Diagrama a bloques del diseño
El PIC del Joystick (PIC1)
El efecto de mover la palanca del joystick, es variar la resistencia de dos
potenciómetros; uno para cada eje. Éstos harán que el ancho del pulso de cada monoestable
cambie. Para que el monoestable mantenga ese ancho, necesita ser excitado con un
“trigger” de lógica inversa (se utilizará la palabra “trigger” para distinguir entre el
“disparo” por impulso eléctrico que recibe el monoestable y el disparo físico que provoca el
botón del joystick). A continuación se muestra el diagrama de modo monoestable.
555
555
PotX
PotY
joystick
PIC16F628
Trigger
X
Y
Boton PIC16F628
Tx
Rx
Motor X
Motor Y
Ref X
Ref Y
Disparo
16
C
Fig 9. Modo monoestable para el C.I.. NE555
RA es sustituida por uno de los dos potenciómetros del joystick que, junto con el
capacitor C, logran un ancho de pulso de aproximadamente tw = 1.1 RAC.
Se asigna una pata de algún puerto como salida, para mandar el trigger a los dos
monoestables; y otras dos patas como entrada para los pulsos.
El paso siguiente es, asociar a ese pulso una palabra de bits. Entonces, el PIC revisa
constantemente (por software) los pines de entrada para saber el momento en que los
anchos de pulso caen (este proceso se denomina “encuesta” o “poleo”).
El PIC debe ser capaz de “echar a andar” los monoestables; es decir, generar el
trigger de entrada a éstos, e inmediatamente después asociar de acuerdo al tiempo de caída
del ancho una palabra de bits. El proceso anterior debe realizarse simultáneamente para
cada eje, que para esto el PIC inicializa un timer de 8 bits con periodo de desbordamiento
mayor o igual al máximo valor posible de la salida del monoestable (Td≥TA). Utilizando
dos registros de propósito general, se guardan las palabras asignadas de cada eje listas para
ser transmitidas vía serial.
Eligiendo un preescalamiento de 1:4 y un oscilador de 4MHz; el timer se desborda
en 1 X 10-6 X4 X 256 = 1.024ms Posibles palabras con 8 bits (28)
Preescalamiento Ciclo de reloj (fosc /4)
Sabiendo que los potenciómetros del joystick son de 100kΩ, podemos saber el valor
requerido del capacitor de la siguiente manera:
17
Fµ0093.0C)X10100(1.1
1.024X103
-3 ==
Y aproximamos a un valor comercial de 0.01µF
Entonces el máximo ancho de pulso posible es
tw = 1.1(100X103X0.01X10-6) = 1.1ms
Si llegase a muestrear tal ancho de pulso, el timer se desbordaría antes que termine
dicho pulso. Sin embargo, el joystick tiene un rango pequeño (alrededor de 60kΩ). Así, los
potenciómetros oscilarán entre 20 y 80kΩ; asegurando una palabra para ese rango.
El botón también tiene asignada una pata de puerto que puede ser revisada mediante
una rutina antes de la inicialización del timer o después del desbordamiento de éste.
Posteriormente se espera la petición del PIC que controla los motores para transmitir
vía serial y se envía la palabra asignada al eje X, después al eje Y y por último, la palabra
del botón.
Con el diagrama de flujo intentaremos explicar las acciones y decisiones que el PIC
debe realizar.
18
Inicio
Inicializo Macros,Declaro variables.
mando trigger
entXalto?
cuentaX<-tmr0
si
entYalto?
cuentaY<-tmr0
si
overflow?
transmitrequest?
si
no
no
no
TXREG<-cuentaY
TXREG<-botonreg
si
no
TXREG<-cuentaX
disparo?
si
botonreg<--00h botonreg<--FFh
no
19
Despliegue del programa para el PIC 1
En esta sección se despliega completamente el programa documentado.
Posteriormente se explica cada bloque de éste así como sus rutinas. Puede observarse que
solamente es la traducción del diagrama de flujo a lenguaje ensamblador del PIC.
Para el PIC que asocia una palabra al ancho del pulso de cada monoestable
(coordenadas X e Y), el programa es el siguiente:
;*********************************************************************
; PROYECTO TERMINAL *
; ENRIQUE GARCIA CARBAJAL y CESAR AUGUSTO RENTERIA ORTEGA *
; PIC#1 *
;*********************************************************************
;-*-*-*-*--*-DECLARANDO Y CONFIGURANDO EL MICROCONTROLADOR-*-*-*-*-*-*
PROCESSOR 16F628
#INCLUDE <p16f628.inc>
errorlevel -302
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
;*-*-*-*-*-*-*-*-*-*-*-DECLARANDO MACROS-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
BANK0 MACRO
BCF STATUS,RP1
BCF STATUS,RP0
ENDM
BANK1 MACRO
BCF STATUS,RP1
BSF STATUS,RP0
ENDM
BANK2 MACRO
BSF STATUS,RP1
BCF STATUS,RP0
ENDM
BANK3 MACRO
20
BSF STATUS,RP1
BSF STATUS,RP0
ENDM
;*-*-*-*-*-*-*-*-*-*-*-*-DECLARANDO VARIABLES*-*-*-*-*-*-*-*-*-*-*-*-*
cuentaX equ 23h ;este registro se encuentra en 23h
cuentaY equ 24h ;este registro se encuentra en 24h
wdt_trig equ 25h
dato equ 26h
bandera equ 27h
datoRx equ 28h
boton equ 29h
;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
;*-*-*-*-*-*-*-*-*-*-*-*-PROGRAMA PRINCIPAL*-*-*-*-*-*-*-*-*-*-*-*-*-*
ORG 0X00 ;vector de reset
goto Main
ORG 0X04 ;vector de interrupcion
goto intflag
Main BANK1
movlw B'01100110' ;se carga w para habilitar dos entradas
movwf TRISB ;y una salida en el puerto B
;(bit 6:entX,bit5:entY,bit0:trigger)
movlw B'10000000' ;se carga w para habilitar
movwf TRISA ;salidas en el puerto A (bit 7: boton)
movlw B'00000001' ;bit5=0,bit3=0,bits2-1=0,bit0=1
;(preescalamiento de 1:4)
movwf OPTION_REG ;para activar timer 0
;Periodo de 1.024ms
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
inicio BANK0
clrw
clrf cuentaX ;inicio cuenta en ceros
clrf cuentaY
clrf bandera
clrf boton
call botonver
21
movlw D'5' ;para ancho de trigger 20 microsegs.
movwf wdt_trig ;inicia cuenta para ancho
bsf PORTB,0 ;set en trigger
otrouno decfsz wdt_trig,1 ;decrementa en uno el conteo ...
goto otrouno ; ... del ancho de trigger
movlw D'5'
movwf wdt_trig ;inicia otravez cuenta.
bcf PORTB,0 ;clear en trigger
otrocero decfsz wdt_trig,1 ;decrementa en uno el conteo ...
goto otrocero ;... del ancho de trigger
bsf PORTB,0 ;set en trigger
bcf INTCON,T0IF ;limpio bandera de overflow para timer 0
clrf TMR0 ;reinicio cuenta de TIMER0
BANK0
again
btfss PORTB,6 ;revisa si es uno la entrada X ...
goto Y ; ... si?, salta la linea
movf TMR0,0
movwf cuentaX ;transfiere TMR0 a cuentaX
goto yeye
Y nop
nop
nop
yeye
btfss PORTB,5 ;revisa si es uno la entrada Y ...
goto S ;si?, salta 1 linea
movf TMR0,0
movwf cuentaY ;transfiere TMR0 a cuentaY
goto esese
S nop
nop
nop
22
esese
btfss INTCON,T0IF ;overflow?
goto again ;no?, cuenta otra vez. si?, salta ésta línea
call Recepcion ;habilita recepción serial
nofull btfss bandera,4
goto nofull ;espera request
clrf bandera ;limpia bandera
goto inicio
Transmision
BANK0
movf dato,0 ; copia el dato a transmitir desde la ...
;... variable auxiliar
;(la variable dato debe ser cargada antes de llamar a esta subrutina)
movwf TXREG ; mueve el dato al buffer de transmisión
BANK1
movlw 0x0C ; valor del Baud Rate=4800bps
movwf SPBRG ;(Registro SPBRG=12)
bcf TXSTA,SYNC ; selecciona modo asincrono para transmision
bcf TXSTA,BRGH ; deshabilita el HIGH BAUD RATE
BANK0
bsf RCSTA,SPEN ; habilita el puerto serie
BANK1
bsf TXSTA,TXEN ; habilita la transmisión
BANK0
return
Recepcion
BANK1
movlw 0x0C ; valor del Baud Rate=4800 bps
movwf SPBRG ;(Registro SPBRG=12)
bcf TXSTA,SYNC ; selecciona modo asincrono para recepción
bcf TXSTA,BRGH ; deshabilita el HIGH BAUD RATE
BANK0
bsf RCSTA,SPEN ; habilita el puerto serie
BANK1
23
bsf PIE1,RCIE ; habilita la interrupción por recepción
BANK0
bsf RCSTA,CREN ; habilita la recepción
bsf INTCON,PEIE ; habilita interrupción por perifericos
bsf INTCON,GIE ; habilitacion global de interrupciones
return
botonver
movf boton,0
sublw H'FF'
btfss STATUS,Z
goto ceros
goto acaba
ceros
btfsc PORTA,7
goto acaba
comf boton,1
acaba
return
intflag
BANK0
movf RCREG,0
movwf datoRx
;*-*-*-*-*-*-VOY A MANDAR DATO DE REGISTRO X AL PUERTO SERIAL-*-*-*-*-
movf cuentaX,0
movwf dato
call Transmision
BANK1
toaviano btfss TXSTA,TRMT
goto toaviano
;*-*-*-*-*-*-VOY A MANDAR DATO DE REGISTRO Y AL PUERTO SERIAL-*-*-*-*-
BANK0
movf cuentaY,0
movwf dato
call Transmision
BANK1
24
toaviano1 btfss TXSTA,TRMT
goto toaviano1
;*-*-*-*-*-*-*-VOY A MANDAR DATO DE BOTON AL PUERTO SERIAL-*-*-*-*-*-
BANK0
movf boton,0
movwf dato
call Transmision
BANK1
toaviano2 btfss TXSTA,TRMT
goto toaviano2
;---------------------------------------------------------------------
BANK0
movlw 0xFF
movwf bandera
retfie
end
Bloques del programa
A continuación presentamos el análisis de cada bloque precedido por este último.
;*********************************************************************
; PROYECTO TERMINAL *
; ENRIQUE GARCIA CARBAJAL y CESAR AUGUSTO RENTERIA ORTEGA *
; PIC #1 *
;*********************************************************************
;-*-*-*-*--*-DECLARANDO Y CONFIGURANDO EL MICROCONTROLADOR-*-*-*-*-*-*
PROCESSOR 16F628
#INCLUDE <p16f628.inc>
errorlevel -302
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
El encabezado es reconocido en forma de comentario. Por lo tanto, el ensamblador
no genera código (todos los comentarios son reconocidos por el punto y coma previo al
comentario). El ensamblador necesita saber cuál es el tipo de procesador que se utiliza,
tanto para las librerías como para el archivo proyecto. La línea errorlevel –302 evita que al
25
compilar se generen “warnings”. En la siguiente línea se deshabilita el watchdog timer y se
aclara la configuración con oscilador de cristal.
;*-*-*-*-*-*-*-*-*-*-*-DECLARANDO MACROS-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
BANK0 MACRO
BCF STATUS,RP1
BCF STATUS,RP0
ENDM
BANK1 MACRO
BCF STATUS,RP1
BSF STATUS,RP0
ENDM
BANK2 MACRO
BSF STATUS,RP1
BCF STATUS,RP0
ENDM
BANK3 MACRO
BSF STATUS,RP1
BSF STATUS,RP0
ENDM
Todo macro tiene la misma forma: El nombre en la primera columna; en la segunda
la etiqueta MACRO y al final del macro, la palabra reservada ENDM.
Los bits RP0 y RP1 del registro STATUS son los responsables de cambiar de banco,
según el registro que vaya a emplearse; mediante la combinación de éstos. Es lógico que
únicamente pueden seleccionarse 4 bancos con dos bits. En caso de haber más bancos,
deberán haber más bits de selección.
La palabra reservada BCF pone a “0” un bit de un registro; mientras que BSF lo
pone a “1”.
;*-*-*-*-*-*-*-*-*-*-*-*-DECLARANDO VARIABLES*-*-*-*-*-*-*-*-*-*-*-*-*
cuentaX equ 23h ;este registro se encuentra en 23h
cuentaY equ 24h ;este registro se encuentra en 24h
wdt_trig equ 25h
dato equ 26h
26
bandera equ 27h
datoRx equ 28h
boton equ 29h
;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
Las variables que necesitamos utilizar deben situarse en un bloque de memoria
reservada para registros de propósito general. En éste caso, este bloque comienza en la
dirección 20h.
;*-*-*-*-*-*-*-*-*-*-*-*-PROGRAMA PRINCIPAL*-*-*-*-*-*-*-*-*-*-*-*-*-*
ORG 0X00 ;vector de reset
goto Main
ORG 0X04 ;vector de interrupcion
goto intflag
Main BANK1
movlw B'01100110' ;se carga w para habilitar dos entradas
movwf TRISB ;y una salida en el puerto B
;(bit 6:entX,bit5:entY,bit0:trigger)
movlw B'10000000' ;se carga w para habilitar
movwf TRISA ;salidas en el puerto A (bit 7: boton)
movlw B'00000001' ;bit5=0,bit3=0,bits2-1=0,bit0=1
;(preescalamiento de 1:4)
movwf OPTION_REG ;para activar timer 0
;Periodo de 1.024ms
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
Al inicio del programa, el PIC debe situarse en el origen, es decir, en la dirección
00h.
Es necesario especificar en el programa que cuando ocurre una interrupción (en caso
nuestro la interrupción es provocada por la recepción de la petición request), el apuntador
de instrucciones debe ir a la dirección 04h, donde se encuentra el bloque reservado para la
atención a interrupciones.
Debido que los registros TRISB, TRISA y OPTION_REG se encuentran en el
banco1, nos colocamos en éste mediante uno de los macros. TRISB es el encargado de
27
configurar los pines del puerto B, así que elegimos los bits 6 y 5 del puerto B como
entradas de los monoestables(podría ser cualquier bit del puerto); entonces se ponen en “1”
los bits 6 y 5 del registro TRISB. Análogamente con TRISA, donde el bit 7 es la entrada del
botón de disparo. Utilizamos la opción del preescalamiernto de 1:4 con los tres bits menos
significativos de OPTION_REG.
inicio BANK0
clrw
clrf cuentaX ;inicio cuenta en ceros
clrf cuentaY
clrf bandera
clrf boton
call botonver
bcf INTCON,T0IF ;limpio bandera de overflow para timer 0
clrf TMR0 ;reinicio cuenta de TIMER0
movlw D'5' ;para ancho de trigger 20 microsegs.
movwf wdt_trig ;inicia cuenta para ancho
bsf PORTB,0 ;set en trigger
otrouno decfsz wdt_trig,1 ;decrementa en uno el conteo ...
goto otrouno ; ... del ancho de trigger
movlw D'5'
movwf wdt_trig ;inicia otravez cuenta.
bcf PORTB,0 ;clear en trigger
otrocero decfsz wdt_trig,1 ;decrementa en uno el conteo ...
goto otrocero ;... del ancho de trigger
bsf PORTB,0 ;set en trigger
Aunque por defecto los registros de propósito general están en ceros, como manera
preventiva son limpiados. Llamamos la rutina botonver, que se encarga de revisar si el
botón de disparo fue accionado. Posteriormente se explicará este procedimiento.
Es necesario que el PIC genere el trigger de lógica negada, de manera que
empezamos generando la parte alta del trigger, después hacemos los mismo con la parte
28
baja del mismo y, por último, lo dejamos otra vez en alto. Es importante limpiar la bandera
de sobreflujo para el timer0, ya que al generarse el trigger, debe empezar a correr el timer.
BANK0
again btfss PORTB,6 ;revisa si es uno la entrada X ...
goto Y ; ... si?, salta la linea
movf TMR0,0
movwf cuentaX ;transfiere TMR0 a cuentaX
goto yeye
Y nop
nop
nop
yeye btfss PORTB,5 ;revisa si es uno la entrada Y ...
goto S ;si?, salta 1 linea
movf TMR0,0
movwf cuentaY ;transfiere TMR0 a cuentaY
goto esese
S nop
nop
nop
esese btfss INTCON,T0IF ;overflow?
goto again ;no?, cuenta otra vez. si?, salta ésta línea
Para trabajar con los puertos, debemos cambiarnos al banco 0. Como ya empezó a
correr el timer, revisamos si aún está en alto la entrada proveniente del monoestable en la
entrada X del PIC. Si está en alto, transferimos el valor del timer0 al registro cuentaX, en
caso contrario, no hacemos tal transferencia; y después hacemos lo mismo con cuentaY .
Esta operación se hace varias veces hasta que el timer se desborda.
El último valor transferido del timer a cuentaX es la palabra asociada al ángulo del
joystick. Como los pulsos provenientes de los monoestables caen antes que el timer se
desborde, no existe problema que un ángulo máximo tenga asociada una palabra mínima.
Ahora están listas las dos palabras concernientes a los ejes y el estado del botón de
disparo para ser transmitidos vía serial. Esperamos el request del otro PIC, mediante una
bandera que solo es modificada en la rutina de atención a la interrupción.
29
call Recepcion ;habilita recepción serial
nofull btfss bandera,4
goto nofull ;espera request
clrf bandera ;limpia bandera
goto inicio
El loop nofull espera a que el registro bandera sea puesto en “alto”; claro que por
comodidad solamente nos fijamos en el estado del bit 4. Cuando ocurre la interrupción por
recepción, en la rutina intflag es modificada la bandera y así sale del loop, limpia la
bandera y regresa a contar otra vez.
Transmision
BANK0
movf dato,0 ; copia el dato a transmitir desde la ...
;... variable auxiliar
;(la variable dato debe ser cargada antes de llamar a esta subrutina)
movwf TXREG ; mueve el dato al buffer de transmisión
BANK1
movlw 0x0C ; valor del Baud Rate=4800bps
movwf SPBRG ;(Registro SPBRG=12)
bcf TXSTA,SYNC ; selecciona modo asincrono para transmision
bcf TXSTA,BRGH ; deshabilita el HIGH BAUD RATE
BANK0
bsf RCSTA,SPEN ; habilita el puerto serie
BANK1
bsf TXSTA,TXEN ; habilita la transmisión
BANK0
return
Esta rutina es llamada dentro de la rutina intflag, que es cuando es atendido el
request. Aquí es habilitada la transmisión y el baud rate, además de transferir el contenido
del registro dato al registro TXREG, que es el responsable de mandar bit a bit su contenido.
El manual del PIC explica la forma de calcular el valor del SPBRG, sabiendo la
frecuencia de oscilación, el baud rate requerido y el modo de transmisión (síncrona o
asíncrona). La fórmula se obtiene de la siguente tabla:
30
SYNC BRGH = 0 (Low Speed) BRGH = 1 (High Speed)
0 (Asynchronous) Baud Rate = Fosc/(64(X+1) (Asynchronous) Baud Rate = Fosc/(16(X+1)
1 (Synchronous) Baud Rate = Fosc/(4(X+1) NA
Donde X es el valor del SPBRG.
Recepcion
BANK1
movlw 0x0C ; valor del Baud Rate=4800 bps
movwf SPBRG ;(Registro SPBRG=12)
bcf TXSTA,SYNC ; selecciona modo asincrono para recepción
bcf TXSTA,BRGH ; deshabilita el HIGH BAUD RATE
BANK0
bsf RCSTA,SPEN ; habilita el puerto serie
BANK1
bsf PIE1,RCIE ; habilita la interrupción por recepción
BANK0
bsf RCSTA,CREN ; habilita la recepción
bsf INTCON,PEIE ; habilita interrupción por perifericos
bsf INTCON,GIE ; habilitacion global de interrupciones
return
Puede observarse que la rutina llamada Recepción es muy parecida a la de
transmisión, con la excepción que no se utiliza el registro dato o alguno análogo a éste.
botonver movf boton,0
sublw H'FF'
btfss STATUS,Z
goto ceros
goto acaba
ceros btfsc PORTA,7
goto acaba
comf boton,1
acaba
return
31
botonver es la rutina encargada de verificar si el botón de disparo ha sido presionado
o no. En el registro boton puede revisarse si fue provocado un disparo, cuando éste está en
“alto”. Si no ha sido presionado el botón, el registro boton está en “ceros”. El boton es
limpiado cada que el PIC vuelve a contar.
intflag
BANK0
movf RCREG,0
movwf datoRx
;*-*-*-*-*-*-VOY A MANDAR DATO DE REGISTRO X AL PUERTO SERIAL-*-*-*-*-
movf cuentaX,0
movwf dato
call Transmision
BANK1
toaviano btfss TXSTA,TRMT
goto toaviano
;*-*-*-*-*-*-VOY A MANDAR DATO DE REGISTRO Y AL PUERTO SERIAL-*-*-*-*-
BANK0
movf cuentaY,0
movwf dato
call Transmision
BANK1
toaviano1 btfss TXSTA,TRMT
goto toaviano1
;*-*-*-*-*-*-*-VOY A MANDAR DATO DE BOTON AL PUERTO SERIAL-*-*-*-*-*-
BANK0
movf boton,0
movwf dato
call Transmision
BANK1
toaviano2 btfss TXSTA,TRMT
goto toaviano2
;---------------------------------------------------------------------
BANK0
movlw 0xFF
movwf bandera
32
retfie
end
Esta rutina es la que, cuando ocurre la única interrupción (de request), atiende a
ésta; entonces el registro datoRx recoge el request. Posteriormente transmite cuentaX y
espera que el búffer de transmisión se vacíe para mandar cuentaY. El proceso es análogo
para mandar el registro boton. Por último, se pone en “unos” el registro bandera, porque al
terminar la rutina, el apuntador de instrucciones se sitúa donde se quedó antes de la
interrupción, es decir, en el loop; que únicamente puede salirse de él cuando el bit 4 de
bandera está en alto.
La palabra reservada retfie señala que la rutina es de interrupción; y la otra palabra
end es el cierre de la rutina main.
El PIC de los motores (PIC2)
Para que el PIC sea capaz de mover los motores, debe primero recibir los tres
registros concernientes a cuentaX, cuentaY, y boton. Ya habíamos mencionado
anteriormente que el máximo valor posible en los registros es 255. Como los motores
escogidos son de 200 pasos por revolución, los registros sin alterar de cuentaX y cuentaY
son una buena aproximación tomando en cuanta que el joystick maneja un rango pequeño
de palabras. Sin embargo, en caso de desear una mejor aproximación, a éstos registros
pueden multiplicarse por 0.75, debido que: 200/256 = 0.78125≅0.75=3/4.
Así que con dos corrimientos a la derecha dividimos entre 4; y sumando tres veces
por él mismo este valor obtenido, multiplicamos por 3. De esta manera, se tiene
prácticamente una palabra por paso.
Debido que los motores a pasos carecen de una referencia que es útil al inicializar el
sistema, optamos por utilizar unos optointerruptores montados de tal forma que los
motores en un inicio se muevan a una dirección hasta lograr que cada interruptor se cierre
(o se abra en el caso de estar permanentemente cerrado) para inmediatamente moverse a la
dirección contraria los pasos que necesarios para llegar a donde se desea que los motores se
sitúen cuando el joystick está en reposo (parecido a lo que las impresoras realizan cuando
son encendidas).
33
Los motores que elegimos necesitan de una corriente de 2.1 y 2.5V que, aunque los
PICs pueden proporcionar una corriente mayor a otros microcontroladores es, por mucho,
una corriente que no pueden proporcionar. De esta forma, es necesario de un driver o etapa
de amplificación de potencia para mover dichos motores, además de una fuente de
alimentación capaz de otorgar una corriente por lo menos de 4.2 A y 5V en el caso de
utilizar el modo de paso simple (que luego explicaremos) u 8.4A en el caso de doble torque.
Entonces, el PIC se encarga de verificar (por dos de sus entradas) si los motores ya
han activado los optointerruptores y generar loops que terminen cuando se llegue a donde
(como habíamos mencionado antes) corresponde la posición de los motores cuando el
joystick reposa. Se manda la señal de request y a partir de la recepción se mueven los
motores hasta alcanzar la posición que manda el PIC 1, además de disparar cuando es
indicado.
El PIC rota un bit (en el caso de paso simple, o dos para más torque) para adelante o
para atrás dependiendo si los registros iniciales de X e Y son mayores o menores a las
cuentas respectivas. Éste sale a los puertos, donde asignamos los bits menos significativos
del puerto A como salidas al motor X, y los más significativos del puerto B al motor Y
(porque la multiplexación del módulo serial impide a estos bits usarlos como salida del
puerto B).
A la salida de los puertos se conecta la etapa de amplificación de potencia, que
explicaremos más tarde. Esta se conecta finalmente a los motores para lograr su
movimiento.
El diagrama de flujo intenta ilustrar de mejor modo la tarea del PIC.
34
Inicio
Inicializo Macros,declaro variables,
TMR0<-1:32 preesc
transmit request
bufferlleno?
no
si
bufferlleno?
no
cuentaX<-RCREG
cuentaY<-RCREG
si
bufferlleno?
no
boton<-RCREG
si
w<-cuentaX-inicialX
Z=1?si
no
1
Referenciapara motores
C=1?
Paso para atrásmotorX,
inicialX<- inicialX-1
Paso paraadelante motorX,
inicialX<-inicialX+1
no si
3
2
35
Cuando el sistema se enciende, mientras el PIC 1 asigna las primeras palabras, el
PIC 2 posiciona los motores en su lugar inicial y forza que las palabras que el PIC 1 manda
cuando el joystick se encuentra en reposo correspondan a la posición inicial de los motores,
inicializando unos registros llamados inicialX e inicialY, que son los encargados de
“seguirle los pasos” a las cuentas X e Y. El PIC 2 debe ser capaz de mandar la señal de
request y prepararse a recibir mediante una interrupción por recepción; las secuencias
otorgadas por el PIC 1. Sabiendo que el primer byte corresponde a la palabra generada para
el eje X, inicializamos un registro llamado cuentaX (como el del PIC 1). La segunda
recepción es para cuentaY y la tercera, el registro boton. Las posiciones iniciales y los
pasos de los motores que van a los puertos son incrementados o decrementados hasta
w<-cuentaY-inicialY
Z=1?si
no
C=1?no si
3
boton=1?
Dispara noDispara
cuentaX=inicialXy
cuentaY=inicialY?1 2
no
no
si
si
Paso paraadelante motorY,
inicialY<-inicialY+1
Paso paraatrás motorY,
inicialY<-inicialY-1
36
alcanzar las cuentas. Alcanzadas éstas, se realiza el disparo, si es que se provocó tal, y por
último, la rutina regresa a mandar otro request.
Una pregunta lógica es: ¿Por qué el PIC 1 realiza menos tarea que el PIC 2?. La
razón es que el proyecto está diseñado para posteriormente implementar módems de
radiofrecuencia entre los dos PICs. Por tanto, en dado caso que el PIC 2 no llegue en un
intervalo de tiempo a recibir la secuencia mandada por el PIC 1 (por motivos de distancia o
interferencia) y posteriormente la recupere, el PIC 2 recuperará también la referencia; de
otro modo, el PIC 2 perderá la referencia.
Despliegue del programa para el PIC 2
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
;PROYECTO I
;ENRIQUE GARCIA CARBAJAL y CESAR RENTERIA ORTEGA
;PIC#2
;-*-*-*-*-*-*-*-*-*-DECLARANDO Y CONFIGURANDO EL MICROCONTROLADOR-*-*-
PROCESSOR 16F628
#INCLUDE <p16f628.inc>
errorlevel -302
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-DECLARANDO MACROS-*-*-*-*-*-*-*-*-*-*-
BANK0 MACRO
BCF STATUS,RP1
BCF STATUS,RP0
ENDM
BANK1 MACRO
BCF STATUS,RP1
BSF STATUS,RP0
ENDM
BANK2 MACRO
BSF STATUS,RP1
BCF STATUS,RP0
ENDM
37
BANK3 MACRO
BSF STATUS,RP1
BSF STATUS,RP0
ENDM
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-DECLARANDO VARIABLES*-*-*-*-*-*-*-*-*-*-
inicialX equ 20h
inicialY equ 21h
corridoX equ 22h
corridoY equ 23h
cuentaX equ 24h ;este registro se encuentra en 24h
cuentaY equ 25h
bandera equ 26h
REG equ 27h
datoRx equ 28h
auxiliar equ 29h
dato equ 2Ah
contint equ 2Bh
val equ 2Ch
boton equ 2Dh
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-PROGRAMA PRINCIPAL*-*-*-*-*-*-*-*-*-*-*-
ORG 0X00 ;vector de reset
goto Main
ORG 0X04 ;vector de interrupcion
goto intflag
Main
BANK1
movlw B'10010000' ;se carga w para habilitar
movwf TRISA ;salidas en el puerto A
movlw B'00000110' ;se carga w para habilitar
movwf TRISB ;salidas en el puerto B
movlw B'00000100' ;bit5=0,bit3=0,bits2-1=0,bit0=1
;(preescalamiento de 1:4)
movwf OPTION_REG ;para activar timer 0
;Periodo de 1.024ms
38
;-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
inicio
BANK0
clrw
clrf bandera
clrf contint
clrf PORTA
clrf PORTB
clrf corridoX
clrf corridoY
clrf val
clrf RCREG
movlw H'06'
movwf corridoX
movlw H'60'
movwf corridoY
movlw H'00'
movwf contint
;-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*referencia-*-*-*-*-*-*-*-*-*-
refX
btfsc PORTA,4 ;referencia de X
goto regresaX
call Xrewind
bcf INTCON,T0IF
clrf TMR0
aqui30 btfss INTCON,T0IF ;retardo
goto aqui30
bcf INTCON,T0IF
clrf TMR0
aqui3a btfss INTCON,T0IF ;retardo
goto aqui3a
comf corridoX,0
movwf PORTA
goto refX
regresaX
clrf inicialX
agX
39
call Xforward
bcf INTCON,T0IF
clrf TMR0
aqui3 btfss INTCON,T0IF ;retardo
goto aqui3
bcf INTCON,T0IF
clrf TMR0
aqui3b btfss INTCON,T0IF ;retardo
goto aqui3b
comf corridoX,0
movwf PORTA
movf inicialX,0
sublw D'100'
btfss STATUS,Z
goto agX
refY
btfsc PORTA,7
goto regresaY
call Yrewind
bcf INTCON,T0IF
clrf TMR0
aqui31 btfss INTCON,T0IF ;retardo
goto aqui31
bcf INTCON,T0IF
clrf TMR0
aqui3c btfss INTCON,T0IF ;retardo
goto aqui3c
movf corridoY,0
movwf REG
rrf REG,0
andlw H'08'
movwf REG
movf corridoY,0
andlw H'E0'
iorwf REG,1
comf REG,0
movwf PORTB
40
bcf PORTB,0
goto refY
regresaY
clrf inicialY
agY
call Yforward
bcf INTCON,T0IF
clrf TMR0
aqui33 btfss INTCON,T0IF ;retardo
goto aqui33
bcf INTCON,T0IF
clrf TMR0
aqui34 btfss INTCON,T0IF ;retardo
goto aqui34
movf corridoY,0
movwf REG
rrf REG,0
andlw H'08'
movwf REG
movf corridoY,0
andlw H'E0'
iorwf REG,1
comf REG,0
movwf PORTB
bcf PORTB,0
movf inicialY,0
sublw D'103'
btfss STATUS,Z
goto agY
;------------------*********************-----------------*************
clrf inicialX
movlw D'63'
movwf inicialX
clrf inicialY
movlw D'50'
movwf inicialY
;------------------*********************-----------------*************
41
otropasoX clrw
;---------------------------------------------------------------------
bcf STATUS,Z
bcf STATUS,C
bcf INTCON,T0IF
clrf contint
movlw H'05'
movwf dato ;request
call Transmision
call Recepcion
quenoX btfss bandera,4
goto quenoX
clrf bandera
call Recepcion
quenoY btfss bandera,4
goto quenoY
clrf bandera
call Recepcion
quenoB btfss bandera,4
goto quenoB
clrf bandera
;---------------------------------------------------------------------
aivoy
clrf val
movf inicialX,0
subwf cuentaX,0
btfss STATUS,Z
goto sigueX
goto palaY
sigueX btfss STATUS,C
goto atrasX1
call Xforward
goto palaY
atrasX1 call Xrewind
42
palaY movf inicialY,0
subwf cuentaY,0
btfss STATUS,Z
goto sigueY
goto salida
sigueY btfss STATUS,C
goto atrasY1
call Yforward
goto salida
atrasY1 call Yrewind
salida
comf corridoX,0
movwf PORTA
movf corridoY,0
movwf REG
rrf REG,0
andlw H'08'
movwf REG
movf corridoY,0
andlw H'E0'
iorwf REG,1
comf REG,0
movwf PORTB
;*********************************************************************
btfss boton,4
goto bo
bsf PORTB,0
goto ton
bo
bcf PORTB,0
ton
**********************************************************************
ret bcf INTCON,T0IF
clrf TMR0
aqui2 btfss INTCON,T0IF ;retardo
goto aqui2
43
bcf INTCON,T0IF
clrf TMR0
aqui39 btfss INTCON,T0IF ;retardo
goto aqui39
;----------------------valida para pedir transmision------------------
movf inicialX,0
subwf cuentaX,0
btfss STATUS,Z
goto aY
incf val,1
aY
movf inicialY,0
subwf cuentaY,0
btfss STATUS,Z
goto aver
incf val,1
aver
movf val,0
sublw H'02'
btfss STATUS,Z
goto aivoy
goto otropasoX
;----------------------fin valida para pedir transmision--------------
;¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
Xrewind
movf corridoX,0
sublw H'0C'
btfss STATUS,Z
goto resetX1
movlw H'09'
movwf corridoX
goto yastuvoX1
resetX1
movf corridoX,0
sublw H'09'
btfss STATUS,Z
goto resetX2
44
movlw H'03'
movwf corridoX
goto yastuvoX1
resetX2
bcf STATUS,C
rlf corridoX,1
yastuvoX1
decf inicialX,1
return
Yrewind
movf corridoY,0
sublw H'C0'
btfss STATUS,Z
goto resetY1
movlw H'90'
movwf corridoY
goto yastuvoY1
resetY1
movf corridoY,0
sublw H'90'
btfss STATUS,Z
goto resetY2
movlw H'30'
movwf corridoY
goto yastuvoY1
resetY2
bcf STATUS,C
rlf corridoY,1
yastuvoY1
decf inicialY,1
return
Xforward
movf corridoX,0
sublw H'03'
45
btfss STATUS,Z
goto resetX3
movlw H'09'
movwf corridoX
goto yastuvoX3
resetX3
movf corridoX,0
sublw H'09'
btfss STATUS,Z
goto resetX4
movlw H'0C'
movwf corridoX
goto yastuvoX3
resetX4
bcf STATUS,C
rrf corridoX,1
yastuvoX3
incf inicialX,1
return
Yforward
movf corridoY,0
sublw H'30'
btfss STATUS,Z
goto resetY3
movlw H'90'
movwf corridoY
goto yastuvoY3
resetY3
movf corridoY,0
sublw H'90'
btfss STATUS,Z
goto resetY4
movlw H'C0'
movwf corridoY
goto yastuvoY3
46
resetY4
bcf STATUS,C
rrf corridoY,1
yastuvoY3
incf inicialY,1
return Transmision
BANK0
movf dato,0 ; copia el dato a transmitir desde la ...
;... variable auxiliar
;(la variable dato debe ser cargada antes de llamar a esta subrutina)
movwf TXREG ; mueve el dato al buffer de transmisión
BANK1
movlw 0x0C ; valor del Baud Rate=4800bps
movwf SPBRG ;(Registro SPBRG=12)
bcf TXSTA,SYNC ; selecciona modo asincrono para transmision
bcf TXSTA,BRGH ; deshabilita el HIGH BAUD RATE
BANK0
bsf RCSTA,SPEN ; habilita el puerto serie
BANK1
bsf TXSTA,TXEN ; habilita la transmisión
BANK0
return
Recepcion
BANK1
movlw 0x0C ; valor del Baud Rate=4800 bps
movwf SPBRG ;(Registro SPBRG=12)
bcf TXSTA,SYNC ; selecciona modo asincrono para recepción
bcf TXSTA,BRGH ; deshabilita el HIGH BAUD RATE
BANK0
bsf RCSTA,SPEN ; habilita el puerto serie
BANK1
bsf PIE1,RCIE ; habilita la interrupción por recepción
BANK0
bsf RCSTA,CREN ; habilita la recepción
bsf INTCON,PEIE ; habilita interrupción por perifericos
bsf INTCON,GIE ; habilitacion global de interrupciones
47
return
intflag
BANK0
movf contint,0
sublw H'00'
btfss STATUS,Z
goto pasalas
movf RCREG,0
movwf cuentaX
incf contint,1
goto fin
pasalas
movf contint,0
sublw H'01'
btfss STATUS,Z
goto botones
movf RCREG,0
movwf cuentaY
incf contint,1
goto fin
botones
movf contint,0
sublw H'02'
btfss STATUS,Z
goto fin
movf RCREG,0
movwf boton
movlw H'00'
movwf contint
fin movlw 0xFF
movwf bandera
bcf RCSTA,CREN ; deshabilita la recepción
retfie
end
48
Bloques del programa
La inicialización del PIC y las rutinas de transmisión y recepción no serán
explicadas, debido a su similitud con el programa del PIC 1; sin embargo en el despliegue
para el programa del PIC 1 está la explicación de esta sección.
Cabe mencionar de lo omitido, que el preescalamiento del timer0 en el PIC 2 es
mucho mayor al configurado para los monoestables en el PIC 1 debido a la velocidad de
respuesta de los motores. El preescalamiento para los motores puede incrementarse a gusto
del diseñador, pero no disminuirlo más de lo que el programa tiene como valor; según
nuestras observaciones experimentales. La sincronización y comunicación bidireccional de
los PICs lo inicia el request.
inicio
BANK0
clrw
clrf bandera
clrf contint
clrf PORTA
clrf PORTB
clrf corridoX
clrf corridoY
clrf val
clrf RCREG
movlw H'06'
movwf corridoX
movlw H'60'
movwf corridoY
movlw H'00'
movwf contint
Iniciamos con un valor que coloca a la mitad los “unos” en los registros corridoX y
corridoY , porque usamos el modo de pasos con gran torque. Después, al contador de
interrupciones los iniciamos en ceros.
49
;-*-*-*-**-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*referencia-*-*-*-*-*-*-*-*-*-
refX btfsc PORTA,4 ;referencia de X
goto regresaX
call Xrewind
bcf INTCON,T0IF
clrf TMR0
aqui30 btfss INTCON,T0IF ;retardo
goto aqui30
bcf INTCON,T0IF
clrf TMR0
aqui3a btfss INTCON,T0IF ;retardo
goto aqui3a
comf corridoX,0
movwf PORTA
goto refX
Debido que para posicionar los motores a su estado inicial; revisamos el bit 4 del
puerto A y en caso de ser cero, ya está cerrado el optointerruptor. Si está abierto aún,
llamamos a la rutina Xrewind (la encargada de decrementar el valor de inicialX una vez,
pero principalmente de rotar a la izquierda los bits que van a salir al puerto A) varias veces
hasta que cerrar el interruptor. Pueden observarse repetidamente varios retardos para el
motor. Cada vez que se da un paso, se manda al puertoA la palabra de corridoX, que son los
bits rotados. El registro corridoX la mandamos complementada, porque utilizamos para la
etapa de potencia, una configuración de dos transistores en cascada operando en saturación
que como es sabido, la lógica se invierte cuando esta configuración se implementa.
regresaX
clrf inicialX
agX
call Xforward
bcf INTCON,T0IF
clrf TMR0
aqui3 btfss INTCON,T0IF ;retardo
goto aqui3
bcf INTCON,T0IF
50
clrf TMR0
aqui3b btfss INTCON,T0IF ;retardo
goto aqui3b
comf corridoX,0
movwf PORTA
movf inicialX,0
sublw D'100'
btfss STATUS,Z
goto agX
En el caso de que el interruptor se encuentra cerrado, hacemos lo mismo pero esta
vez llamamos a la rutina Xforward hasta que inicialX llegue al valor decimal 100, que
puede ser cambiado si se desea que el motor se sitúe en algún otro lado. Para revisar si
inicialX ha llegado al valor mencionado antes, se transfiere inicialX al registro de trabajo y
después se resta con el valor y si la bandera de cero Z se pone en “uno”, entonces ya llegó
al valor; de otro modo sigue el ciclo agX.
refY
btfsc PORTA,7
goto regresaY
call Yrewind
bcf INTCON,T0IF
clrf TMR0
aqui31 btfss INTCON,T0IF ;retardo
goto aqui31
bcf INTCON,T0IF
clrf TMR0
aqui3c btfss INTCON,T0IF ;retardo
goto aqui3c
movf corridoY,0
movwf REG
rrf REG,0
andlw H'08'
movwf REG
movf corridoY,0
andlw H'E0'
51
iorwf REG,1
comf REG,0
movwf PORTB
bcf PORTB,0
goto refY
regresaY
clrf inicialY
agY
call Yforward
bcf INTCON,T0IF
clrf TMR0
aqui33 btfss INTCON,T0IF ;retardo
goto aqui33
bcf INTCON,T0IF
clrf TMR0
aqui34 btfss INTCON,T0IF ;retardo
goto aqui34
movf corridoY,0
movwf REG
rrf REG,0
andlw H'08'
movwf REG
movf corridoY,0
andlw H'E0'
iorwf REG,1
comf REG,0
movwf PORTB
bcf PORTB,0
movf inicialY,0
sublw D'103'
btfss STATUS,Z
goto agY
Para el caso del motor del eje Y, es casi idéntico a lo del motorX, con una
excepcion: El modo en que los bits de corridoY salen al puerto B no es similar. La razón
radica en que al utilizar los bits mas significativos del puerto, no todos los bits se
52
encuentran disponibles, especialmente el bit 4. En el manual puede observarse que este bit
también tiene como función la habilitación de programación a bajo voltaje, así que por
defecto, éste bit está deshabilitado como salida de puerto; entonces optamos por enmascarar
el cuarto bit de corridoY y desenmascararlo en el bit 3 del puertoB. Otra alternativa para
este problema es, antes de programar el PIC, deshabilitar la opción low voltaje en la
ventana de programación.
;------------------*********************-----------------*************
clrf inicialX
movlw D'63'
movwf inicialX
clrf inicialY
movlw D'50'
movwf inicialY
Los valores iniciales son cambiados para que, después de la inicialización, los
motores no se reposicionen cuando el joystick está en reposo.
Estos valores ‘63’ Y ‘50’, son obtenidos experimentalmente; es decir, valores de
prueba y error que el PIC 1 manda estando el joystick en reposo. Por supuesto éstos valores
pueden cambiar en caso de usar otro joystick o de calibrar sus potenciómetros.
;------------------*********************-----------------*************
otropasoX clrw
;---------------------------------------------------------------------
bcf STATUS,Z
bcf STATUS,C
bcf INTCON,T0IF
clrf contint
movlw H'05'
movwf dato ;request
call Transmision
call Recepcion
quenoX btfss bandera,4
53
goto quenoX
clrf bandera
call Recepcion
quenoY btfss bandera,4
goto quenoY
clrf bandera
call Recepcion
quenoB btfss bandera,4
goto quenoB
clrf bandera
La señal de request es enviada al PIC 1, para que mande las coordenadas y el estado
del botón. Aunque el PIC 1 no lo valida, se manda un ‘5’ como request, que en código
ASCII es la petición de transmisión. Posteriormente se habilita la recepción cada vez que se
recibe una palabra. Puede observarse que el orden de las palabras en la recepción es
equivalente al orden en que se transmiten. Esta sección no es la que recibe y transfiere los
datos a sus respectivos registros, pero es la que espera a que la interrupción sea atendida
para esperar otra.
;---------------------------------------------------------------------
aivoy
clrf val
movf inicialX,0
subwf cuentaX,0
btfss STATUS,Z
goto sigueX
goto palaY
sigueX btfss STATUS,C
goto atrasX1
call Xforward
goto palaY
atrasX1 call Xrewind
54
Mediante una resta de cuentaX con inicialX se decide si se mueve el motor X o no.
En caso de que la resta sea cero (bandera Z=1) el motor no se mueve y brincamos para
hacer lo mismo con el motor Y, restando cuentaY con inicialY . Cuando la resta de cuentaX
con inicialX es diferente de cero, necesitamos verificar si la resta es positiva o negativa, con
la bandera de acarreo C; porque si la resta es positiva, quiere decir que inicialX está por
debajo de cuentaX y, por tanto, el motor debe caminar a para adelante; y en caso que la
resta sea negativa, inicialX es mayor que cuentaX, así que el motor camina hacia atrás,
mediante la rutina Xrewind.
palaY movf inicialY,0
subwf cuentaY,0
btfss STATUS,Z
goto sigueY
goto salida
sigueY btfss STATUS,C
goto atrasY1
call Yforward
goto salida
atrasY1 call Yrewind
Puede observarse que este bloque, que es destinado para el motor Y, es análogo a lo
hecho para el motor X.
salida comf corridoX,0
movwf PORTA
movf corridoY,0
movwf REG
rrf REG,0
andlw H'08'
movwf REG
movf corridoY,0
andlw H'E0'
iorwf REG,1
comf REG,0
movwf PORTB
55
;*********************************************************************
btfss boton,4
goto bo
bsf PORTB,0
goto ton
bo bcf PORTB,0
ton
Este es el bloque de salida a los puertos; de la misma forma que la inicialización,
pero ahora revisando si el botón fue presionado para mandar un nivel alto al bit 0 del puerto
B en caso de ser afirmativo lo antes dicho.
**********************************************************************
ret bcf INTCON,T0IF
clrf TMR0
aqui2 btfss INTCON,T0IF ;retardo
goto aqui2
bcf INTCON,T0IF
clrf TMR0
aqui39 btfss INTCON,T0IF ;retardo
goto aqui39
Dos retardos que pueden ser modificados para variar la velocidad de los motores.
;----------------------valida para pedir transmision------------------
movf inicialX,0
subwf cuentaX,0
btfss STATUS,Z
goto aY
incf val,1
aY
movf inicialY,0
subwf cuentaY,0
btfss STATUS,Z
goto aver
incf val,1
aver
56
movf val,0
sublw H'02'
btfss STATUS,Z
goto aivoy
goto otropasoX
;----------------------fin valida para pedir transmision--------------
En caso de que los valores de cuentaX y cuentaY ya han sido alcanzados, se brinca a
donde se pide mediante el request, otras coordenadas y el estado actual del botón. De otro
modo, el brinco es después de que ocurren las recepciones.
;¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
Xrewind
movf corridoX,0
sublw H'0C'
btfss STATUS,Z
goto resetX1
movlw H'09'
movwf corridoX
goto yastuvoX1
resetX1
movf corridoX,0
sublw H'09'
btfss STATUS,Z
goto resetX2
movlw H'03'
movwf corridoX
goto yastuvoX1
resetX2
bcf STATUS,C
rlf corridoX,1
yastuvoX1
decf inicialX,1
return
Ya habíamos aclarado que la secuencia que utilizamos para mover los motores fue
la de gran torque, y Xrewind rota dos bits juntos. Hay dos casos críticos que se deben tomar
57
en cuenta. El primero es cuando dos los bits están a punto de desbordarse por cualquiera de
los lados del registro (pasar de 1100 a 1001 si se rota a la izquierda o de 0011 a 1001 para
rotación a la derecha) y el segundo es la trascendencia contraria; es decir, reposicionarlos
(de 1001 a 1100 si se rota a la derecha o de 1001 a 0011 para rotación a la izquierda). En el
caso de Xrewind, solamente nos centramos en lo que ocurre cuando se desbordan los bits de
corridoX por la izquierda. Esa razón forza a revisar primero si el nibble (arreglo de cuatro
bits) es la palabra binaria 1100, que en hexadecimal es el número 0C. Si esto ocurre, la
palabra debe cambiar a 1001, que en hexadecimal es 09. En caso de no encontrarse en la
posición 1100, debemos ahora revisar si la posición es 1001, para reposicionar al número
binario en 0011, que en hexadecimal es 03; y en caso de no encontrarse en ninguno de estos
casos, solamente rotar el registro a la izquierda. Después de esta toma de decisiones,
decrementamos inicialX.
Yrewind
movf corridoY,0
sublw H'C0'
btfss STATUS,Z
goto resetY1
movlw H'90'
movwf corridoY
goto yastuvoY1
resetY1 movf corridoY,0
sublw H'90'
btfss STATUS,Z
goto resetY2
movlw H'30'
movwf corridoY
goto yastuvoY1
resetY2 bcf STATUS,C
rlf corridoY,1
yastuvoY1 decf inicialY,1
return
58
Xforward
movf corridoX,0
sublw H'03'
btfss STATUS,Z
goto resetX3
movlw H'09'
movwf corridoX
goto yastuvoX3
resetX3 movf corridoX,0
sublw H'09'
btfss STATUS,Z
goto resetX4
movlw H'0C'
movwf corridoX
goto yastuvoX3
resetX4 bcf STATUS,C
rrf corridoX,1
yastuvoX3 incf inicialX,1
return
Yforward
movf corridoY,0
sublw H'30'
btfss STATUS,Z
goto resetY3
movlw H'90'
movwf corridoY
goto yastuvoY3
resetY3 movf corridoY,0
sublw H'90'
btfss STATUS,Z
goto resetY4
movlw H'C0'
movwf corridoY
goto yastuvoY3
resetY4 bcf STATUS,C
rrf corridoY,1
59
yastuvoY3
incf inicialY,1
return
Observamos que la rutina Xforward tiene la misma función que Xrewind, con la
variante de ir rotando a la derecha los bits de corridoX e incrementar inicialX. Asimismo,
Yrewind e Yforward tiene tareas casi idénticas a sus análogos Xrewind y Xforward
respectivamente, pero alterando inicialY y corridoY .
intflag
BANK0
movf contint,0
sublw H'00'
btfss STATUS,Z
goto pasalas
movf RCREG,0
movwf cuentaX
incf contint,1
goto fin
pasalas movf contint,0
sublw H'01'
btfss STATUS,Z
goto botones
movf RCREG,0
movwf cuentaY
incf contint,1
goto fin
botones movf contint,0
sublw H'02'
btfss STATUS,Z
goto fin
movf RCREG,0
movwf boton
movlw H'00'
movwf contint
fin movlw 0xFF
60
movwf bandera
bcf RCSTA,CREN ; deshabilita la recepción
retfie
end
Por último la rutina intflag, que es habilitada mediante la interrupción por recepción,
asigna por cada interrupción y con la ayuda del contador de interrupciones contint, lo
recibido en RCREG a su correspondiente registro y cada vez que sale de la interrupción
pone a “unos” la bandera.
Termina la explicación para el programa del PIC 2.
Etapa de potencia
Esta etapa es la intermedia entre el PIC y los motores. Como su nombre lo indica,
incrementa la potencia de las señales salientes de los puertos del PIC, elevando la corriente
de colector del transistor Darlington, en el que una bobina del motor es la carga. En el
marco teórico se incluye el circuito necesario para motores unipolares y bipolares. Cabe
mencionar que tal circuito es para una sola bobina; de tal modo que para cuatro bobinas por
motor, se necesitó de ocho etapas de potencia.
Al trabajar con un motor bipolar de 2.5V y 2.1A de consumo, debimos incluir un
Darlington que soporte más de 4A, porque si la secuencia es de gran torque, cada motor
consume 4.2A; así que la fuente de alimentación debe proporcionar alrededor de 9A.
El voltaje colector-emisor del Darlington es alrededor de 2.5V en modo de
saturación; entonces agregando el voltaje que el motor necesita, la fuente utilizada fue de
5V (una fuente conmutada como la de una computadora cumple este requisito,
proporcionando hasta 20A para 5V). Es necesario saber la beta del transistor, porque de
ésta depende el valor de la resistencia, ya cuando el optoacoplador se encuentre en corte,
prácticamente toda la corriente que pasa por la resistencia va hacia la base del Darlington.
Sabiendo la corriente necesaria para el motor y la beta, la corriente de base es obtenida. Por
otro lado, por una ecuación sencilla de malla obtenemos la corriente de base que depende
de la resistencia; recordando que el voltaje base-colector de un Darlington es alrededor de
1.4V.
61
El optoacoplador que utilizamos fue el 4N27. Un optoacoplador es un transistor que
mediante luz es excitado en su base. Es útil debido a que la base se encuentra aislada
eléctricamente y evita corrientes de retorno. El Darligton que utilizamos es el de matrícula
2N6039, que soporta hasta 4A de corriente de colector.
RESULTADOS DE LABORATORIO
Al inicio del proyecto decidimos comenzar experimentando la generación del
trigger (por medio del PIC) y observar cómo respondía el monoestable ante éste, mediante
un programa que generaba un pulso bajo de 10µs de ancho cada milisegundo. Entonces,
con un osciloscopio pudimos observar tanto el trigger como la salida del monoestable.
Como estaba calculado, la salida máxima del 555 era menor a 1ms.
Habiendo obtenido lo anterior, la tarea siguiente fue muestrear el ancho de pulso
que entra al PIC y asociarle una palabra de acuerdo a lo que tarda en caer; así que al variar
el potenciómetro del monoestable se generan palabras de 8 bits. Al graficar la palabra
generada contra la resistencia del potenciómetro, obtuvimos lo siguiente:
Puede observarse en la anterior gráfica que el máximo valor donde la curva puede
considerarse lineal es 55kΩ. Posiblemente afectó en la gráfica los intervalos más
distanciados que a partir de ese valor tomamos, como puede verse en la tabla siguiente:
Palabra vs. Resistencia
0,00
0,50
1,00
1,50
2,00
2,50
3,00
0,00 20,00 40,00 60,00 80,00
Resistencia (kOhms)
Pal
abra
dec
imal
(/10
0)
62
Palabra en Binario R(kΩΩΩΩ) Decimal decimal (/100)
00000000 1.62 0 0,00 00000001 2.32 1 0,01 00000100 2.60 4 0,04 00000111 3.43 7 0,07 00001001 4.59 9 0,09 00001100 5.50 12 0,12 00001111 6.53 15 0,15 00010010 7.13 18 0,18 00010100 8.01 20 0,20 00010111 8.81 23 0,23 00011010 9.54 26 0,26 00011101 10.92 29 0,29 00011111 11.37 31 0,31 00100010 12.56 34 0,34 00100101 13.16 37 0,37 00101000 14.33 40 0,40 00101010 14.80 42 0,42 00101101 16.11 45 0,45 00110000 17.02 48 0,48 00110011 17.46 51 0,51 00110101 18.73 53 0,53 00111000 19.55 56 0,56 00111011 20.1 59 0,59 00111110 21.3 62 0,62 01000000 21.8 64 0,64 01000011 22.9 67 0,67 01000110 24.1 70 0,70 01001001 24.7 73 0,73 01001011 26.2 75 0,75 01001110 26.9 78 0,78 01010001 27.7 81 0,81 01010100 28.8 84 0,84 01010110 29.9 86 0,86 01011001 30.4 89 0,89 01011100 31.5 92 0,92 01011111 32.7 95 0,95 01100001 33.5 97 0,97 01100100 33.9 100 1,00 01100111 35.3 103 1,03 01101010 36.0 106 1,06 01101100 37.0 108 1,08 01101111 38.2 111 1,11 01110010 39.6 114 1,14 01110101 40.1 117 1,17
63
01111010 41.9 122 1,22 10000000 43.2 128 1,28 10000010 44.7 130 1,30 10000101 45.3 133 1,33 10001011 47.0 139 1,39 10010000 48.6 144 1,44 10010011 50.3 147 1,47 10011000 52.0 152 1,52 10011110 53.8 158 1,58 10100001 54.8 161 1,61 10100110 57.3 166 1,66 10101100 59.1 172 1,72 10110111 63.0 183 1,83 10111111 65.1 191 1,91 11000100 66.5 196 1,96 11001010 68.8 202 2,02 11001101 70.0 205 2,05 11010010 71.6 210 2,10 11010101 72.7 213 2,13 11011000 73.9 216 2,16 11100000 75.7 224 2,24 11100101 78.8 229 2,29 11101110 81.5 238 2,38 11110000 82.1 240 2,40 11110011 83.0 243 2,43 11111001 84.8 249 2,49 11111011 86.5 251 2,51 11111110 87.5 254 2,54
Los valores cursivos están más distanciados entre ellos que los anteriores.
Tomando en cuenta la linealidad de los primeros valores, la pendiente obtenida para
ese segmento es de 5/2, así que aproximadamente el valor de cada palabra aumentaba
respecto a la anterior en 3, por cada 1kΩ incrementado. La utilidad de este experimento
radica en asumir una relación lineal entre el joystick y la palabra asociada, además de
corroborar que no habían dificultades con los valores que salían al puerto, como
anteriormente nos había ocurrido. Es importante recalcar que estos valores no muestran la
relación entre el ángulo del joystick y el ángulo de los motores. Sin embargo por este medio
es fácil hallar lo anterior realizando una tabla de medición ángulo del joystick vs resistencia
del jostick.
64
La gráfica siguiente muestra un ejemplo de los problemas obtenidos a la salida del puerto
debido a la mala lectura de un bit.
Aún con el error puede observarse la tendencia lineal de la relación. Como se había
explicado anteriormente, un bit del puerto B no funcionaba y fue necesario utilizar otro pin
del puerto; pero en ese traslado hubo un error de programación, que provocó el error. Al
darnos cuenta del error tomamos las mediciones de la primer gráfica.
La tarea siguiente fue una rutina para mover un motor hasta un determinado ángulo;
con palabras fijas programadas en el PIC, con el propósito de observar tanto la velocidad
máxima del motor y el control de la posición. Pudimos observar que el reloj debía estar
preescalado mínimo a 1:16 para que el motor respondiera de forma adecuada, además
agregamos unos retardos por cada cambio de posición del motor.
Resuelto lo anterior, controlamos el motor mediante el potenciómetro del 555, es
decir, acoplamos la parte de muestreo y asignación de palabra con la rutina de posición del
motor. No tuvimos mayores problemas.
Tomando como premisa que al poder controlar un motor podíamos controlar dos,
duplicamos lo hecho para un motor, con la diferencia que la salida para el otro motor sería
en otro puerto. Sin embargo un problema que surgió (y que no pudimos resolver) fue que
en un intervalo pequeño, al mover uno de los potenciómetros influía en la palabra
controlada por el otro. En las simulaciones observamos que, cuando una palabra de la
Palabra vs. Resistencia
0,00
0,50
1,00
1,50
2,00
2,50
0,00 20,00 40,00 60,00 80,00 100,00
Resistencia (kOhms)
Pal
abra
en
deci
mal
(/10
0)
65
posición actual había alcanzado ya su correspondiente deseada, mientras que la del otro
motor aún no, el brinco provocado por esto en la programación hacía que el eje aún
muestreando tomara un valor del reloj anterior a la que le correspondía, debido a las
diferencias entre ciclos de reloj. Por lo tanto, utilizamos el comando nop para acoplar tales
ciclos; sin embargo, esto aminoró en forma poco significativa el error.
Un problema anterior a éste fue el hecho de no percatarnos que cuando un registro
lo rotamos, el valor de la bandera de acarreo es añadida a tal registro, y para tal situación
optamos por limpiar la bandera de acarreo antes de rotar cualquier registro.
La mayor dificultad que tuvimos fue lo concerniente a la transmisión y recepción
serial. La primera prueba fue mover un motor mandando por vía serial a otro PIC la palabra
del ángulo deseado, y en éste caso no hubo mayor problema; pero al mandar más de dos
palabras, se generaba una confusión en los ejes. Por ejemplo, al mover el potenciómetro
que controlaba el motor vertical se movía el horizontal y viceversa, pero no siempre.
Entonces intentamos añadir en la trama de las palabras transmitidas, un “header”, el cual si
no era el adecuado, desechaba el byte y leía el otro, así hasta hallar el header. Éste es un
proceso tardado tomando en cuenta que la transmisión serial es mucho más lenta que el
ciclo de lectura. Previamente hicimos variantes agregando un noveno bit; obteniendo el
mismo resultado.
Fue entonces cuando, para sincronizar los PICs optamos por generar en el segundo
PIC una señal de request, mandada vía serial al primero. Significaba que el segundo PIC
estaba listo para recibir la trama y se iba a quedar esperando en un loop hasta que la
interrupción por recepción se activara. Este procedimiento dio resultado satisfactorios.
CONCLUSIONES
Al tener conocimiento de la versatilidad que los PICs proporcionan, es inevitable
compararlos con otros microcontroladores. Nos lleva a apreciar y concluir que disponemos
de una herramienta verdaderamente accesible; tanto en manejabilidad como en recursos
económicos se refiere.
En el transcurso del proyecto no dimos cuenta que no hubiese sido posible realizar
el proyecto de esta forma relativamente fácil con otro microcontrolador, sino que
hubiésemos estado limitados en memoria y registros de propósito general, como es
66
acostumbrado en los controladores habituales. Además, el modo en que son habilitados los
módulos y las interrupciones en los PICs son realmente fáciles, tomando en cuenta que, por
ejemplo en los microcontroladores Intel, este proceso resulta verdaderamente engorroso.
Controlar una cámara de video por telemetría mediante un joystick no es nuevo.
Comúnmente hemos podido observar varias aplicaciones; principalmente en vehículos de
rastreo y módulos de vigilancia.
Aunque la etapa de telemetría no es implementada en este proyecto, todos los demás
elementos necesarios son incluidos; facilitando la adaptación de módems entre las
conexiones de transmisión y recepción de los PICs, porque sin esta etapa, el proyecto
prácticamente no tiene sentido. En caso contrario se hubiera optado por utilizar un solo
microcontrolador.
Una etapa esencial que, sin embargo no es a menudo mencionada, es la de potencia.
No hubiera sido posible mover los motores con la potencia proporcionada por los puertos, y
con ayuda de los optoacopladores y los diodos, se evita que los controladores sean
arruinados por la corriente de retorno. La etapa de potencia debe ser exacta. Además de
mantener la diferencia de tensión adecuada para no dañar los motores, no se permite un
exceso o falta de corriente porque esto alteraría el movimiento del dispositivo.
Cuando se habla de un proyecto de este tipo, inmediatamente se asocia a una o
varias aplicaciones, tales como cámaras espías, de vigilancia o de caza, y si se añade un
botón de disparo, las aplicaciones tienen un buen agregado. De hecho, el proyecto en
cuestión pretende ser montado a un vehículo de rastreo de dos cámaras de video; la
primera, utilizada para acecho de un objetivo (posiblemente montada en ésta un láser o
algún dispositivo de disparo, el cual sería activado mediante el botón del joystick) y la
segunda cámara, movida paralelamente con la dirección del vehículo.
En general, el proyecto es un modelo inicial de las posibilidades de control
inalámbrica por telemetría, y aunque el proyecto fue terminado con algunos errores, es de
utilidad para proyectos posteriores, implementando sus respectivas modificaciones.
67
REFERENCIAS BIBLIOGRÁFICAS
• Motores de pasos, tema de la revista ElectroElectrónica de la Pontificia Universidad
Católica del Perú. 2do. semestre 1998, N° 10
• Jones on Stepper Motors
http://www.cs.uiowa.edu/~jones/step/circuits.html
• Stepper Motors, by Ian Harris
http://www.doc.ic.ac.uk/~ih/doc/stepper/control2/connect.html
http://www.doc.ic.ac.uk/~ih/doc/stepper/control2/sequence.html
• PIC16F62X Data Sheet
http://www.microchip.com
• Todo sobre PIC’s, Ing. Horacio Daniel Vallejo
• Stepping Motors, Douglas W. Jones, Departamento de ciencias de la computación
de la Universidad de Iowa.
http://www.uiowa.edu
http://www.cenece.com/faq.htm