Práctica de Laboratorio de Arquitectura de las computadoras - 4º Curso -
Universidad Pontificia de Salamanca en Madrid
- Facultad de Informática -
PLATAFORMA ORIENTABLE HACIA LA LUZ
Autores: Oscar Herrera Cabanillas David Nicolas Villen Naranjo Tutelado por: Andres Prieto-Moreno Torres |
1.DESCRIPCION GENERAL DEL PROYECTO
Se trata de una plataforma que se orienta hacia donde detecte mas luz.
Dicha plataforma consta de tres LDR y dos diodos LED. La plataforma está montada sobre un motor que será el encargado de moverla. Dos de los sensores están dispuestos en cada lateral de dicha plataforma y el tercero está situado justo en el centro. Si se detecta mas luz por alguno de los sensores de los laterales , la plataforma girará hacia el lado en que se encuentre situado el sensor. Si se detecta mas luz por el sensor central, la plataforma permanece inmóvil.
El giro del motor se ha limitado a 180 º para evitar que los cables que conectan la plataforma con el microcontrolador se enreden con el eje del motor al realizar giros mas grandes. Desde la posición inicial en la que se encuentra la plataforma, se podrá girar 90 º hacia la derecha o hacia la izquierda. Se dispone de dos diodos LED que se iluminan cuando la plataforma ha alcanzado el tope de giro y por tanto no puede seguir girando en ese sentido.
[ Foto 1 ] [ Foto 2 ] [ Foto 3 ] [ Foto 4 ]
2. DESCRIPCION DEL FUNCIONAMIENTO
El encargado de gobernar todo el funcionamiento es un microcontrolador PIC16F876. Este utiliza un cristal de cuarzo de 4 MHZ.
El motor utilizado es un motor paso a paso bipolar de cuatro hilos. Para poder mover el motor con el microcontrolador se ha utilizado el driver L293b.
También se han utilizado tres potenciómetros para ajustar la cantidad de luz que pueden detectar los tres LDR también utilizados y para evitar que la luz ambiente provoque un funcionamiento anómalo en el funcionamiento.
Se han conectado los LDR en serie con los potenciómetros y se ha aplicado una tensión de 5v. En función de la cantidad de luz, la tensión en el punto medio (unión de un potenciómetro con la LDR) varía. En condiciones normales, se han ajustado los potenciómetros para que la tensión en el punto medio sea de 2,5 V.
Se ha utilizado el conversor A/D para convertir las señales analógicas.
El conversor A/D del PIC16F876 tiene 10 bits de resolución. La entrada
analógica de 0 V le corresponde el código digital de 00 0000 0000
y para la de 5 V un código de 11 1111 1111.
Contra mayor luz detecte un sensor, menor valor decimal tendrá la representación
con esos diez bits. Por otro lado, si detecta menos luz, mayor será el
valor decimal representado. Para evitar que la luz ambiente afecte, se han considerado
válidos los valores decimales comprendido entre 0-255 correspondientes
a la conversión.
3.ESQUEMA ELECTRICO
![]() |
4. COMPONENTES UTILIZADOS
1 Microcontrolador
PIC16F876 1 Cristal de cuarzo XT 4MHZ 2 Condensadores cerámicos de 27 pF 2 Resistencias 4K7 1 Resistencia 330 ohmios 1 Resistencia 100 ohmios 3 Potenciómetros 10K 3 Sensores de luz ( LDR ) 1 Motor paso a paso bipolar 1 Driver L293b 3 Diodos LED 1 Portapilas 1 Pulsador 1 Interruptor |
5. DESCRIPCION DEL SOFTWARE
Lo primero de todo, es configurar los pines de los puertos utilizados por el
motor y por los diodos LED de salida y los correspondientes a las LDR de entrada.
Una vez configurado esto, hay que sincronizar las bobinas del motor con una secuencia, para evitar que cuando el motor tenga que girar lo haga de forma extraña durante un breve espacio de tiempo.
Lo siguiente es entrar en el bucle principal de la aplicación que será un bucle infinito. Lo que hace es convertir los valores proporcionados por los sensores con el conversor A/D. Si el valor decimal de estos valores están comprendidos entre 0-255 se consideran valores válidos y se cargarán en registros para posteriormente poder compararlos. Los registros utilizados se llaman VALORA0, VALORA1 y VALORA2 correspondientes a cada uno de los valores proporcionados por los sensores. Si los valores no son validos, en estos registros se cargará el valor FF.
Posteriormente se comparan dichos valores y en función de esta comparación se girará hacia un lado u otro, o bien se volverá a realizar una conversión.
6. CODIGO FUENTE
LIST P=16f876 include "P16f876.INC" RADIX HEX WREG EQU 0x00 Z EQU 0x02 TEMP1 EQU 0x20 ; Registros de propósito general. TEMP2 EQU 0x21 CONTA0 EQU 0x22 VALORA0 EQU 0x23 ; Valor de la conversion de los sensores VALORA1 EQU 0x24 VALORA2 EQU 0x25 CONTADE EQU 0x26 ; Contador para limitar el giro CONTAIZ EQU 0x27 ;***************************************************************** org 0x00 goto inicio org 0x05 inicio: clrf INTCON ;Se anulan las interrupciones. movlw 0X04 movwf CONTADE ; Limita el giro a la derecha. movwf CONTAIZ ; limita el giro a la izquierda. bcf STATUS,RP1 bsf STATUS,RP0 ; Seleccionamos el banco 1 movlw b'00000000' movwf TRISB ; Puerto B de salida movlw b'00000000' ; Puerto C de salida movwf TRISC movlw b'00000111' ; RA0,RA1 y RA2 como entradas movwf TRISA movlw b'10000000' ; Configuramos entradas analogicas movwf ADCON1 ; Resultado justificado en ADRESH. bcf STATUS,RP0 ; Seleccionamos banco1 clrf PORTA ; PORTA <- 0 clrf PORTC movlw b'00110101' ; Secuencia de inicializacion del motor. movwf PORTB ; Sincroniza las bobinas con una secuencia inicial call TEMPO ; para evitar un comportamiento anómalo la ; primera que recibe una secuencia de giro movlw b'00110101' movwf PORTB call TEMPO movlw b'00110101' movwf PORTB call TEMPO movlw b'00110101' movwf PORTB movlw b'00000000'; Se selecciona RA0 para realizar la conversion movwf ADCON0 bsf ADCON0,0 ; Activa el convertidor A/D convertir: call espera20u bsf ADCON0,2 ; Inicia la conversion espera: btfsc ADCON0,2 ; Espera a que termine la conversion goto espera bsf STATUS,RP0 movf ADRESL,0 bcf STATUS,RP0 movwf VALORA0 movf ADRESH,0 sublw b'00000000' ; Si ADRESH es 0x00, VALORA0=ADRESL btfsc STATUS,Z goto convertir2 movlw b'11111111' ; Si ADRESH <> 0x00, VALORA0=0xFF movwf VALORA0 convertir2: bsf ADCON0,3 ; Seleccionamos RA1 call espera20u bsf ADCON0,2 ; Inicia la conversion espera2: btfsc ADCON0,2 ; Espera a que termine la conversion goto espera2 bsf STATUS,RP0; movf ADRESL,0 bcf STATUS,RP0 movwf VALORA1 movf ADRESH,0 sublw b'00000000' ;Si ADRESH es 0x00, VALORA1=ADRESL btfsc STATUS,Z goto convertir3 movlw b'11111111' movwf VALORA1 ; Si ADRESH <> 0x00, VALORA0=0xFF convertir3: bcf ADCON0,3 ; bsf ADCON0,4 ; Seleccionamos RA2 call espera20u bsf ADCON0,2 ; Inicia la conversion espera3: btfsc ADCON0,2 ; Espera a que termine la conversion goto espera3 bsf STATUS,RP0; movf ADRESL,0 bcf STATUS,RP0 movwf VALORA2 movf ADRESH,0 sublw b'00000000' ;Si ADRESH es 0x00, VALORA1=ADRESL btfsc STATUS,Z goto comparar movlw b'11111111' movwf VALORA2 ; Si ADRESH <> 0x00, VALORA0=0xFF comparar: movf VALORA0,0 subwf VALORA2,0 ; Comparamos los extremos btfsc STATUS,Z goto configura ;Si los extremos son iguales, vuelve a coger valores btfss STATUS,0 ; Vemos cual es el que ha detectado mas luz goto compara2 ; RA2 Detecta mas luz compara1: movf VALORA0,0 ; RA0 Detecta mas luz subwf VALORA1,0 ; Restamos RA0 - RA1 (Central y extremo con mayor luz) btfsc STATUS,0 goto derecha ; RA0 es el sensor que detecta mas luz goto configura ; RA1 es el central y es el que tiene mas luz compara2: movf VALORA2,0 subwf VALORA1,0 ; Restamos RA2 - RA1 (Central y extremo con mayor luz) btfsc STATUS,0; goto izquierda ; RA2 es el sensor que detecta mas luz configura: movlw b'00000000' ; Se selecciona RA0 para realizar la conversion movwf ADCON0 bsf ADCON0,0 ; Activa el convertidor A/D goto convertir derecha: decfsz CONTADE,1 ; Comprobamos que no ha llegado al tope goto derechaok ; Si llega al tope que no gire incf CONTADE,1 ; y vuelva a tomar valores movlw 0x04 movwf PORTC goto configura derechaok: movlw 0x00 movwf PORTC incf CONTAIZ,1 movlw b'00110101' ; primer paso movwf PORTB call TEMPO ;Temporización antes de realizar el siguiente paso movlw b'00110110' ;segundo paso. movwf PORTB call TEMPO movlw b'00111010' ;tercer paso. movwf PORTB call TEMPO movlw b'00111001' ;cuarto y último paso movwf PORTB call TEMPO goto configura izquierda: decfsz CONTAIZ,1 ; Comprobamos que no ha llegado al tope goto izquierdaok ; Si llega al tope que no gire incf CONTAIZ,1 ; y vuelva a tomar valores movlw 0x08 movwf PORTC goto configura izquierdaok: movlw 0x00 movwf PORTC incf CONTADE,1 movlw b'00111001' ; Primer paso para el giro hacia la derecha. movwf PORTB call TEMPO ;Temporización antes de realizar el siguiente paso movlw b'00111010' ;Segundo paso. movwf PORTB call TEMPO movlw b'00110110' ;Tercer paso. movwf PORTB call TEMPO movlw b'00110101' ;Último paso. movwf PORTB call TEMPO goto configura ;****************************************************************************************** ;TEMPO Subrutina de temporización para poder enviar otra secuencia al motor. TEMPO movlw 0xFF ;carga FF en TEMP1 movwf TEMP1 clrf TEMP2 ;Carga 0 en TEMP2 TEMPO_1 decfsz TEMP2,1 ;Decrementa TEMP2 y si es 0 salta goto TEMPO_1 ;volver a TEMPO_1 decfsz TEMP1,1 ;Decrementa TEMP1 y si es 0 salta goto TEMPO_1 ;volver a TEMPO_1 RETURN ;********************************************************************************** ; espera20u Subrutina de espera para poder volver a tomar otro valor del conversor espera20u movlw 0x05 movwf CONTA0 ret1 decfsz CONTA0,1 goto ret1 return end |
7. PROBLEMAS Y SOLUCIONES
A lo largo del desarrollo del proyecto nos hemos encontrado con diversos problemas
que al final fueron resueltos con éxito. Mostramos una enumeración
de los mismos con sus soluciones:
1. El motor al recibir una secuencia para girar se comporta de manera extraña
Al enviar diferentes secuencias al motor, este empezaba a vibrar y ha realizar giros incontrolados. Inicialmente pensamos que podría deberse al driver L293b y después de revisar todas las conexiones compramos otro en la tienda de electrónica. Al sustituir el antiguo por el nuevo, el motor seguía comportándose de la misma forma. La segunda idea que se nos ocurrió era ver que secuencia estaba llegando al motor, por tanto se decidió poner unos diodos LED's. Nuestra sorpresa fue los diodos LED's estaban continuamente iluminados por lo que decidimos poner una pequeña pausa entre secuencia y secuencia. Esta era la causa del problema. Hay que pausar las secuencias enviadas al motorpara que este funcione bien.
2. Al enchufar la alimentación en el circuito, cuando el motor tenía
que girar por primera vez, tenía un comportamiento anómalo.
Esto es debido a que las bobinas del motor inicialmente no se encuentran en un estado conocido y hay que sincronizarlas con una secuencia inicial. Esta secuencia tiene que ser enviada antes de que hagamos girar el motor a nuestro antojo. La secuencia inicial puede observarse en el código.
3. No podemos cargar el valor de la conversión del registro ADRESH en un registro de propósito general.
Esto fue un fallo de programación muy común cuando uno está familiarizandose con el ensamblador del micro. El problema estaba en que no cambiamos de banco para realizar la carga del registro de propósito general a partir del registro ADRESH.
4. El programa no se ejecutaba a no ser que tocáramos con el dedo
el oscilador
La fuente de este error era la pata MCLR del PIC encargada de producir un reset al micro. Esta pata se activa a nivel bajo y nosotros en principio la dejábamos al aire. La solución fue poner un pulsador y una resistencia de pull-up. Esta puede observarse en el esquema del circuito.
[ Foto 1 ] [ Foto
2 ] [ Foto 3 ] [
Foto 4 ]
IEA ROBOTICS | Página de inicio | Dirección de contacto |