Autor Tema: Medidor ADC con transmisión RS232 infrarroja  (Leído 13308 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Medidor ADC con transmisión RS232 infrarroja
« en: 19 de Septiembre de 2008, 15:52:11 »
Hola

Hace unos días terminé un proyecto muy simple que tuve que realizar en ensamblador  :x   :D Lo comparto ya que tiene lo más básico para usar visual basic y pics para comunicación serial.

Pueden encontrar el proyecto completo en esta página (cálculos e imágenes del circuito)...

http://www.migsantiago.com/index.php?option=com_content&view=article&id=7&Itemid=8

El objetivo fue construir un circuito que mediante el uso de un microcontrolador PIC16 obtenga la medición de un voltaje y lo transmita vía infrarrojo a una interfaz RS232 de una computadora.

Operación del PIC

El pic que se empleó es el PIC16F877A ya que cuenta con los periféricos que se necesitaban para la aplicación, siendo estos el temporizador de 8 bits, el generador de modulación de ancho de pulso (PWM), el convertidor analógico-digital de 10bits y el puerto serial RS232.

El oscilador del PIC es un cristal de 4MHz y su fuente de alimentación puede ser de 4V a 5.5V, siendo en el caso de la aplicación un paquete de baterías de 4.5V.

Configuración de las entradas y salidas del PIC

El pic solo controla 5 de sus 33 terminales de entrada-salida. Las terminales empleadas son las siguientes:

    * Salida PWM a 38kHz -> RC2
    * Salida TX RS232 -> RC6
    * Entrada ADC -> RA0
    * Entrada de referencias de voltaje ->RA3 (Vref+) y RA2 (Vref-)

La configuración de las demás terminales se dejó como entrada.

Configuración de la modulación por ancho de pulso (PWM)

El PWM se necesita en la aplicación para generar una señal de 38kHz como portadora de la transmisión de información por puerto serial. La señal debe ser de 38kHz debido a que el receptor infrarrojo TSOP1738 empleado solo demodula señales con tal frecuencia, entregándolas en niveles TTL. Esto se explicará más a detalle en la sección del circuito.

Para la configuración del PWM la frecuencia de trabajo requerida es de 38kHz y el periodo de trabajo requerido es del 50%.

Configuración del Timer 0

El timer 0 se emplea en la aplicación para generar retardos de 960ms. Se configuró el timer 0 para funcionar con una pre-escala de 1:256 y un desbordamiento de su registro de 8 bits cada 64ms. Para lograr un tiempo total de 960ms solo se cuentan los desbordamientos del timer 0 por 15 veces.

Configuración del ADC de 10 bits

Se emplea el ADC del pic para medir el voltaje presente en la terminal A0 y posteriormente reportarlo vía infrarrojo.

La configuración del ADC empleada es la siguiente:

    * Frecuencia de reloj del convertidor = Fosc / 32
    * Canal de medición: RA0
    * Terminales de referencia: RA3 como Vref+ y RA2 como Vref-
    * Justificación de la conversión: Derecha (útil para 10 bits)

Configuración del puerto serial RS232

Se empleó el módulo USART del pic con las siguientes características:

    * Velocidad de conexión: 2400bps
    * Modo asíncrono (full-dúplex)
    * Tamaño de palabra 8 bits
    * Sin Paridad

Circuito ADC y emisor



El circuito cuenta con un sensor de temperatura LM35 que entrega 10mV/°C, o bien, 100°C/V. Se conecta a un amplificador operacional LM324 configurado como amplificador no inversor con una ganancia de 4. El LM324 puede funcionar sin fuentes bipolares. Posteriormente se tiene un capacitor de 1uF que reduce el ruido a la entrada A0 del ADC.

El voltaje de referencia positivo del ADC en RA3 se obtiene mediante un diodo zener de 3.3V, y el voltaje de referencia negativo solo se conecta a tierra.

Se colocan unos capacitores de 1uF muy cerca de las terminales Vdd y Vss del pic para filtrar posible ruido inducido por la fuente de alimentación.

El ánodo del diodo emisor de luz infrarroja se conecta a una resistencia de 330ohms para limitar su corriente. Su cátodo se conecta a la salida de la transmisión RS232 (TX RC6). Una conexión de este tipo genera lo siguiente:

    * Si CCP1 está en alto y TX en alto, el led no emite luz.
    * Si CCP1 está en bajo y TX en alto, el led no emite luz.
    * Si CCP1 está en alto y TX en bajo, el led emite luz.
    * Si CCP1 está en bajo y TX en alto, el led no emite luz.

Cuando TX está en bajo, el led estará emitiendo luz infrarroja a 38kHz con la señal PWM de CCP1, es decir, tiene una lógica inversa. Esto resulta bastante útil porque el circuito receptor cuenta con un foto módulo TSOP1738 que funciona de la siguiente manera:

    * Si TSOP recibe una señal infrarroja de 38kHz, entrega una salida de 0V.
    * Si TSOP no recibe una señal infrarroja de 38kHz, entrega una salida de 5V.

Cuya operación también resulta ser de lógica inversa, y cuando recibe la información generada con el led infrarrojo la revierte quedando los voltajes en su lógica original.

Se eligió una velocidad de conexión serial de 2400bps ya que el fabricante del TSOP1738 lo maneja como la máxima velocidad posible en su hoja de características.

Circuito Receptor y RS232



El circuito empleado para la recepción emplea el módulo infrarrojo TSOP1738 y un MAX232N que adapta los voltajes TTL recibidos por el TSOP1738 a voltajes de ±8.5V, que son los necesarios para realizar una conexión con el puerto RS232 de una PC.

La comunicación realizada es solo de recepción de parte de la PC ya que no se implementó la transmisión hacia el pic.

Programa en ensamblador del PIC16F877A

A continuación se muestra el programa completo del pic, compilado con MPLAB 8.0.

Código: [Seleccionar]
LIST P=16f877a
__config  B'11111100111001'
;CRISTAL 4MHz
;FUSIBLES CONFIGURADOS EN MPLAB (CONFIG BITS)
;OSCILADOR XT, NO WDT, POWER UP TIMER, NO LVP, NO CODE PROTECT

include "p16f877a.inc"

;Santiago Villafuerte
;Septiembre 2008

;Programa que obtiene la medición de lo que esté conectado
;en la terminal RA0 mediante el ADC.
;Posteriormente toma los 10 bits que el ADC genera y
;los envía por el puerto serie TX.
;La transmisión infrarroja se logra generando una portadora de
;38kHz gracias al PWM y conectando un led emisor infrarrojo
;entre las terminales RC2 y RC6 con su resistencia de 330ohms.

;La recepción se hace en una computadora con puerto serie y
;conectando un MAX232 junto con un TSOP1738 para demodular la
;señal infrarroja, todo esto a una velocidad de 2400bps, que es
;el ancho de banda que recomienda el fabricante del TSOP1738

;TERMINALES
;Salida PWM a 38kHz -> RC2
;Salida TX -> RC6
;Entrada ADC -> RA0

;CALCULOS PWM
;f=38kHz
;Tpwm=26.3157us
;duty time= 13.1578us
;Tpwm=(PR2+1)4 Tosc PRtm2
;Tpwm=(25+1)(4)(1/4MHz)(1)=26us
;fpwm=1/26us=38.461kHz
;duty time=CCP Tosc PRtm2
;duty time=52(1/4MHz)(1)=13us
;Res=[log(4MHz/38.461KHz)/log 2]=6.7bit=6bit
;52d=0x34=110100b O.K.

;VARIABLES
CONTEO EQU 0X20

ORG 0X0000

;CONFIGURA ENTRADAS Y SALIDAS
;TRISC
BSF STATUS,RP0 ;BANCO 1
MOVLW B'10111011' ;RC2 Y RC6 SALIDA
MOVWF TRISC
;TRISA
MOVLW B'11111111' ;RA0 ENTRADA
MOVWF TRISA

;CONFIGURA ENTRADAS ANALÓGICAS Y ADC
MOVLW B'10001111' ;JUST DER,F0SC/32,RA0 VREF +A3 Y -A2
MOVWF ADCON1
BCF STATUS,RP0 ;BANCO 0
MOVLW B'10000001' ;F0SC/32,CANAL A0,ADON
MOVWF ADCON0

;CONFIGURA TIMER 0 PARA SUBRUTINA DE RETARDO
BSF STATUS,RP0 ;BANCO 1
MOVLW B'11010111' ;T0CS INTERNO, TOSE ALTO A BAJO
MOVWF OPTION_REG ;PRESCALER EN TMR0 Y 1:256

;CONFIGURA PWM
MOVLW D'25'
MOVWF PR2
BCF STATUS,RP0 ;BANCO 0
MOVLW B'00001101' ;DUTY = B'00001101 00'=52D
MOVWF CCPR1L
MOVLW B'00000100' ;1:1 POST, TM2 ON, 1:1 PRE
MOVWF T2CON
MOVLW B'00001111' ;DUTY = B'00001101 00',PWM
MOVWF CCP1CON

;CONFIGURA RS232
BSF STATUS,RP0 ;BANCO 1
MOVLW D'25' ;25 GENERA 2403.84bps
MOVWF SPBRG
BCF TXSTA,SYNC ;HABILITA MODO ASINC
BCF STATUS,RP0 ;BANCO 0
BSF RCSTA,SPEN ;SERIAL PORT ACTIVADO
BSF STATUS,RP0 ;BANCO 1
BSF TXSTA,TXEN ;HABILITA TRANSMISION
BCF STATUS,RP0 ;BANCO 0

;ESPERA 3 SEGUNDOS APROX PARA QUE SE ESTABILICE EL ENCENDIDO
CALL RETARDO
CALL RETARDO
CALL RETARDO

;ENVIA NOMBRE POR TX
; MOVLW D'9' ;9 CARACTERES
; MOVWF CONTEO
;LEETABLA CALL TABLA ;COPIA LETRA
;TXBUF BTFSS PIR1,TXIF ;VERIFICA SI PUEDE ESCRIBIR EN BUFFER
; GOTO TXBUF
; MOVWF TXREG
; DECFSZ CONTEO,F ;SIG. LETRA
; GOTO SIG2 ;TABLA PENDIENTE
; GOTO SIG ;TABLA TERMINADA
;SIG2 MOVF CONTEO,W
; GOTO LEETABLA
;SIG CALL RETARDO

;TOMA LA MEDICION DE VOLTAJE EN RA0 Y LA ENVIA POR RS232
CICLO_INF BSF ADCON0,GO ;INICIA MEDICION
AD_ESPERA BTFSC ADCON0,GO
GOTO AD_ESPERA
BCF PIR1,ADIF ;LIMPIA BANDERA AD
MOVF ADRESH,W ;COPIA LOS 2 BITS MS DE LA MEDICION
MOVWF TXREG
TXBUF2 BTFSS PIR1,TXIF ;VERIFICA SI PUEDE ESCRIBIR EN BUFFER
GOTO TXBUF2
BSF STATUS,RP0 ;BANCO 1
MOVF ADRESL,W ;COPIA LOS 8 LSb DE LA MEDICION
BCF STATUS,RP0 ;BANCO 0
MOVWF TXREG
CALL RETARDO ;ESPERA 960ms
GOTO CICLO_INF ;CICLO INFINITO

;///////////////////////////////////////////////////////////////
;SUBRUTINA DE TIEMPO DE 960ms
RETARDO MOVLW D'15' ;15 X 64ms = 960ms
MOVWF CONTEO
CICLO MOVLW D'06' ;GENERA 64ms
MOVWF TMR0
CICLO2 BTFSS INTCON,T0IF ;ESPERA EL DESBORDE
GOTO CICLO2
BCF INTCON,T0IF ;LIMPIA BANDERA
DECFSZ CONTEO,F ;BRINCA SI YA ES CERO
GOTO CICLO
RETURN

;///////////////////////////////////////////////////////////////
;TABLA CON NOMBRE
;TABLA ADDWF PCL,F
; NOP
; RETLW ' '
; RETLW '0'
; RETLW 'G'
; RETLW 'A'
; RETLW 'I'
; RETLW 'N'
; RETLW 'A'
; RETLW 'S'
END

Programa del Receptor en Visual Basic

El programa fue hecho en Visual Basic 6 SP5. La interfaz con el usuario es la siguiente:



El programa recibe 2 bytes en el puerto COM1 ya que el ADC del pic está operando con resolución de 10 bits. El cálculo del valor entero resultará en un valor que va de 0 hasta 1023, siendo 0 el equivalente al voltaje de referencia negativo y 1023 el equivalente al voltaje de referencia positivo.

La conversión de los valores ASCII recibidos como cadena se logra con el código siguiente:

binario = (Asc(bin_msb) * 256) + (Asc(bin_lsb)) 'calcula de 0 a 1023

Siendo bin_msb el byte más significativo y bin_lsb el byte menos significativo de la conversión ADC. El byte bin_msb solo contiene 2 bits de importancia (bit 1 y bit 0) y el byte bin_lsb contiene 8, siendo en total los 10 bits de la conversión. Los 2 bits más significativos se multiplican por 256 y posteriormente se suma el contenido del byte menos significativo para obtener la medición.

Posteriormente solo se hace una conversión entre unidades de ingeniería y su equivalente en V, según el sensor que se esté empleando.

El código fuente de la forma usada en Visual Basic se muestra a continuación:

Código: [Seleccionar]
'Santiago Villafuerte
'Programa que recibe una cadena pequeña con la conversión ADC
'de un PIC a través del puerto serial a 2400bps
'Convierte el valor de 8 bits en una unidad de ingeniería
'Recibe los voltajes de referencia con los que el pic fue
'configurado
'Solo trabaja con COM1

'Mis variables
Public vrefpos As Double
Public vrefneg As Double
Public voltaje As Double
Private captura As Boolean

Private Sub btnCaptura_Click()
cadena = MSComm1.Input
captura = True
btnCaptura.Enabled = False
btnDetener.Enabled = True
txtVrefp.Enabled = False
txtVrefn.Enabled = False
txtUIV.Enabled = False
txtUI.Enabled = False
End Sub

Private Sub btnDetener_Click()
captura = False
btnCaptura.Enabled = True
btnDetener.Enabled = False
txtVrefp.Enabled = True
txtVrefn.Enabled = True
txtUIV.Enabled = True
txtUI.Enabled = True
End Sub

'Subfunción que se ejecuta al principio de la aplicación
Private Sub Form_Load()
    'Configura puerto serial COM1
    MSComm1.Settings = "2400,N,8,1"
    MSComm1.CommPort = 1 'usa el com1
    MSComm1.InputLen = 0 'tamaño de buffer de entrada
    MSComm1.PortOpen = True 'abre puerto
    MSComm1.RThreshold = 1 'habilita el evento ante recepción
                           'en buffer después de recibir 1 byte
    vrefneg = txtVrefn.Text 'valores iniciales de referencia
    vrefpos = txtVrefp.Text

End Sub

'aquí llega si el com1 tuvo cambios en rx o tx
Private Sub MSComm1_OnComm()
If (MSComm1.InBufferCount >= 2) And (captura = True) Then 'el pic envía 2bytes cada 960ms
    cadena = MSComm1.Input
    cadrec.Caption = cadena
    vrefneg = txtVrefn.Text 'valores de referencia
    vrefpos = txtVrefp.Text
    bin_msb = Mid(cadena, 1, 1) 'copia el 1er byte de la cadena
    bin_lsb = Mid(cadena, 2, 1) 'copia el 2do byte
    binario = (Asc(bin_msb) * 256) + (Asc(bin_lsb)) 'calcula de 0 a 1023
    conv.Caption = binario
    volts = ((binario / 1023) * (vrefpos - vrefneg)) + vrefneg
    lblVolts.Caption = volts
    UIV = txtUIV.Text
    uing = volts * UIV 'convierte a unidades de ing.
    lblUMedidas.Caption = CStr(uing)
    lblUMedidas.Caption = Mid(lblUMedidas.Caption, 1, 5) + " " + txtUI.Text
   
End If
End Sub


Errores conocidos en el programa y circuito

- El voltaje de referencia dado por el diodo zener no es constante ya que depende de la fuente de alimentación y de la corriente que fluye por el diodo Esto implica que la conversión ADC pueda tener un error indeterminado.

- No se implementó corrección de errores en la comunicación infrarroja en Visual Basic por lo que el programa puede mostrar desbordamiento de cadena y fallar.

- El sensor de temperatura LM35 cuenta con un error de ±0.5°C en su medición.

- No se considera tampoco el offset que el LM324 tiene al amplificar el voltaje del LM35.
« Última modificación: 21 de Marzo de 2009, 15:06:28 por migsantiago »

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Medidor ADC con transmisión RS232 infrarroja
« Respuesta #1 en: 20 de Septiembre de 2008, 02:43:20 »
Muy ilustrativo y didáctico, querido Migsantiago.

Dices que es simple, pero seguro que te has tenido que topar con muchas dificultades en esa transmisión serial por infrarrojos.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Medidor ADC con transmisión RS232 infrarroja
« Respuesta #2 en: 20 de Septiembre de 2008, 14:21:18 »
jaja nop  :P Ya conoces al tsop y lo fácil que es usarlo  :mrgreen:

Es verdaderamente simple cuando usas la hyperterminal.

Este diseño lo hice hace como 2 años cuando estaba experimentando con controles remotos de 38kHz (leyendo tus experimentos y los de Redpic). Un día vi una página en donde usaban el tsop1738 y el pwm del pic solo para detectar obstáculos y de ahí que se me ocurriera adecuar la comunicación serial.

Desconectado allado

  • PIC10
  • *
  • Mensajes: 10
    • Circuitos Impresos
Re: Medidor ADC con transmisión RS232 infrarroja
« Respuesta #3 en: 25 de Septiembre de 2008, 21:02:16 »
Hola Amigo.

Gracias por presentarnos tu proyecto.... una duda que tengo, que  distancias se puede manejar con infrarrojos? 10 metros mas o menos?
La humildad es el hilo con el que se encadena la gloria.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Medidor ADC con transmisión RS232 infrarroja
« Respuesta #4 en: 26 de Septiembre de 2008, 18:12:39 »
Hola

Depende del LED infrarrojo y de la corriente que fluya por él.

En mi diagrama le puse una R de 330ohms y una fuente de 4.5V. Si le pones una R de 180ohms y una fuente de 5V la distancia debe ser como de 8 metros, es cuestión de jugar con la R ya que todos los leds son diferentes.

Desconectado Chrisbaf

  • PIC16
  • ***
  • Mensajes: 178
Re: Medidor ADC con transmisión RS232 infrarroja
« Respuesta #5 en: 27 de Septiembre de 2008, 16:16:39 »
Gracias y felicitaciones exelente aporte.

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: Medidor ADC con transmisión RS232 infrarroja
« Respuesta #6 en: 27 de Septiembre de 2008, 16:21:12 »
Mágnifica presentación del proyecto, amigo Santiago. Mis mas sinceras felicitaciones.  :mrgreen: :mrgreen: :mrgreen:
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Medidor ADC con transmisión RS232 infrarroja
« Respuesta #7 en: 27 de Septiembre de 2008, 21:50:19 »
Gracias  :mrgreen:


 

anything