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