Sensor de Aparcamiento

Anuncio
David Ruiz Hernández
DSM
06/2007
Introducción
La base de esta práctica es el desarrollo de un proyecto utilizando como elemento base
un PIC. En un principio se iba a trabajar con el PIC 16f84, pero tras plantear la idea a
desarrollar, se descubrió que sería más fácil trabajar con un 18f1320, ya que posee un
conversor analógico/digital interno.
La idea planteada fue la siguiente; el desarrollo de un sensor de aparcamiento, el cual, a
partir de la señal devuelta por un sensor de distancia por infrarrojos, detectara la
distancia a la que está situado el obstáculo y mostrara por pantalla el valor de dicha
distancia.
Materiales y su descripción
PIC18f1320
Este PIC tiene una serie de particularidades que lo diferencian del PIC16f84,
pero en esta práctica, lo más señalado que nos incumbe es el A/D converter, ya que el
objetivo principal es tomar la medida de un sensor y mostrar por pantalla la distancia a
la que se encuentra un objeto.
Este conversor está integrado en el PIC y requiere una configuración básica, que
consiste en la modificación de los registros ADCON0 (para indicar las tensiones ref., el
canal utilizado y habilitar el conversor), ADCON1 (para indicar que puertos serán
utilizados como entradas analógicas), ADCON2 (para determinar el tiempo de
adquisición y la frecuencia)1
Todo lo anterior es antes de comenzar la adquisición. Una vez queremos tomar
datos, debemos esperar por el bit GO/DONE (ADCON0, 1) y esperar a que se ponga a
0, ya que esto indica que la toma de datos ha terminado, y luego mirar los registros
ADRESH y ADRESL, que es el lugar donde se almacena la salida dada por el
conversor y dicha salida es almacenada en 2 registros ya que su valor se devuelve en 10
bits.
*Nota: Se adjunta el diagrama de bloque del conversor
1
La configuración utilizada se explicará junto al código
Sensor de distancia por Infrarrojos: Sharp GP2D12
Para este proyecto se utilizo el mencionado sensor a
causa de que fue del que se disponía en el laboratorio.
En las especificaciones del sensor podemos encontrar
que el rango de sensibilidad está entre los 10 cm. y los 80 cm. y
su curva de calibración “original” es la siguiente:
Para resumir, se adjunta la tabla de especificaciones del sensor, donde podemos
observar sus rangos de trabajo, tanto de tensión como de distancia:
Placa PICDEM4
Programador T20
Desarrollo
Como en un principio se ignoraba el funcionamiento de la pantalla LCD, y esta
era una parte muy importante para el desarrollo del proyecto, se optó por crear un
pequeño programa el cuál utilizara dicha pantalla.
Este programa consistía básicamente en un contador del número de veces que se
pulsaba el botón correspondiente al RB0 y mostrar dicho valor por pantalla2, aunque
parecía un ejercicio relativamente sencillo, se encontraron muchas dificultades que se
comentan en el apartado de dificultades.
Durante el desarrollo de esta “prueba” se descubre que la librería facilitada con
la placa para el manejo del LCD nos facilita una serie de funciones que nos permiten,
desde elegir la línea en la que se quiere escribir, hasta el lugar en el que se desea situar
el cursor.
Una vez se consigue escribir de una forma coherente en pantalla, comenzamos
con el calibrado del sensor, es decir que se tomaron una serie de entradas y acorde a las
salidas se mide la distancia.
El calibrado no se realizó tomando unos voltajes de referencia, sino que
directamente se conectó el sensor al circuito en el que estaba el PIC y con la ayuda del
conversor A/D del microcontrolador se calibró el sensor.
Al hacer las conexiones nos dimos cuenta que se debía conectar la salida a una
resistencia (0,5 K) conectada con tierra porque si no la respuesta siempre era constante,
además de esto, se observó que el voltaje de referencia debía ser menor que el de
entrada ya que las medidas eran demasiado imprecisas y para ello se necesitó un divisor
de tensión que consistía en dos resistencias en serie (R1=1,5 K y R2=1 K).
2
El código se adjunta en los anexos
Tras insertar el divisor de tensión, las conexiones quedan de la siguiente manera:
la salida del sensor se conectó a una resistencia (como se menciona anteriormente) y los
puertos que se encargan de los valores de referencia quedan conectados al divisor de
tensión (uno a 5 V, y otro a 3 V), y por último, los puntos de alimentación de la placa se
conectan también al circuito en el que se encuentra el divisor, para así no tener que
utilizar dos fuentes
Antes de explicar cómo se realizó el calibrado, indicar que en el PIC se guardaba
la respuesta en 3 registros, ya preasignados al convertidor A/D. Una vez aclarado esto,
comenzamos con el calibrado, con la ayuda de un flexómetro, comenzamos a medir
desde 10 cm hasta 80 cm, ya que ese era el rango que las especificaciones del sensor nos
indicaban que este funcionaba correctamente, pero durante las pruebas tuvimos que
cambiar dichas “medidas de referencia”, ya que a partir de 15 cm hacia abajo y 50 cm
hacia arriba el sensor daba problemas en el circuito montado. Por lo tanto decidimos
que las medidas devueltas por el sensor estarían dentro de ese rango, y las respuestas
variarían de 5 en 5 cm, salvo en los casos que las medidas se salieran de rango, ya que si
estábamos muy cerca, simplemente indicaba que la distancia era menor a 15 cm y si
estábamos muy lejos, no indicaba nada “-- centimetros”.
Ya una vez calibramos, utilizamos los valores almacenados en los 3 registros del
conversor para averiguar cual era la distancia a la que nos encontrábamos y a partir de
esto ir mostrando los mensajes en pantalla, aunque durante la ejecución del programa, lo
único que varía es la distancia, ya que al principio se inicializa la pantalla con el texto:
---------------------------------------|
Esta usted a menos de: |
|
centimetros
|
---------------------------------------y luego, simplemente se varía el valor del número de centímetros a los que estamos.
Antes de proseguir, aclarar que se eligen intervalos de 5 cm, ya que el sensor no
daba medidas claramente diferenciadas en un rango menor.
A nivel de código, el PIC adquiría los datos a partir de una interrupción la cual
se encargaba de comprobar si el sensor había leído y si lo había hecho, se encargaba de
volcar los datos en unos registros para así poderlos evaluar.
Un ejemplo de funcionamiento del sensor es: para una medida de 23 cm, el PIC
mostrará por pantalla
---------------------------------------|
Esta usted a menos de: |
|
25
centimetros
|
---------------------------------------Quedando la tabla de la salida del sensor de la siguiente manera:
viéndose que en los “puntos críticos” el sensor puede dar unos valores “varaibles”.
Una vez se calibró el sensor se desarrolló el código para unir la parte del LCD
con la adquisición de datos para ya dar por terminado.
CODIGO
Primero, a parte de los includes y de las inicializaciones se establece le valor de los
registros de configuración
__CONFIG
_CONFIG1H, _IESO_OFF_1H & _FSCM_OFF_1H &
_INTIO2_OSC_1H
__CONFIG _CONFIG2L, _PWRT_ON_2L & _BOR_OFF_2L & _BORV_27_2L
__CONFIG _CONFIG2H, _WDT_OFF_2H & _WDTPS_32_2H
__CONFIG _CONFIG3H, _MCLRE_ON_3H
__CONFIG
_CONFIG4L, _DEBUG_OFF_4L & _LVP_OFF_4L &
_STVR_OFF_4L
__CONFIG _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L
__CONFIG _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H
__CONFIG _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L
__CONFIG
_CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H &
_WRTD_OFF_6H
__CONFIG _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L
__CONFIG _CONFIG7H, _EBTRB_OFF_7H
Luego, se realizan las inicializaciones, destacando el trabajo con el TIMER para
controlar el tiempo de lanzamiento de la interrupción.
bcf RCON, 7
bsf INTCON, 7
bsf INTCON, 5
movlw 0C7h
movwf T0CON ;TMR0 hab, 8bit, presc0
Tras esto entramos en el bucle que inicializa el cursor y manda los datos al selector de
mensajes (tra) para que este mande la distancia acordada.
Po
movlw
0x00
movwf
vIOExpLCD_X
movlw
0x00
call
IOExpLCDSetCursor
movff tenx, ten
movff totx, tot
movff interx, inter
goto tra
Otro punto a destacar del código es la interrupción, que además de comprobar si se esta
realizando una medida, almacena en 3 variables el resultado de dicha medida
in
bsf ADCON0, 1
movwf auxw
movf STATUS, 0
bu
ne
movwf auxs
btfss ADCON0, 1
goto ne
goto bu
movlw B'00001111'
andwf ADRESL, 0
movwf interx
movlw B'11110000'
andwf ADRESL, 0
movwf totx
rrncf totx
rrncf totx
rrncf totx
rrncf totx
movlw B'00000011'
andwf ADRESH, 0
movwf tenx
bcf
INTCON, 2
movf auxs, 0
movwf STATUS
movf auxw, 0
retfie
Dificultades
Las principales dificultades reencontraron en el momento de trabajar con el LCD,
ya que se facilitaban una serie de librerías para hacerlo funcionar a través del PIC
18f1320 pero no se explicaba su funcionamiento por ningún lado.
Otra dificultad añadida, fue el comenzar a trabajar sobre un PIC (el 18f1320) del
que se tenia muy poca información, y gran parte del tiempo de desarrollo del proyecto
lo llevó la documentación sobre dicho microcontrolador
Por otro lado, y no menos lioso, apareció un problema con el sensor, ya que la
variación era muy pequeña a largas distancias, y la calibración se izo muy difícil para
dichas distancias.
En cuestión del código, no fue muy costoso, ya que tras el trabajo extra que
supuso el conflicto con el LCD, y que la prueba utilizada para que este elemento
funcionara era muy similar al funcionamiento del proyecto.
ANEXOS
Codigo utilizado para probar el LCD
;######################################################################
############
;# TITLE "I/O Expander Driven LCD Display Test Software
;#
;#
;# Program:
MAIN.ASM
;#
Version:
1.0
;#
Revision Date:
;#
Author:
CG
;#
;#
;# Program demonstrates use of an I/O expander to manage an LCD Interface
;######################################################################
############
tot
equ 0x20
sum equ 0x21
temp equ 0x22
ten
equ 0x23
inter equ 0x24
auxw equ 0x25
auxs equ 0x26
at
equ 0x27
tota equ 0x28
#define
PIC18
;set the test to use PIC16 device
;#define
_ADD_PROC_INC_FILE
#ifdef
PIC16
list p=16f819
include <P16F819.INC>
#else
list p=18f1320
include <P18F1320.INC>
#endif
include "IOExpLCD.inc"
include "LCDMsgs.inc"
include "SPImb.inc"
;-------------------------------------------------------------------;COPIADO DEL PICDEM18
__CONFIG
_CONFIG1H, _IESO_OFF_1H & _FSCM_OFF_1H &
_INTIO2_OSC_1H
__CONFIG _CONFIG2L, _PWRT_ON_2L & _BOR_OFF_2L & _BORV_27_2L
__CONFIG _CONFIG2H, _WDT_OFF_2H & _WDTPS_32_2H
__CONFIG _CONFIG3H, _MCLRE_ON_3H
__CONFIG
_CONFIG4L, _DEBUG_OFF_4L & _LVP_OFF_4L &
_STVR_OFF_4L
__CONFIG _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L
__CONFIG _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H
__CONFIG _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L
__CONFIG
_CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H &
_WRTD_OFF_6H
__CONFIG _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L
__CONFIG _CONFIG7H, _EBTRB_OFF_7H
;--------------------------------------------------------------------STARTUP CODE 0x0000
goto start
CODE 0x0008
goto in
Real_Code_Start
CODE
start
#ifdef
PIC18
;bsf
ADCON1,PCFG5
for I2C as digital
;bsf
ADCON1,PCFG6
movlw B'0111000'
movwf OSCCON
setf
ADCON1
;call LongDelay
#endif
clrf inter
clrf tota
bcf RCON, 7
;bsf INTCON2, 2
bsf INTCON, 7
bsf INTCON, 5
movlw 0C5h
movwf T0CON ;TMR0 hab, 8bit, presc0
;bcf T0CON, 6
clrf tot
clrf ten
movlw 030h
movwf sum
call
IOExpLCDInit
call
IOExpLCDHideCursor
call
IOExpLCDLine1
mIOExpLCDSendMessage Prueba
call
IOExpLCDLine2
goto Po
aux movlw 09h
cpfseq tot
goto I
goto Ix
Ix
movlw
0x06
movwf
vIOExpLCD_X
;set pins used
movlw
0x01
call
IOExpLCDSetCursor
movf ten, 0
addwf sum, 0
call
IOExpLCDWriteData
movlw 030h
call
IOExpLCDWriteData
incf inter
goto Po
I
movlw
0x07
movwf
vIOExpLCD_X
movlw
0x01
call
IOExpLCDSetCursor
movf tot, 0
addwf sum, 0
call IOExpLCDWriteData
incf inter
goto Po
Po
movf tota, 0
cpfseq inter
goto aux
goto Po
i
incf tot
incf tota
goto fi
ix
incf ten
clrf tot
incf tota
goto fi
ax2
movlw 09h
cpfseq tot
goto i
goto ix
ps
btfss temp, 0 ; Comprueba si el pulsador fue pulsado
goto fi
goto ax2
bot btfsc PORTB, 0 ; Comprueba si el pulsador esta pulsado o no
goto ps
bsf temp, 0
goto bot
in
movwf auxw
movf STATUS, 0
movwf auxs
clrf temp
goto bot
fi
bcf
INTCON, 2
bcf temp, 0
movf auxs, 0
movwf STATUS
movf auxw, 0
retfie
goto
$
END
Codigo del Proyecto
tot
equ 0x20
ten equ 0x21
inter equ 0x22
sum equ 0x23
totx equ 0x24
tenx equ 0x25
interx equ 0x26
auxw equ 0x27
auxs equ 0x28
#define
PIC18
;#define
_ADD_PROC_INC_FILE
;set the test to use PIC16 device
#ifdef
PIC16
list p=16f819
include <P16F819.INC>
#else
list p=18f1320
include <P18F1320.INC>
#endif
include "IOExpLCD.inc"
include "LCDMsgs.inc"
include "SPImb.inc"
;-------------------------------------------------------------------;COPIADO DEL PICDEM18
__CONFIG
_CONFIG1H, _IESO_OFF_1H & _FSCM_OFF_1H &
_INTIO2_OSC_1H
__CONFIG _CONFIG2L, _PWRT_ON_2L & _BOR_OFF_2L & _BORV_27_2L
__CONFIG _CONFIG2H, _WDT_OFF_2H & _WDTPS_32_2H
__CONFIG _CONFIG3H, _MCLRE_ON_3H
__CONFIG
_CONFIG4L, _DEBUG_OFF_4L & _LVP_OFF_4L &
_STVR_OFF_4L
__CONFIG _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L
__CONFIG _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H
__CONFIG _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L
__CONFIG
_CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H &
_WRTD_OFF_6H
__CONFIG _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L
__CONFIG _CONFIG7H, _EBTRB_OFF_7H
;--------------------------------------------------------------------STARTUP CODE 0x0000
goto start
CODE 0x0008
goto in
Real_Code_Start
CODE
start
#ifdef
PIC18
;bsf
ADCON1,PCFG5
for I2C as digital
;bsf
ADCON1,PCFG6
movlw B'0111000'
movwf OSCCON
setf
ADCON1
;call LongDelay
#endif
goto S
;ADRESH
;ADRESL
in
bsf ADCON0, 1
movwf auxw
movf STATUS, 0
movwf auxs
bu
btfss ADCON0, 1
goto ne
goto bu
ne
movlw B'00001111'
andwf ADRESL, 0
movwf interx
movlw B'11110000'
andwf ADRESL, 0
movwf totx
rrncf totx
rrncf totx
rrncf totx
rrncf totx
movlw B'00000011'
andwf ADRESH, 0
movwf tenx
bcf
INTCON, 2
movf auxs, 0
movwf STATUS
movf auxw, 0
retfie
cerca call
IOExpLCDLine2
mIOExpLCDSendMessage crqui
goto Po
quive call
IOExpLCDLine2
mIOExpLCDSendMessage quiven
goto Po
vevc
call
IOExpLCDLine2
mIOExpLCDSendMessage veci
goto Po
;set pins used
vctre call
IOExpLCDLine2
mIOExpLCDSendMessage vctrei
goto Po
tretc
call
IOExpLCDLine2
mIOExpLCDSendMessage tretci
goto Po
tccu
call
IOExpLCDLine2
mIOExpLCDSendMessage tccua
goto Po
cucc
call
IOExpLCDLine2
mIOExpLCDSendMessage cucci
goto Po
cccq
call
IOExpLCDLine2
mIOExpLCDSendMessage ccci
goto Po
cqse
call
IOExpLCDLine2
mIOExpLCDSendMessage cqses
goto Po
sesc
call
IOExpLCDLine2
mIOExpLCDSendMessage sesci
goto Po
sest
call
IOExpLCDLine2
mIOExpLCDSendMessage sestn
goto Po
scst
call
IOExpLCDLine2
mIOExpLCDSendMessage sctn
goto Po
maxim call
IOExpLCDLine2
mIOExpLCDSendMessage maxi
goto Po
atr
movlw 05H
cpfslt inter
goto cccq
goto cqse
ads
movlw 05H
cpfslt inter
goto cqse
goto sesc
aun
movlw 05h
cpfslt inter
goto sesc
goto scst
ace
movlw 08h
cpfslt tot
goto scst
goto maxim
uno
movlw 0AH
cpfslt tot
goto tccu
movlw 06h
cpfslt tot
goto cucc
movlw 03h
cpfslt tot
goto atr
movlw 02H
cpfslt tot
goto ads
movlw 01H
cpfslt tot
goto aun
goto ace
dos
movlw 0Bh
cpfslt tot
goto vctre
movlw 03h
cpfslt tot
goto vctre
goto tretc
tres
movlw 06H
cpfslt tot
goto cerca
goto quive
tra
movlw 03H
cpfslt ten
goto tres
movlw 02h
cpfslt ten
goto dos
goto uno
S
clrf totx
clrf tenx
clrf interx
movlw 030h
movwf sum
bcf ADCON1, 4
bcf ADCON1, 3
movlw B'01010001'
movwf ADCON0
movlw B'10000011'
movwf ADCON2
call
IOExpLCDInit
call
IOExpLCDHideCursor
call
IOExpLCDLine1
mIOExpLCDSendMessage Prueba
call
IOExpLCDLine2
mIOExpLCDSendMessage cntm
bcf RCON, 7
bsf INTCON, 7
bsf INTCON, 5
movlw 0C7h
movwf T0CON ;TMR0 hab, 8bit, presc0
Po
movlw
0x00
movwf
vIOExpLCD_X
movlw
0x00
call
IOExpLCDSetCursor
movff tenx, ten
movff totx, tot
movff interx, inter
goto tra
END
Descargar