Hardware - Creando una estación propia 1

informacion sacada de
http://99055.forums.motigo.com/?action=messages_show&boardmessage_id=525604

Empezé con un circuito capaz de medir la temperatura del medio ambiente. Utiliza un microcontrolador PIC 16F877, un LCD para ver el valor y como sensor, utilizo el LM35.

Al momento lo tengo montado en un protorboard funcionando. Ya subo las imágenes junto con el circuito y el programa para que lo puedan descargar y armar.

La particularidad de este circuito que utilizo con el LM35, es que mide con décimos. Algo que en muchos circuitos que hay en la red, solo lo hacen con enteros.



El Zener D1. sirve para fijar la tensión de referencia +Vref en 2,5V O sea que el CAD del PIC, me va a entregar B'1111111111' cuando mida en el canal seleccionado 2,5V

Los amplificadores operacionales, están configurado como seguidor de tensión y se utiliza solo por la impedancia, entre el CAD del PIC y el sensor. Como se puede observar, un AO está conectado a la salida del sensor LM35 y el otro en el PIN GND del sensor.

R2, sirve para elevar la tensión de referencia hacia al sensor. Está calibrada para que entregue uns tensión de 1V, así, cuando el sensor mida 150ºC, me entregue una tensión de 2,5V y cuando mida -55ºC, el sensor me entregue 0,45V. A 0ºC, la tensión será de 1V

¿Porqué mido la tensión de referencia con el PIC si se que es de 1V? para reducir el mínimo error y el programa sea autoajustable. También, como los componentes tienen una tolerancia, el POT es de seguro que no me entrega 1V todo el tiempo, y si la temperatura es constante, la salida será constante mientras no varíe la tensión de referencia del sensor. Si la temperatura es constante, y el pot oscila entregandome pequeñas variaciones, la tensión de salida del sensor, variará con la oscilación del pot.

Está adjuntado también, el programa y el archivo .hex listo para ser cargado al pic, y probarlo. La particularidad de este programa, es que trabaja con los 10bit de resolución del CAD. Como es sabido, los dos bit menos significativos del CAD varían mucho. Son muy sensibles. Algunos eliminan estos 2 bit ajustando a la izquierda la conversión y trrabajando con solo 8 bit. Si hacía lo mismo, no podía usarlo con décimo y mi objetivo es que mida con décimo. Para solucionar el problema de la variación continua en cada sensado de los dos bit menos sognificativos, y haciendo imposible su lectura, lo que hise fue tomar 42 muestras, y promediarlas, el resultado es con muy poca variación y lenta, haciendo su lectura en el LCD muy fácil.

Para no extenderme y aburrirlos, les explico como funciona el programa para que lo sigan y lo entiendan.

1- Muestra en el LCD la frase TEMPERATURA
2- Sensa la tensión entregada por el sensor y lo guarda en la RAM.
3- Sensa la tensión entregada por el pot2 y lo guarda en la RAM.
4- Resta estos dos valores obteniendo la temperatura del sensor como si el pin GND, estuviera a 0V. No obstante, el valor obtenido, corresponde a la resolución del CAD. También me fijo si la temperatura es negativa o positiva.
5- Lo multiplico por 244 para pasar el valor a volt, que corresponde a la temperatura.
6- Lo divido por 100 para trabajar solo con 4 dígitos.
7- Si la temperatura es positiva, lo guardo en el banco 2, y si es negativa en el banco 3
8- Tomo en total 42 muestras, repitiendo los pasos del 2 hasta 7
9- Una vez tomado las 42 muestras, hago el promedio
10- Descompongo el promedio en centena, decena, unidad y décimo.
11- Lo muesto en el LCD
12- Espero 1 segundo y luego empiezo desde el punto 2.

SI bien parece complicado, el programa está bien explicado. Si tienen alguna duda, la explicaré con todo gusto.

El programa está muy desordenado y da bastante que desear, pero hace muy bien su objetivo. Dentro de poco la modificaré para hacerlo más eficiente y ordenado. De todas maneras lo pueden modificar a su gusto.

Las rutinas que llamo con la instrucción INCLUDE, están en el post Rutinas para compartir (haciendo click aquí). Un punto importante que hay que tener encuenta, es que la rutina del LCD hay que modificarlas. Solo hay que modificar las líneas de manejo del LCD. O sea, hay que cambiar el puerto a por el puerto d.


El programa lo pueden descargar de aquí: http://www.ucontrol.com.ar/for osmf/index.php?topic=315.0


Mi siguiente paso, será agregarle un sensor de humedad. De varios sensores que puedo conseguir, me inclino por el sensor HIH-4000. Este sensor expresa la humedad variando su tensión de salida. Y por lo que se puede ver, tiene una gran linealidad HR/Volts.

Dado que el sensor trabaja con tensión y el PIC utilizado tiene una CAD integrado, no necesito de otros circuitos integrados o circuitería adicional para poder utilizarlo, salvo el AO para miniminar los problemas de impedancia.

La ventaja de este sensor que trabaja variando su tensión en la salida, me ahorro de circuitos convertidores a tensión. Hay sensores que trabajan variando su capacidad, los sensores de humedad capacitivos como el sensor 5X38H122R de la marca MEPCO//ELECTRA son muy confiables, pero em microprocesador no trae medidor de capacidades.

Por el momento, empezaré a modificar el programa anterior para poder sensar la humedad y una vez comprado el sensor, poder empezar a experimentar.

Recuerden que voy a facilitar el programa junto con el diseño del PCB para que ustedes también, puedan armar la estación automática.


Devido a mi distracción, me olvidé de mencionar que el esquemático anteriormente subido, solo está configurado para medir temperaturas positivas. Para que mida temperaturas negativas, hay que agregarle una resistencia a la salida del sensor y este conectado a -VS. Mi intención es que el circuito funcione con baterías y para obtener una fuente simétrica a partir de una fuente simple, utilizaré el CI [ujrl=http://www.alldatasheet. com/datasheet-pdf/pdf/67436/IN TERSIL/ICL7660.html]ICL7660[/u rl]

También eh actualizado mi programa anterior para que muestre °C y lo he ordenado para que se pueda entender mejor. Copio y pego aquí el programa en assembler.

LIST P=16F877A
INCLUDE
__CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC
;
;----------------------------- ------------------------------ ----
;VARIABLES.
;----------------------------- ------------------------------ ----
;
CBLOCK H'20'
dem1
dem2
cursor
curdisp
poeslcd
cuenta_tabla
centena ;millar por que llega hasta 1024
decena ;centena idem anterior
unidad ;decena idem anterior
decimo ;unidad idem anterior
ACCaHI ;2A
ACCaLO ;2B
ACCbHI ;2C
ACCbLO ;2D
ACCcHI ;2E
ACCcLO ;2F
multiplicador ;30
mresul3 ;31
mresul2 ;32
mresul1 ;33
resAL ;34 RESTA 1 AUXILIAR
resBA ;35 RESTA 2 AUXILIAR
;
CARRY ;36
DATO1 ;37 dato 1 (8 bits + significativos)
DATO2 ;38
DATO3 ;39
DATO4 ;3A dato 1 (8 bits - significativos)
FUNC1 ;3B dato 2 (8 bits + significativos)
FUNC2 ;3C
FUNC3 ;3D
FUNC4 ;3E dato 2 (8 bits - significativos)
RES1 ;3F resultado (8 bits + significativos)
RES2 ;40
RES3 ;41
RES4 ;42 resultado (8 bits - significativos)
TEMP1 ;43
TEMP2 ;44
TEMP3 ;45
TEMP4 ;46
PDel0 ;47
PDel1 ;48
PDel2 ;49
muestras ;4A
positivoAL ;4B
positivoBA ;4C
negativoAL ;4D
negativoBA ;4E
;4F
ENDC
;
estado EQU H'7F' ;7F
;
;***************************** ************************
;ESTADO:
;
;B0: 1: HAY DATOS NEGATIVOS
; 0: NO HAY DATOS NEGATIVOS
;
;B1 1: HAY DATOS POSITIVOS
; 0: NO HAY DATOS POSITIVOS
;
;B2 1: DATOS POSITIVOS
; 0: DATOS NEGATIVOS
;
;
;
CBLOCK H'110'
positivo_AL ;110h HASTA 168h BANCO 2. PARTE ALTA DEL RESULTADO DEL PROMEDIO
positivo_BA ;PARTE BAJA DEL RESULTADO DEL PROMEDIO
ENDC
;
CBLOCK H'169' ;DIRECCIÓN A APUNTAR PARA LOS POSITIVOS
dir1
prom_pos ;CANTIDAD DE VECES A DIVIDIR PARA HACER EL PROMEDIO POSITIVOS
prom_pos_alt
ENDC
;
CBLOCK H'190'
negativo_AL ;190h HASTA 1E8h BANCO 3. PARTE ALTA DEL RESULTADO DEL PROMEDIO
negativo_BA ;PARTE BAJA DEL RESULTADO DEL PROMEDIO
ENDC
;
CBLOCK H'1E9' ;DIRECCIÓN A APUNTAR PARA LOS NEGATIVOS
dir2
prom_neg ;CANTIDAD DE VECES A DIVIDIR PARA HACER EL PROMEDIO NEGATIVO.
prom_neg_alt
ENDC
;
;
RESET ORG H'00'
GOTO INICIO
ORG H'04' ;VECTOR INTERRUPCIÓN
INTERRUP
;
;
;
;TABLAS
;
;----------------------------- -------
;TABLA
;----------------------------- -------
;
TABLA ADDWF PCL,F
NOP
RETLW 'T'
RETLW 'E'
RETLW 'M'
RETLW 'P'
RETLW 'E'
RETLW 'R'
RETLW 'A'
RETLW 'T'
RETLW 'U'
RETLW 'R'
RETLW 'A'
;
TABLA_2 ADDWF PCL,F
RETLW '0'
RETLW '1'
RETLW '2'
RETLW '3'
RETLW '4'
RETLW '5'
RETLW '6'
RETLW '7'
RETLW '8'
RETLW '9'
;
INCLUDE RutinaLCD.inc
;
INCLUDE MUL16X8BIT.INC
;
INCLUDE RESTA32BIT CHARLY.INC
;
INCLUDE SUMA_RESTA.INC
;
;
;DEMORAS
;
DELAY_5MS MOVLW .6
MOVWF dem1
DEMLOOP2 MOVLW .207
MOVWF dem2
DEMLOOP1 NOP
DECFSZ dem2,1
GOTO DEMLOOP1
DECFSZ dem1,1
GOTO DEMLOOP2
NOP
NOP
NOP
RETURN
;
;RUTINA PARA GRABAR EL SÍMBOLO °C ECHO CON EL PROGRAMA DE PALI
;
caracter0_direccion:
addwf PCL, F
dt 0x40,0x41,0x42,0x43,0x44,0x45, 0x46,0x47
caracter0_datos:
addwf PCL, F
dt b'11000',b'11011',b'00100',b'0 0100',b'00100',b'00011',b'0000 0',b'0'
;
;DEMORA DE 1 SEGUNDO.
;
DEMORA movlw .16 ; 1 set numero de repeticion (C)
movwf PDel0 ; 1 |
PLoop0 movlw .72 ; 1 set numero de repeticion (B)
movwf PDel1 ; 1 |
PLoop1 movlw .247 ; 1 set numero de repeticion (A)
movwf PDel2 ; 1 |
PLoop2 clrwdt ; 1 clear watchdog
decfsz PDel2, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop2 ; 2 no, loop
decfsz PDel1, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop1 ; 2 no, loop
decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ? (C)
goto PLoop0 ; 2 no, loop
PDelL1 goto PDelL2 ; 2 ciclos delay
PDelL2 clrwdt ; 1 ciclo delay
goto PRE_ADQ_TEMP ; 2+2 Fin.
;
M_TEMP CALL PRE_LCD
CLRF cuenta_tabla
NO_TERMINO_TABLA
PAGESELW TABLA
INCF cuenta_tabla,F
MOVFW cuenta_tabla
CALL TABLA
CALL LCD_DATO
MOVLW D'11'
SUBWF cuenta_tabla,W
BTFSS STATUS,Z
GOTO NO_TERMINO_TABLA
RETURN
;
GRADO CLRF cuenta_tabla
CICLO movf cuenta_tabla, W
Call caracter0_direccion
Call LCD_REG
movf cuenta_tabla, W
Call caracter0_datos
Call LCD_DATO
;
incf cuenta_tabla, 1
movlw 0x8
xorwf cuenta_tabla, W
btfss STATUS,Z ;Comprueba si es el último
goto CICLO ; NO ha llegado al final
;
MOVLW H'92' ;POCICIÓN A MOSTRAR EL CARACTER GUARDADO
MOVWF poeslcd
CALL PO_ES_LCD
MOVLW .0 ;MUESTRO EL CARACTER GUARDADO QUE ESTÁ EN LA POCICIÓN 0 POR ESO MUESTRO EL 0 COMO DECIMAL Y NO COMO CÓDIGO ASCII
CALL LCD_DATO
RETURN
;
ADQUISICIÓN BSF ADCON0,GO ;INICIO LA CONVERSIÓN
CAD BTFSC ADCON0,GO ;¿TERMINÓ LA CONVERSIÓN?
GOTO CAD ;NO, VUELVO A CAD
RETURN
;
VALOR_POSITIVO
MOVLW H'8C'
MOVWF poeslcd
CALL PO_ES_LCD
MOVLW ' '
CALL LCD_DATO
RETURN
;
VALOR_NEGATIVO
MOVLW H'8C'
MOVWF poeslcd
CALL PO_ES_LCD
MOVLW '-'
CALL LCD_DATO
RETURN
;
;
PRE_ADQ_TEMP
BCF STATUS,RP0
BSF STATUS,RP1 ;BANCO 2
CLRF prom_pos
BSF STATUS,RP0 ;BANCO 3
CLRF prom_neg
BCF STATUS,RP0
BCF STATUS,RP1 ;BANCO 0
CLRF estado ;BORRAMOS EL REGISTRO ESTADO
MOVLW .84
MOVWF muestras ;CARGAMOS CON 42 A MUESTRAS (EN REALIDAD ES 84 POR QUE CADA MUESTRA OCUPA DOS POCICIONES)
;
;RUTINA PARA BORRAR LAS VARIABLES DONDE SE ALOJARÁN LAS MUESTRAS.
;
BSF STATUS,IRP ;DIRECCIONAMIENTO INDIRECTO BANCO 2,3
MOVLW H'10'
MOVWF FSR ;DIRECCIÓN A APUNTAR
REP_POS CLRF INDF ;BORRO LA POCICIÓN APUNTADA
INCF FSR,F
DECFSZ muestras,F ;¿ES CERO?
GOTO REP_POS ;NO
MOVLW .84 ;SI, BORRAMOS LAS NEGATIVAS
MOVWF muestras
MOVLW H'90'
MOVWF FSR
REP_NEG CLRF INDF
INCF FSR,F
DECFSZ muestras,F ;¿ES CERO?
GOTO REP_NEG ;NO
MOVLW H'69' ;SI, DEJO INICIALIZADA LAS DIRECCIONES
MOVWF FSR ;A APUNTAR PARA GUARDAR LAS MUESTRAS
MOVLW H'10'
MOVWF INDF
MOVLW H'E9'
MOVWF FSR
MOVLW H'90'
MOVWF INDF
;
DATO_MUESTRAS
MOVLW .42
MOVWF muestras
GOTO ADQ_TEMP
TOTAL_MUESTRAS
DECFSZ muestras,F
GOTO ADQ_TEMP
MOVLW H'69' ;DEJO INICIALIZADA LAS DIRECCIONES
MOVWF FSR ;A APUNTAR PARA GUARDAR LAS MUESTRAS
MOVLW H'10'
MOVWF INDF
MOVLW H'E9'
MOVWF FSR
MOVLW H'90'
MOVWF INDF
GOTO FIN_PROMEDIO
;
ADQ_TEMP BSF STATUS,RP0
BCF STATUS,RP1 ;BANCO 1
MOVLW B'00001001'
MOVWF TRISA ;RA0 y RA3 COMO ENTRADA, DEMÁS SALIDAS
BCF STATUS,RP0 ;BANCO 0
MOVLW B'10000001' ;ADC ENC. CANAL AN0. FREC Fosc/32
MOVWF ADCON0 ;Y LO PASO AL ADCON0
BSF STATUS,RP0 ;BANCO 1
MOVLW B'10000001' ;+VREF RA3, ALINEACIÓN A LA DERECHA Y PORTA TODAS ANALÓGICAS.
MOVWF ADCON1 ;Y LO PASO AL ADCON1
BCF STATUS,RP0 ;BANCO 0
BCF PIR1,ADIF ;INDICO QUE LA CONVERSIÓN NO ESTÁ ECHA
NOP
NOP
NOP
NOP
CALL ADQUISICIÓN ;COMIENZO LA CONVERSIÓN
;----------------------------- ------------------------------
;PASAMOS LA CONVERSIÓN A LA MEMORIA RAM
;----------------------------- ------------------------------
MOVFW ADRESH
MOVWF ACCbHI
MOVWF TEMP1 ;SALVO EN TEMP1 POR SI LA RESTA ES NEGATIVO
BSF STATUS,RP0
MOVFW ADRESL
BCF STATUS,RP0
MOVWF ACCbLO
MOVWF TEMP2 ;SALVO EN TEMP2 POR SI LA RESTA ES NEGATIVO
;
CALL DELAY_5MS ;ESPERAMOS 5MS PARA UNA NUEVA CONVERSIÓN
;
ADQ_REF BSF STATUS,RP0
BCF STATUS,RP1 ;BANCO 1
MOVLW B'00001010'
MOVWF TRISA
MOVLW B'10000001'
MOVWF ADCON1 ;+VREF RA3, ALINEACIÓN A LA DERECHA Y PORTA TODAS ANALÓGICAS
BCF STATUS,RP0
MOVLW B'10001001'
MOVWF ADCON0 ;ADC ENC. CANAL AN1. FREC Fosc/32
BCF PIR1,ADIF ;INDICO QUE LA CONVERSIÓN NO ESTÁ ECHA
NOP
NOP
NOP
NOP ;PARA ESTABILIZAR
CALL ADQUISICIÓN
;----------------------------- ------------------------------
;PASAMOS LA CONVERSIÓN A LA MEMORIA RAM
;----------------------------- ------------------------------
MOVFW ADRESH
MOVWF ACCaHI
MOVWF TEMP3
BSF STATUS,RP0
MOVFW ADRESL
BCF STATUS,RP0
MOVWF ACCaLO
MOVWF TEMP4
;----------------------------- ------------------------------
;RESTAMOS LOS DOS VALORES PARA QUE ME DÉ EL VALOR REAL SI EL VALOR ES NEGATIVO, LA TEMPERATURA TEMBIÉN LO ES.
;RESULTADO EN ACCb Y COMO ALTERNATIVO res
;----------------------------- ------------------------------
CALL RESTA
BTFSS STATUS,C ;¿ES NEGATIVO?
GOTO TEMP_NEGATIVA ;SI, LA TEMPERATURA ES NEGATIVO
BSF estado,1 ;NO. AJUSTAMOS LOS ESTADOS CORRESPONDIENTES. HAY DATOS POSITIVOS A PROMEDIAR
BSF estado,2 ;EL DATO DE AHORA ES POSITIVO.
GOTO DESCOMPONER_NÚMERO
;
TEMP_NEGATIVA
MOVFW TEMP1 ;AL SER NEGATIVO, VUELVO HACER LA RESTA PERO INVIERTIENDO
MOVWF ACCaHI ;EL MINUENDO POR EL SUBTRAENDO, ASÍ NOS DÁ EL VALOR CORRECTO
MOVFW TEMP2 ;ES POR ELLO QUE GUARDAMOS LOS DATOS EN TEMP
MOVWF ACCaLO ;PARA PASARLO INVIRTIÉNDOLO Y YA NO ES NECESARIO CHEQUEAR EL
MOVFW TEMP3 ;BIT C, YA QUE SABEMOS QUE ES NEGATIVO.
MOVWF ACCbHI
MOVFW TEMP4
MOVWF ACCbLO
CALL RESTA
;
BSF estado,0 ;HAY DATOS NEGATIVOS A PROMEDIAR
BCF estado,2 ;EL DATO DE AHORA ES NEGATIVO
;DESCOMPONER_NÚMERO

;
;----------------------------- ------------------------------ ------
;UNA VEZ RESTADOS LAS DOS ADIQUICICIONES, MULTIPLICAMOS EL RESULTADO POR 244 ASÍ LO PASAMOS A VOLT.
;SE OBTIENE UN RESULTADO DE 24 BIT. LUEGO, LO DIVIDIMOS POR 100 PARA QUEDARNOS CON LOS VALORES DESEADOS,
;HASTA 4 DÍGITOS QUE NOS CONSUMIRÁ DOS REGISTRO DE 8 BITS.
;
;UNA VEZ ECHO ESTO,TOMAMOS 42 MUESTRAS. Y HACEMOS EL PROMEDIO. PARA ELLO, PRIMERO SUMAMOS
;TODAS LAS TEMPERATURAS, Y LUEGO LO DIVIDIMOS POR 42. ESTO NOS DA EL PROMEDIO.

;CUANDO OBTENEMOS EL PROMEDIO, LO DESCOMPONEMOS EN CENTENA, DECENA, UNIDAD Y DÉCIMO.
;
;NOTA: QUE HACER CUANDO LA TEMPERATURA ES NEGATIVA Y POSITIVA.
;SI LA TEMPERATURA ES POSITIVA, SE ALMACENAN DESDE H'110' HASTA H'168' BANCO 2
;SI LA TEMPERATURA ES NEGATIVA, SE ALMACENAN DESDE H'190' HASTA H'1E8' BANCO 3
;
;LA FORMA DE HACER EL PROMEDIO VARÍA SI TENEMOS POSITIVOS O NEGATIVOS O LOS DOS.
;1er CASO: SOLO POSITIVOS. SUMAMOS LAS 42 MUESTRAS (DOS NÚMEROS DE 8 BITS) Y LUEGO LO DIVIDIMOS POR 42
; EL RESULTADO ES EL DATO A MOSTRAR LUEGO VOLVEMOS A EMPEZAR TOMANDO DE NUEVO LAS 42 MUESTRAS
;2dO CASO: SOLO NEGATIVOS. LO TRATAMOS COMO SI FUERAN POSITIVOS Y EN EL MOMENTO DE MOSTRAR EL DATO,
; MOSTRAMOS EL SIGNO MENOS EN EL LCD.
;3er CASO: POSITIVOS Y NEGATIVOS. PRIMERO SUMAMOS LOS POSITIVOS Y HACEMOS EL PROMEDIO. LO GUARDAMOS EN LA MEMORIA
; LUEGO SUMAMOS LOS NEGATIVOS Y HACEMOS EL PROMEDIO. LO GUARDAMOS EN LA MEMORIA. PARA OBTENER EL DATO A MOSTRAR
; RESTAMOS EL PROMEDIO POSITIVO CON EL PROMEDIO NEGATIVO. DE ESTA MANERA TENEMOS 3 OPCIONES
; 1- EL PROMEDIO POSITIVO ES MAYOR QUE EL NEGATIVO, EL DATO OBTENIDO ES POSITIVO. NOS DAMOS CUENTA CHEQUEANDO EL BIT C
; 2- EL PROMEDIO POSITIVO EN MENOR QUE EL NEGATIVO, EL DATO OBTENIDO ES NEGATIVO. NOS DAMOS CUENTA CHEQUEANDO EL BIT C
; 3- EL PROMEDIO POSITIVO ES IGUAL QUE EL NEGATIVO, EL DATO OBTENIDO ES CERO.
;

;
;MULTIPLICAMOS POR 244.
;
DESCOMPONER_NÚMERO
;
MOVFW ACCbHI
MOVWF mresul2
MOVFW ACCbLO
MOVWF mresul1
MOVLW .244
MOVWF multiplicador
CALL MULTIPLICAR ;MULTIPLICAMOS Y OBTUVIMOS UN RESULTADO DE 24 BIT EN ACCbLO,ACCcHI,ACCcLO
MOVFW mresul1
MOVWF ACCcLO
MOVFW mresul2
MOVWF ACCcHI
MOVFW mresul3
MOVWF ACCbLO
CLRF ACCbHI
;............................. ......
;DIVIDIMOS EN 100 PARA OBTENER EL VALOR A ALMACENAR SOLO EN 4 DÍGITOS, EL RESULTADO OBTENIDO ESTA EN ACCb
;............................. ......
;
MOVFW ACCcLO
MOVWF DATO4
MOVFW ACCcHI
MOVWF DATO3
MOVFW ACCbLO ;RECUPERO EL VALOR PARA PASARLO A DATO2
CLRF ACCbLO ;BORRO ESTA POCICIÓN PARA SU POSTERIOR USO.
MOVWF DATO2
MOVFW ACCbHI ;RECUPERO EL VALOR PARA PASARLO A DATO1
CLRF ACCbHI ;BORRO ESTA POCICIÓN PARA SU POSTERIOR USO.
MOVWF DATO1 ;
CLRF RES1
CLRF RES2
CLRF RES3
CLRF RES4
DATO_PARC MOVLW .100 ;DIVISOR
MOVWF FUNC4
CLRF FUNC3
CLRF FUNC2
CLRF FUNC1
CALL RESTA2
BTFSS STATUS,C ;¿ES NEGATIVO?
GOTO RES_NEG ;ES NEGATIVO
MOVFW RES4
MOVWF DATO4
MOVFW RES3
MOVWF DATO3
MOVFW RES2
MOVWF DATO2
MOVFW RES1
MOVWF DATO1
MOVLW .1 ;ES POSITIVO
ADDWF ACCbLO,F ;SUMO 1
BTFSS STATUS,C ;¿HUBO ACARREO?
GOTO DATO_PARC ;NO
ADDWF ACCbHI,F ;SUMO 1
GOTO DATO_PARC ;VUELVO A RESTAR
;
;ANALIZAMOS SI LA TEMPERATURA ES NEGATIVA O PISITIVA
;
RES_NEG BTFSS estado,2 ;¿ES POSITIVO?
GOTO DATO_NEG ;ES NAGATIVO
;
;GUARDAMOS LOS DATOS EN EL BANCO CORRESPONDIENTE
;
;PARA POSITIVOS
;
BCF STATUS,RP0 ;ES POSITIVO
BSF STATUS,RP1 ;BANCO 2
MOVFW dir1 ;DIRECCIÓN A APUNTAR
MOVWF FSR ;APUNTAMOS
BCF STATUS,RP1 ;BANCO 0
MOVFW ACCbHI ;RECUPERO EL RESULTADO MAS SIGNIFICATIVO
BSF STATUS,RP1 ;BANCO 2
MOVWF INDF ;GUARDAMOS EL DATO EN LA POCICIÓN APUNTADA EN FSR
INCF FSR,F ;INCREMENTAMOS EL FSR PARA GUARDAR EL RESULTADOS MENOS SIGNIFICATIVO
BCF STATUS,RP1 ;BANCO 0
MOVFW ACCbLO ;RECUPERO EL RESULTADO MENOS SIGNIFICATIVO
BSF STATUS,RP1 ;BANCO 2
MOVWF INDF ;PASAMOS EL VALOR A LA POCICIÓN APUNTADA EN FSR
INCF prom_pos,F ;INCREMENTO EN 1 A PROM_POS
INCF FSR,F
MOVFW FSR ;PASAMOS EL DATO A W
MOVWF dir1 ;Y LO SALVAMOS PARA SU POSTERIOR USO
BCF STATUS,RP1 ;BANCO 0
GOTO TOTAL_MUESTRAS
;
;PARA NEGATIVOS
;
DATO_NEG BSF STATUS,RP0 ;
BSF STATUS,RP1 ;BANCO 3
MOVFW dir2
MOVWF FSR
BCF STATUS,RP0
BCF STATUS,RP1
MOVFW ACCbHI
BSF STATUS,RP0
BSF STATUS,RP1
MOVWF INDF
INCF FSR,F
BCF STATUS,RP0
BCF STATUS,RP1
MOVFW ACCbLO
BSF STATUS,RP0
BSF STATUS,RP1
MOVWF INDF
INCF prom_neg,F
INCF FSR,F
MOVFW FSR
MOVWF dir2
BCF STATUS,RP0
BCF STATUS,RP1
GOTO TOTAL_MUESTRAS
;
;REALIZAMOS EL PROMEDIO
;
FIN_PROMEDIO
BTFSS estado,1 ;¿HAY VALORES POSITIVOS?
GOTO DATOS_NEGATIVOS ;NO HAY. SOLOS NEGATIVOS.
;
;DATOS POSITIVOS, LOS SUMAMOS Y EL RESULTADO ESTÁ EN ACCb
;
BCF STATUS,RP0 ;SI HAY
BSF STATUS,RP1 ;BANCO 2
MOVFW prom_pos ;SALVAMOS LA CANTIDAD DE DATOS POSITIVOS
BCF STATUS,RP1 ;BANCO 0
MOVWF prom_pos_alt ;PARA SABER CUANTAS VECES HAY QUE SUMARLAS, PARA LUEGO DIVIDIRLAS.
BSF STATUS,RP1 ;BANCO 2
MOVFW dir1
MOVWF FSR ;DIRECCIÓN A LEER
MOVFW INDF ;EL VALOR EN FSR SE GUARDA EN W
BCF STATUS,RP1 ;BANCO 0
MOVWF ACCbHI
BSF STATUS,RP1 ;BANCO 2
INCF FSR,F ;DIRECCIÓN A APUNTAR SEGUNDO DATO
MOVFW INDF
BCF STATUS,RP1 ;BANCO 0
MOVWF ACCbLO
BSF STATUS,RP1 ;BANCO 2
INCF FSR,F
MOVFW FSR
MOVWF dir1
;
SUMAR_PROMEDIO
BSF STATUS,RP1 ;BANCO 2
MOVFW dir1
MOVWF FSR
MOVFW INDF
BCF STATUS,RP1 ;BANCO 0
MOVWF ACCaHI
BSF STATUS,RP1 ;BANCO 2
INCF FSR,F
MOVFW INDF
BCF STATUS,RP1 ;BANCO 0
MOVWF ACCaLO
BSF STATUS,RP1 ;BANCO 2
INCF FSR,F
MOVFW FSR
MOVWF dir1
BCF STATUS,RP1 ;BANCO 0
CALL D_addF
DECFSZ prom_pos_alt,F
GOTO SUMAR_PROMEDIO
;
;OBTUVIMOS LA SUMA EN ACCb, AHORA HACEMOS EL PROMEDIO DIVIDIENDO POR LA CANTIDAD DE MUESTRAS OBTENIDAS
;
CLRF positivoBA
CLRF positivoAL
PROM_POS CLRF ACCaHI
BSF STATUS,RP1 ;BANCO 2
MOVFW prom_pos
BCF STATUS,RP1 ;BANCO 0
MOVWF ACCaLO
CALL RESTA
BTFSS STATUS,C ;¿ES NEGATIVO?
GOTO PROM_NEG
MOVLW .1
ADDWF positivoBA,F
BTFSS STATUS,C ;¿HUBO EXESO?
GOTO PROM_POS
ADDWF positivoAL,F
GOTO PROM_POS ;VUELVO A DIVIDIR
;
;CHEQUEAMOS SI HAY NEGATIVOS.
;
PROM_NEG BTFSC estado,0 ;¿HAY DATOS NEGATIVOS?
GOTO DATOS_NEGATIVOS ;SI HAY

ANT_DESCOMPONER ;NO HAY
CALL VALOR_POSITIVO ;NO. CARGAMOS EL LUGAR DESDE DÓNDE EMPEZARÁ A MOSTRAR LOS DATOS EL LCD
MOVFW positivoBA
MOVWF TEMP2
MOVFW positivoAL
MOVWF TEMP1
GOTO DESCOMPONER
;

;
DATOS_NEGATIVOS
BSF STATUS,RP0
BSF STATUS,RP1 ;BANCO 3
MOVFW prom_neg
BCF STATUS,RP0 ;BANCO 0
BCF STATUS,RP1
MOVWF prom_neg_alt
BSF STATUS,RP0
BSF STATUS,RP1 ;BANCO 3
MOVFW dir2
MOVWF FSR
MOVFW INDF
BCF STATUS,RP0
BCF STATUS,RP1
MOVWF ACCbHI
BSF STATUS,RP0
BSF STATUS,RP1
INCF FSR,F
MOVFW INDF
BCF STATUS,RP0
BCF STATUS,RP1
MOVWF ACCbLO
BSF STATUS,RP0
BSF STATUS,RP1
INCF FSR,F
MOVFW FSR
MOVWF dir2
;
SUMAR_PROMEDIO_NEG
BSF STATUS,RP1 ;BANCO 3
BSF STATUS,RP0
MOVFW dir2
MOVWF FSR
MOVFW INDF
BCF STATUS,RP1 ;BANCO 0
BCF STATUS,RP0
MOVWF ACCaHI
BSF STATUS,RP1 ;BANCO 3
BSF STATUS,RP0
INCF FSR,F
MOVFW INDF
BCF STATUS,RP1 ;BANCO 0
BCF STATUS,RP0
MOVWF ACCaLO
BSF STATUS,RP1 ;BANCO 3
BSF STATUS,RP0
INCF FSR,F
MOVFW FSR
MOVWF dir2
BCF STATUS,RP1 ;BANCO 0
BCF STATUS,RP0
CALL D_addF
DECFSZ prom_neg_alt,F
GOTO SUMAR_PROMEDIO_NEG
;
;OBTUVIMOS LA SUMA EN ACCb, AHORA HACEMOS EL PROMEDIO DIVIDIENDO POR LA CANTIDAD DE MUESTRAS OBTENIDAS
;
CLRF negativoBA
CLRF negativoAL
PROM_POS_A CLRF ACCaHI
BSF STATUS,RP1
BSF STATUS,RP0 ;BANCO 3
MOVFW prom_neg
BCF STATUS,RP0
BCF STATUS,RP1 ;BANCO 0
MOVWF ACCaLO
CALL RESTA
BTFSS STATUS,C ;¿ES NEGATIVO?
GOTO PROM_NEG_A
MOVLW .1
ADDWF negativoBA,F
BTFSS STATUS,C ;¿HUBO EXESO?
GOTO PROM_POS_A
ADDWF negativoAL,F
GOTO PROM_POS_A
;
;EL ÚLTIMO PASO ES CHEQUEAR QUE SI HAY POSITIVOS Y NEGATIVOS A RESTAR. EN ESTA PARTE NO SABEMOS SI HAY DE LOS DOS O UNO SOLO.
;
PROM_NEG_A BTFSC estado,1 ;¿HAY POSITIVOS?
GOTO RESTAR_AMBOS ;SI, HAY QUE RESTAR POSITIVOS - NEGATIVOS.
MOVFW negativoBA ;NO, MOSTRAMOS EL PROMEDIO NEGATIVO AL LCD
MOVWF TEMP2
MOVFW negativoAL
MOVWF TEMP1
CALL VALOR_NEGATIVO
GOTO DESCOMPONER
;
;----------------------------- ------------------------------ -------
;RESTAMOS LOS POSITIVOS CON NEGATIVOS. EL RESULTADO QUEDA EN ACCb Y HAY QUE PASARLO
;SEGÚN EL VALOR, SI ES POSITIVO O NEGATIVO (positivo O negativo). Y LUEGO MOSTRARLO AL LCD.
;----------------------------- ------------------------------ -------
;
RESTAR_AMBOS
MOVFW positivoBA
MOVWF ACCbLO
MOVFW positivoAL
MOVWF ACCbHI
MOVFW negativoBA
MOVWF ACCaLO
MOVFW negativoAL
MOVWF ACCaHI
CALL RESTA
BTFSS STATUS,C ;¿ES NEGATIVO?
GOTO PROMEDIO_NEGATIVO
CALL VALOR_POSITIVO ;CARGAMOS EL LUGAR DESDE DÓNDE EMPEZARÁ A MOSTRAR LOS DATOS EL LCD
MOVFW ACCbLO
MOVWF TEMP2
MOVFW ACCbHI
MOVWF TEMP1
GOTO DESCOMPONER
;
PROMEDIO_NEGATIVO
CALL VALOR_NEGATIVO
MOVFW ACCbLO
MOVWF TEMP2
MOVFW ACCbHI
MOVWF TEMP1
;VAMOS A DESCOMPONER
;----------------------------- ------------------------------ ------------------------------ ------------------------------ ------------------------------ --------
;
;BORRAMOS LAS VARIABLES Y PASAMOS EL RESULTADO DE LA OPERACIÓN ANTERIOR A DATO.
;Y LO PASAMOS A TEMP PARA SALVAR EL VALOR SI ES NEGATIVO.
;
DESCOMPONER BCF STATUS,IRP ;DIRECCIONAMIENTO INDIRECTO PÁGINA 0;1
CLRF centena
CLRF decena
CLRF unidad
CLRF decimo
;
MOVFW TEMP2
MOVWF ACCbLO
MOVFW TEMP1
MOVWF ACCbHI
;----------------------------- ------------------------------ -
;DIVIMOS EL PROMEDIO EN:
;1.000, LUEGO EN 100, LUEGO EN 10 Y POR ÚLTIMO EN OBTUVIMOS EL DÉCIMO.
;----------------------------- ------------------------------ -
;
;RESTAMOS 10.000
;
MOVLW H'03'
MOVWF ACCaHI
MOVLW H'E8'
MOVWF ACCaLO
CALL RESTA
BTFSS STATUS,C ;¿ES NEGATIVO?
GOTO CEN_NEG ;SI, RECUPERO EL RESULTADO
INCF centena,F ;NO, INCREMENTO Y COMO NO PUEDE SUPERAR DE 1, CONTINUO.
MOVFW ACCbHI
MOVWF TEMP1
MOVFW ACCbLO
MOVWF TEMP2
GOTO DEC
CEN_NEG MOVFW TEMP1
MOVWF ACCbHI
MOVFW TEMP2
MOVWF ACCbLO
;
;RESTAMOS 100
;
DEC CLRF ACCaHI
MOVLW .100
MOVWF ACCaLO
CALL RESTA
BTFSS STATUS,C ;¿ES NEGATIVO?
GOTO DEC_NEG ;SI, RECUPERO EL RESULTADO
INCF decena,F ;NO, INCREMENTO
MOVFW ACCbHI
MOVWF TEMP1
MOVFW ACCbLO
MOVWF TEMP2
GOTO DEC
DEC_NEG MOVFW TEMP1
MOVWF ACCbHI
MOVFW TEMP2
MOVWF ACCbLO
;
;RESTAMOS 10
;
UNI CLRF ACCaHI
MOVLW .10
MOVWF ACCaLO
CALL RESTA
BTFSS STATUS,C ;¿ES NEGATIVO?
GOTO UNI_NEG ;SI, RECUPERO EL RESULTADO
INCF unidad,F ;NO, INCREMENTO Y COMO NO PUEDE SUPERAR DE 1, CONTINUO.
MOVFW ACCbHI
MOVWF TEMP1
MOVFW ACCbLO
MOVWF TEMP2
GOTO UNI
UNI_NEG MOVFW TEMP1
MOVWF ACCbHI
MOVFW TEMP2
MOVWF ACCbLO
;
;EL RESULTADO EN ACCbLO LO PASO A DÉCIMO
;
MOVFW ACCbLO
MOVWF decimo
;
;MOSTRAMOS LOS DATOS EN EL LCD
;
PAGESELW TABLA_2
MOVFW centena
CALL TABLA_2
CALL LCD_DATO
PAGESELW TABLA_2
MOVFW decena
CALL TABLA_2
CALL LCD_DATO
PAGESELW TABLA_2
MOVFW unidad
CALL TABLA_2
CALL LCD_DATO
MOVLW ','
CALL LCD_DATO
PAGESELW TABLA_2
MOVFW decimo
CALL TABLA_2
CALL LCD_DATO
GOTO DEMORA ;DEMORA DE 1 SEGUNDO. NO ES NECESARIO EJECUTARLO. SE PUEDE ELIMINAR TRANQUILAMENTE.
;
;***************************** ****************************** ****************************** *******
;NOTA: COMO SE PUEDE OBSERVAR, SE HISO UNA RUTINA COMPLETA DE SENSADO DE UN LM35 Y MOSTRARLO AL LCD
; ASÍ, ESTA RUTINA SE PUEDE LLAMAR POR MEDIO DE CALL Y VOLVER CON EL DATO MOSTRADO EN EL LCD.
;***************************** ****************************** ****************************** *******

;
INICIO BCF STATUS,RP0
BCF STATUS,RP1
CLRF PORTA
CLRF PORTB
CLRF PORTC
CLRF PORTD
CLRF PORTC
CALL M_TEMP ;MOSTRAMOS TEMPERATURA EN EL LCD
CALL GRADO ;CREAR UNA RUTINA PARA QUE MUESTRE °C
GOTO PRE_ADQ_TEMP ;EMPEZAMOS A SENSAR LA TEMPERATURA.

;
END





Subo algunos avances de mi pluviómetro a cangilón. Va tomando forma. Luego prometo subir un instructivo de como armar uno. La característica de este pluviómetro, es que está echo con cosas recicladas.



La siguiente imágen, podemos ver como quedará con un enbudo. Este embudo no es el que lleva. Lleva uno más grande. Este está solo a modo ilustrativo.

Solo me falta hacer la parte de control y conseguir el embudo adecuado colocarlo y hacer las primeras pruebas.



0 comentarios:

Publicar un comentario

Mi nombre es Ivana y les doy la bienvenida a este tema... para que juntos lo descubramos...