# Controlar estaque de agua con un PIC



## Meta (Feb 24, 2010)

Hola:

Quiero encontrar algunos esquemas sobre control de niveles de depósitos de agua. He encontrado uno y me parece bueno.







Si encuentran más mejor, ya que estoy con un PIC para hacer el mini proyecto en realidad. Espero obtener muchas ideas con ustedes.


```
S1 S2 = LV LR M
 0   0  =   0    0   0  
 1   0  =   1    0   0 
 1   1  =   0    1   1
```
*Entradas:*
S1 = Sensor 1 Vacio
S2 = Sensor 2 Lleno

*Salidas:*
LV = Led Verde
LR = Led Rojo
M  = Motor

*Funcion:*
El tanque debe estar siempre vacio. Por la lluvia el agua sube. En todo momento el motor M debe estar apagado y el Led verde LV porque el agua sigue por debajo del S1 y no lo toca.

Cuando empieza a llover y el agua sube, con el tiempo toca el sensor S1 y el motor M todavia sigue parado y el Led verde LV se enciende.

Cuando el agua suba del todo significa lleno y es que ha tocado el S2, el LR se enciende y el LV se apaga al mismo tiempo, mientras el M se activa hasta que el agua baje por debajo del S1, que es cuando el M se detiene. Si M se detiene, el LR se apaga.

Se vuelve a repetir el mismo ciclo siempre que el agua suba. El agua simpre se deposita en un desague y el estanque que no se llene. Como el M siempre debe tener agua, se deja un poco para ella. El motor no debe quedarse sin agua ya que puede quemarse.

*Ver ejemplo que hice.*
http://electronicapic.iespana.es/deposito.swf

Se acepta sugerencia para su mejora.






Edito:

He hecho por ahora con el PIC12F508 que es el pequeño que tengo ahora. También 12C509. Si prefieren otro PIC a usar me lo dicen. 

Para aprovechar todos los pines posibles, usaré el tercer Led en Amarillo.

 S1  S2 = LA  LV  LR   M
 0    0   =   1   0   0    0   ; Se activa Led amarillo cuando no ha detectado agua.
 1   0   =   0     1   0   0  ; Led verde cuando sólo detecta el primer sensor S1.
 1  1  =   0    0    1  1 ; Led rojo y motor se activan.

El código que estoy haciendo que aún no funciona es este, a ver s hay alguien que me ayude hacrlo funcionar.


```
;+---------------------------------+
;¦ PROCESADOR A EMPLEAR PIC12F50x  ¦
;+---------------------------------+
SELECCIONAR    EQU 0          ;0=PIC12F508 1=PIC12F509
     IF            SELECCIONAR
    LIST        P=12F509
    INCLUDE        <P12F509.INC>
     ELSE
    LIST        P=12F508
    INCLUDE        <P12F508.INC>
     ENDIF 
;+-----------------------------------+
;¦ FUSIBLES, WASDOG, OSCILADOR ETC.. ¦
;+-----------------------------------+
    __CONFIG   _MCLRE_ON & _CP_OFF & _WDT_OFF & _IntRC_OSC

; ZONA DE CÓDIGOS ********************************************************************

    ORG        0
Inicio
    movwf   OSCCAL          ;CALIBRA EL OSCILADOR INTERNO 
    movlw   b'11000010'         ;CONFIGURA TMR0 PRESCALER = 1:8
    OPTION                          ;OSCILADOR = 4MHZ
    movlw   b'00000011'     ;INICIALIZA TODOS LOS
    tris    GPIO            ;PUERTOS EN ALTO Y 

Principal
    movf    GPIO,W                ; Lee los sensores.
    andlw    b'00000011'            ; Máscara para quedarse con el valor de los sensores.
    addwf    PCL,F                ; Salta a la configuración adecuada.
    goto    Configuracion0
    goto    Configuracion1
    goto    Configuracion2
Configuracion0
    movlw     b'00001000'            
    goto    ActivaSalida
Configuracion1
    movlw     b'00000100'            
    goto    ActivaSalida
Configuracion2
    movlw     b'00000011'        
    goto    ActivaSalida
ActivaSalida
    movwf    GPIO            
    goto     Principal

    END
```


----------



## Beamspot (Feb 25, 2010)

Hay varias opciones alternativas. Una de ellas es hacer un medidor de distancias por ultrasonidos, de manera que se puede saber en todo momento el nivel de llenado del tanque. Y además funciona sin contacto.

Mi primer proyecto comercial fue precisamente algo parecido, puramente analógico con dos sondas. Para el sistema de detección de agua por conductividad es importante usar corriente alterna, ya que si no las sondas se corroen en un plis plas. Eso y unos pocos OpAmps te dan el sensado para cada una de las sondas.

Si sigues decidiéndote por el sistema de contactos, una máquina de estados es perfecta para la aplicación. Para el tema de los ultrasonidos (mi segundo proyecto comercial, por cierto) la cosa se complica, pero tampoco mucho más.


----------



## Meta (Feb 25, 2010)

En mi caso lo hago así por cuestiones económicas. El que dices lo haré más adelante y para otra cosa.

Ahora estoy centrado intentando programar el 12F508. Coko me cuesta manejar los GPIO.

Quiero saber como programo los GPIO, dos de entrada y 4 de salida.

Entradas:
GPIO, 0
GPIO, 1

Salidas:
GPIO, 2
GPIO, 3
GPIO, 4
GPIO, 5

A parte de esta misión, también quiero saber como poner los 4 MHz exacto con el famoso oscilador interno que creo que no me ha saldio.

Muchas gracias.


----------



## Beamspot (Feb 25, 2010)

Exacto, a eso mismo me refería cuando puse lo de los ultrasonidos.

Respecto del sistema por sonda sumergida o de conductividad del agua, no me acuerdo muy bien cómo iba, sólo que se aprovechaba el transformadorcillo de alimentación para sacar la alterna de ahí antes de rectificar. La verdad es que no debería tener mucho misterio, pero miraré de tirarte algo de esquema cuando pueda.

De los pines de GPIO y demás, lo siento pero la experiencia que tuve con PIC se remonta al 2002, y seguro que cualquiera de este foro te puede ayudar más y mejor que yo al respecto.


----------



## Meta (Feb 25, 2010)

Voy a intentarlo con el 16F84A que con el 12F508 no me sale.

Su código es este.

```
...
```
Aún falta por mejorar, dentro de poco pongo la explicación real del problema. Cuando acabe, intentaré pasarlo a 12F508.

Saludo.




Edito:
Ya me funciona tal como quiero. Ahora sólo me falta que me hechen una mano para pasarlo del *16F84A* al *12F508* que no me sale. Tiene que ser con el oscilador interno a 4 MHz. Mientras tanto lo pasaré al *16F88*.

El código actual y definitivo para le 16F84A es este de abajo.

```
;  S2  S1 |  LV  LA  LR  M
; --------|--------------------------------
;  0   0  |  0   0   0   0    (Configuración 0. Estado "Nulo").
;  0   1  |  0   1   0   0    (Configuración 1. Estado "Llenándose").
;  1   0  |  goto            (Configuración 2. Estado "Llenándose").
;  1   1  |  0   0   1   1    (Configuración 3. Estado "Motor").

; ZONA DE DATOS **********************************************************************

    LIST        P=16F84A
    INCLUDE        <P16F84A.INC>
    __CONFIG    _CP_OFF &  _WDT_OFF & _PWRTE_ON & _XT_OSC

    CBLOCK    0x0C
    Flag
    Config_3
    ENDC

; ZONA DE CÓDIGOS ********************************************************************

    ORG     0                    ; El programa comienza en la dirección 0.

Inicio
    bsf        STATUS,RP0            ; Acceso al Banco 1.
    clrf    PORTB                ; Las líneas del Puerto B se configuran como salida.
    movlw    b'00011111'            ; Las 5 líneas del Puerto A se configuran como entrada.
    movwf    PORTA
    bcf        STATUS,RP0            ; Acceso al Banco 0.
    clrw

Principal
    movf    PORTA,W                ; Lee los sensores.
    andlw    b'00000011'            ; Máscara para quedarse con el valor de los sensores.
    addwf    PCL,F                ; Salta a la configuración adecuada.
    goto    Configuracion0        ; 0 0
    goto    Configuracion1        ; 0 1
    goto    Configuracion2        ; 1 0
    goto    Configuracion3        ; 1 1
Configuracion0                    ; Nulo. Led amarillo.
    movlw     b'00001000'
    clrf    Flag
    clrf    Config_3            
    goto    ActivaSalida
Configuracion1                    ; Llenándoce, Led verde.
    movlw     b'00000100'
    btfss    Flag,0
    goto    ActivaSalida
Configuracion2                    ; Seguridad.
    goto    Configuracion3
Configuracion3                    ; Vaciándose. Led rojo, motor activo.
    movlw    .1
    movwf    Flag
    movlw     b'00000011'
    movwf    Config_3
    goto    ActivaSalida
ActivaSalida
    movwf    PORTB                
    goto     Principal

    END
```
Edito 2:

Ya he consegudi el código completo para el *16F88*. Aún sugiero que me ayude a pasarlo al *12F508*. Aunque parezca mentira, no logro manejar bien los GPIO. Se me resiste. Los que quieran pasarlo al 16F628A lo hacen y lo ponen aquí.


```
;  S2  S1 |  LV  LA  LR  M
; --------|--------------------------------
;  0   0  |  0   0   0   0    (Configuración 0. Estado "Nulo").
;  0   1  |  0   1   0   0    (Configuración 1. Estado "Llenándose").
;  1   0  |  goto            (Configuración 2. Estado "Llenándose").
;  1   1  |  0   0   1   1    (Configuración 3. Estado "Motor").

; ZONA DE DATOS **********************************************************************

    LIST        P=16F88
    INCLUDE        <P16F88.INC>
    __CONFIG _CONFIG1, _CP_OFF & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _XT_OSC
    __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF

    CBLOCK    0x20
    Flag
    Config_3
    ENDC

; ZONA DE CÓDIGOS ********************************************************************

    ORG     0                    ; El programa comienza en la dirección 0.

Inicio
    bcf        STATUS,RP1
    bsf        STATUS,RP0          
    movlw    b'00000000'                                     
    movwf    ANSEL         
    clrf    PORTB         
    movlw    b'11111111'    
    movwf    PORTA          
    bcf        STATUS,RP1
    bcf        STATUS,RP0 
    clrw

Principal
    movf    PORTA,W                ; Lee los sensores.
    andlw    b'00000011'            ; Máscara para quedarse con el valor de los sensores.
    addwf    PCL,F                ; Salta a la configuración adecuada.
    goto    Configuracion0        ; 0 0
    goto    Configuracion1        ; 0 1
    goto    Configuracion2        ; 1 0
    goto    Configuracion3        ; 1 1
Configuracion0                    ; Nulo. Led amarillo.
    movlw     b'00001000'
    clrf    Flag
    clrf    Config_3            
    goto    ActivaSalida
Configuracion1                    ; Llenándoce, Led verde.
    movlw     b'00000100'
    btfss    Flag,0
    goto    ActivaSalida
Configuracion2                    ; Seguridad.
    goto    Configuracion3
Configuracion3                    ; Vaciándose. Led rojo, motor activo.
    movlw    .1
    movwf    Flag
    movlw     b'00000011'
    movwf    Config_3
    goto    ActivaSalida
ActivaSalida
    movwf    PORTB                
    goto     Principal

    END
```

Saludo.


----------



## Meta (Feb 26, 2010)

Hola de nuevo. Lo he intentado con el famoso *12F508* y no me sale como debe ser.

Su código hasta el momento es este. Espero que me ayuden hacerlo bien con el 12F508 ya que el 16F8x es me sobra pines.


```
;+---------------------------------+
;¦ PROCESADOR A EMPLEAR PIC12F50x  ¦
;+---------------------------------+
SELECCIONAR    EQU 0          ;0=PIC12F508 1=PIC12F509
     IF            SELECCIONAR
    LIST        P=12F509
    INCLUDE        <P12F509.INC>
     ELSE
    LIST        P=12F508
    INCLUDE        <P12F508.INC>
     ENDIF 
;+-----------------------------------+
;¦ FUSIBLES, WASDOG, OSCILADOR ETC.. ¦
;+-----------------------------------+
    __CONFIG   _MCLRE_ON & _CP_OFF & _WDT_OFF & _IntRC_OSC

    CBLOCK    0x07
    Raro
    Flag
    RAM_LV
    RAM_LA
    RAM_LR
    RAM_M
    ENDC

#DEFINE    S1    GPIO,2                ; Sensor S1.
#DEFINE    S2    GPIO,3                ; Sensor S2.
#DEFINE    LV    GPIO,0                ; Led verde.
#DEFINE    LA    GPIO,1                ; Led Amarillo.
#DEFINE    LR    GPIO,4                ; Led Rojo.
#DEFINE    M    GPIO,5                ; Motor.


; ZONA DE CÓDIGOS ********************************************************************

    ORG        0
Inicio
    movwf   OSCCAL          ;CALIBRA EL OSCILADOR INTERNO 
    movlw   b'11000010'         ;CONFIGURA TMR0 PRESCALER = 1:8
    OPTION                          ;OSCILADOR = 4MHZ
;    movlw   b'00000011'     ;INICIALIZA TODOS LOS
    movlw    b'00001100'
    TRIS    GPIO            ;PUERTOS EN ALTO Y  
    clrf    GPIO       

Principal
    movf    GPIO,W                ; Lee los sensores.
    andlw    b'00001100'            ; Máscara para quedarse con el valor de los sensores.
    addwf    PCL,F                ; Salta a la configuración adecuada.
    goto    Configuracion0        ; 0 0
    goto    Configuracion1        ; 0 1
    goto    Configuracion2        ; 1 0
    goto    Configuracion3        ; 1 1
Configuracion0                    ; Nulo. Led amarillo.
    movlw    b'00000001'
;    bsf        LV
;    bcf        LA
;    bcf        LR
;    bcf        M
    clrf    Flag            
    goto    ActivaSalida
Configuracion1                    ; Llenándoce, Led verde.
;    bcf        LV
;    bsf        LA
;    bcf        LR
;    bcf        M
    movlw    b'00000010'
    btfss    Flag,0
    goto    ActivaSalida
Configuracion2                    ; Seguridad.
;    goto    Configuracion3
Configuracion3                    ; Vaciándose. Led rojo, motor activo.
    movlw    .1
    movwf    Flag
    movlw    b'00110000'
;    bcf        LV
;    bcf        LA
;    bsf        LR
;    bsf        M
    goto    ActivaSalida
ActivaSalida
    movwf    GPIO                
    goto     Principal


    END
```


----------



## jjfonsecaz (Feb 26, 2010)

Compañero META.
creo que el error esta en donde das el salto a las configuraciones. Estas deberian de tener primero 2 corrimientos a la derecha para que el salto sea de 0,1,2 o 3. y como lo tienes el salto seria de 0,4,8 o 12 localidades.

Principal
    movf    GPIO,W                ; Lee los sensores.
    andlw    b'00001100'            ; Máscara para quedarse con el valor de los sensores.
    movwf TEMP                       ; CArga a un registro temporal para hacer el corrimiento
    bcf STATUS,C                    ;limpiamos el carry
    rrf TEMP,F                     ;primer corrimiento a la derecha
    rrf TEMP,W                    ;segundo corrimiento a la derecha y se almacena en W
    addwf    PCL,F                ; Salta a la configuración adecuada.
    goto    Configuracion0        ; 0 0
    goto    Configuracion1        ; 0 1
    goto    Configuracion2        ; 1 0
    goto    Configuracion3        ; 1 1


----------



## Meta (Feb 26, 2010)

Gracias. Funciona a medias.

Cuando S1 y S2 están activados, debería ir a la configuración 3 y se va al 1. ¿Por qué?


```
;+---------------------------------+
;¦ PROCESADOR A EMPLEAR PIC12F50x  ¦
;+---------------------------------+
SELECCIONAR    EQU 0          ;0=PIC12F508 1=PIC12F509
     IF            SELECCIONAR
    LIST        P=12F509
    INCLUDE        <P12F509.INC>
     ELSE
    LIST        P=12F508
    INCLUDE        <P12F508.INC>
     ENDIF 
;+-----------------------------------+
;¦ FUSIBLES, WASDOG, OSCILADOR ETC.. ¦
;+-----------------------------------+
    __CONFIG   _MCLRE_ON & _CP_OFF & _WDT_OFF & _IntRC_OSC

    CBLOCK    0x08
    Flag
    TEMP
    ENDC

#DEFINE    S1    GPIO,2                ; Sensor S1.
#DEFINE    S2    GPIO,3                ; Sensor S2.
#DEFINE    LV    GPIO,0                ; Led verde.
#DEFINE    LA    GPIO,1                ; Led Amarillo.
#DEFINE    LR    GPIO,4                ; Led Rojo.
#DEFINE    M    GPIO,5                ; Motor.

; ZONA DE CÓDIGOS ********************************************************************

    ORG        0

Inicio
    movwf   OSCCAL          ;CALIBRA EL OSCILADOR INTERNO 
    movlw   b'11000010'     ;CONFIGURA TMR0 PRESCALER = 1:8
    OPTION                     ;OSCILADOR = 4MHZ
;    movlw   b'00000011'     ;INICIALIZA TODOS LOS
    movlw    b'00001100'
    TRIS    GPIO            ;PUERTOS EN ALTO
    clrw

Principal
    movf     GPIO,W                 ; Lee los sensores.
    andlw     b'00001100'         ; Máscara para quedarse con el valor de los sensores.
    movwf     TEMP                 ; CArga a un registro temporal para hacer el corrimiento
    bcf     STATUS,C             ;limpiamos el carry
    rrf     TEMP,F                 ;primer corrimiento a la derecha
    rrf     TEMP,W                 ;segundo corrimiento a la derecha y se almacena en W
    addwf     PCL,F                 ; Salta a la configuración adecuada.                    
    goto    Configuracion0
    goto    Configuracion1
    goto    Configuracion2    
Configuracion0
    movlw     b'00000001'    
    clrf    Flag    
    goto    ActivaSalida
Configuracion1
    movlw     b'00000010'            
    goto    ActivaSalida
Configuracion2        
    goto    Configuracion3
Configuracion3
    movlw    .1
    movwf    Flag
    movlw     b'00110000'            
    goto    ActivaSalida
ActivaSalida
    movwf    GPIO                
    goto     Principal

    END
```
A lo mejor no funciona porque está en 
*
andlw     b'00001100'*

en vez de

*andlw     b'00000011'

*Quizás sea el error por este motivo, más no lo explico.No lo pongo como el ejemplo del _16F88_ ya que el GP3 es de sólo entrada como puedes ver en la página 4 del 12F508.

¿Alguna solución?

Por ahora hace lo que le de la gana.


----------



## jjfonsecaz (Feb 26, 2010)

que tal compañero

si el ejemplo es como lo tienes creo que tienes en tu ultimo comentario, creo que te falta un goto configuracion3. Ya probe el codigo con la inclusion de este y los saltos los realiza correctamente en funcion de las entradas.

En cuanto a la razon de los saltos erroneos si es por el uso del GPIO3 y GPIO2 por eso te recomende hacer los corrimientos a la derecha para que estos queden alineados.

Un saludo.


----------



## Meta (Feb 26, 2010)

Funciona mejor pero no del todo, me explico.


```
;+---------------------------------+
;¦ PROCESADOR A EMPLEAR PIC12F50x  ¦
;+---------------------------------+
SELECCIONAR    EQU 0          ;0=PIC12F508 1=PIC12F509
     IF            SELECCIONAR
    LIST        P=12F509
    INCLUDE        <P12F509.INC>
     ELSE
    LIST        P=12F508
    INCLUDE        <P12F508.INC>
     ENDIF 
;+-----------------------------------+
;¦ FUSIBLES, WASDOG, OSCILADOR ETC.. ¦
;+-----------------------------------+
    __CONFIG   _MCLRE_ON & _CP_OFF & _WDT_OFF & _IntRC_OSC

    CBLOCK    0x08
    Flag
    TEMP
    ENDC

#DEFINE    S1    GPIO,2                ; Sensor S1.
#DEFINE    S2    GPIO,3                ; Sensor S2.
#DEFINE    LV    GPIO,0                ; Led verde.
#DEFINE    LA    GPIO,1                ; Led Amarillo.
#DEFINE    LR    GPIO,4                ; Led Rojo.
#DEFINE    M    GPIO,5                ; Motor.

; ZONA DE CÓDIGOS ********************************************************************

    ORG        0

Inicio
    movwf   OSCCAL          ;CALIBRA EL OSCILADOR INTERNO 
    movlw   b'11000010'     ;CONFIGURA TMR0 PRESCALER = 1:8
    OPTION                     ;OSCILADOR = 4MHZ
;    movlw   b'00000011'     ;INICIALIZA TODOS LOS
    movlw    b'00001100'
    TRIS    GPIO            ;PUERTOS EN ALTO
    clrw

Principal    
    movf     GPIO,W                 ; Lee los sensores.
    andlw     b'00001100'         ; Máscara para quedarse con el valor de los sensores.
    movwf     TEMP                 ; CArga a un registro temporal para hacer el corrimiento
    bcf     STATUS,C             ;limpiamos el carry
    rrf     TEMP,F                 ;primer corrimiento a la derecha
    rrf     TEMP,W                 ;segundo corrimiento a la derecha y se almacena en W
    addwf     PCL,F                 ; Salta a la configuración adecuada.                    
    goto    Configuracion0
    goto    Configuracion1
    goto    Configuracion2
    goto    Configuracion3
Configuracion0
    movlw     b'00000001'    
    clrf    Flag    
    goto    ActivaSalida
Configuracion1
    movlw     b'00000010'            
    goto    ActivaSalida
Configuracion2        
    goto    Configuracion3
Configuracion3
    movlw    .1
    movwf    Flag
    movlw     b'00110000'            
    goto    ActivaSalida
ActivaSalida
    movwf    GPIO                
    goto     Principal

    END
```
*1-* Cuando no detecta el *S1* y *S2* porque no están mojados, el *LV* (Led Verde) está encendido.

*2-* Ahora toca el *S1*, se apaga el *LV* y se enciende el *LA* (Led amarillo) indicando que el agua está subiendo.

*3-* Llegará el momento de que el agua toque el sensor *S2*, que significa que ha llegado el tope. Ahí es cuando se activa el *LR* (Led rojo) y el *M* (Motor) para poder sacar el agua al desagüe.

_Hasta aquí todo bien. Lo que no consigo con el *12F508* es lo siguiente, pero si funciona con el ejemplo que puse con el 16F84A y 16F88._

*4-* El *M* no parará hasta que llegue el sensor *S1* que es cuando ya está vacío.

_Pues esto no ocurre con el *12F508*. Por eso puse el Flag. Por si baja el agua y deje de tocar el *S2*, el *M* no se detenga hasta llegar al *S1* que no ocurre._

*5-* El *M* se para del todo cuando no toque ni el *S1*.

_Desde que deje de tocar el *S2* cuando el agua está bajando, el *M* se detiene y no debe detenerse hasta que llegue al *S1*. Lo que ocurre en ese momento que el *M* se detiene justo desde que deje de tocar el *S2* y el agua permanece cerca del *S2*._

Espero que se entienda algo de lo explicado.




EDITO:

He logrado el objetivo y me funciona muy bien gracias a ti. Sólo tengo una duda. No se si realmente tengo el oscilador interno a 4 MHz. ¿Cómo aseguro que me funciona a 4 MHz? El código del oscilador lo he hecho fijándome en otros ejemplos y no se si realmente está bien configurado.


```
;+---------------------------------+
;¦ PROCESADOR A EMPLEAR PIC12F50x  ¦
;+---------------------------------+
SELECCIONAR    EQU 0          ;0=PIC12F508 1=PIC12F509
     IF            SELECCIONAR
    LIST        P=12F509
    INCLUDE        <P12F509.INC>
     ELSE
    LIST        P=12F508
    INCLUDE        <P12F508.INC>
     ENDIF 
;+-----------------------------------+
;¦ FUSIBLES, WASDOG, OSCILADOR ETC.. ¦
;+-----------------------------------+
    __CONFIG   _MCLRE_ON & _CP_OFF & _WDT_OFF & _IntRC_OSC

    CBLOCK    0x08
    Flag
    TEMP
    ENDC

#DEFINE    S1    GPIO,2                ; Sensor S1.
#DEFINE    S2    GPIO,3                ; Sensor S2.
#DEFINE    LV    GPIO,0                ; Led verde.
#DEFINE    LA    GPIO,1                ; Led Amarillo.
#DEFINE    LR    GPIO,4                ; Led Rojo.
#DEFINE    M    GPIO,5                ; Motor.

; ZONA DE CÓDIGOS ********************************************************************

    ORG        0

Inicio
    movwf   OSCCAL          ;CALIBRA EL OSCILADOR INTERNO 
    movlw   b'11000010'     ;CONFIGURA TMR0 PRESCALER = 1:8
    OPTION                     ;OSCILADOR = 4MHZ
    movlw    b'00001100'
    TRIS    GPIO            ;PUERTOS EN ALTO
    clrw

Principal    
    movf     GPIO,W                 ; Lee los sensores.
    andlw     b'00001100'         ; Máscara para quedarse con el valor de los sensores.
    movwf     TEMP                 ; CArga a un registro temporal para hacer el corrimiento
    bcf     STATUS,C             ;limpiamos el carry
    rrf     TEMP,F                 ;primer corrimiento a la derecha
    rrf     TEMP,W                 ;segundo corrimiento a la derecha y se almacena en W
    addwf     PCL,F                 ; Salta a la configuración adecuada.                    
    goto    Configuracion0
    goto    Configuracion1
    goto    Configuracion2
    goto    Configuracion3
Configuracion0
    movlw     b'00000001'    
    clrf    Flag    
    goto    ActivaSalida
Configuracion1
    movlw     b'00000010'    
    btfss    Flag,0        
    goto    ActivaSalida
Configuracion2        
    goto    Configuracion3
Configuracion3
    movlw    .1
    movwf    Flag
    movlw     b'00110000'            
    goto    ActivaSalida
ActivaSalida
    movwf    GPIO                
    goto     Principal

    END
```

Saludo.


----------



## Meta (Feb 27, 2010)

Hola de nuevo.

Este tipo de cosas es lo que quiero hacer algún día, ya con el PIC de 18 pines como mínimo.







Saludo.


----------



## jjfonsecaz (Feb 27, 2010)

hola compañero

pues revisando el manual de este pic, encontre en la pagina 42 que debes de deshabilitar el MCLRE o de otra manera el mismo actuara como master clear y no como una entrada digital.

En cuanto a la frecuencia de oscilacion; pues el mismo manual dice que tiene el dato de calibracion de fabrica por default en la ultima localidad de memoria de programa por ello la instruccion movwf OSCCAL ya que esta guarda el valor en el registro de calibracion.

Pero aun asi no creo que este exactamente a 4MHZ, si quisieras exactitud pues tendrias que usar un osciloscopio y una rutina toggle de un pin, para ir buscando el valor exacto que debe contener OSCCAL.
Solo que creo que es una perdida de tiempo ya que no creo que sea tan critica la variacion como para que no funcione cualquier programa que quieras implementar.

Saludos.


----------



## Meta (Feb 27, 2010)

Hola:

Pues en el *MPLAB v8.46* me funciona muy bien.



Lo que no me funciona es en el Proteus. Será por lo que me dijiste. Te dejo el ejemplo para que me puedas ayudar.



Descargar Simulador ejemplo.

Casi lo monto con el Protoboard, pero primero hay que hacerlo funcionar bien en el Proteus. Después lo pruebo en la placa de entrenador. Finalmente lo pasaré en una PCB yharé un buen trabajo en el Word  todo lo dicho como he hecho con otro y puedes ver un ejemplo pinchando aquí.

    __CONFIG   *_MCLRE_OFF* & _CP_OFF & _WDT_OFF & _IntRC_OSC

Saludo.


----------



## tecnogirl (Mar 1, 2010)

Beamspot escribio: "Para el sistema de detecci¢n de agua por conductividad es
importante usar corriente alterna, ya que si no las sondas se corroen".

De acuerdo, pero si las sondas las hago de acero inoxidable o de bronce tambien se corroen ?. Si no, me evito contruir la etapa de AC para las sondas, verdad ?.

Saludos


----------



## Vegetal Digital (Mar 1, 2010)

Mira lo que yo hago para que no se corroa es colocar un rele que active/desactive la alimentacion del sensor, entonces funciona así: le doy tensión al sensor, el pic se fija el nivel de agua de cada punto de contacto, quito la tension. esto lo hace en milisegundos y cuido los contactos que en mic aso son clavos, de otro modo, hay que cambiarlos en menos de una semana.
Saludos


----------



## tecnogirl (Mar 1, 2010)

Vegetal Digital: Gracias. Y si pruebas puntas de acero inoxidable (su nombre lo dice, inoxidable) o bronce ? no te evitas el procedimiento que explicaste ?. Saludos.


----------



## Vegetal Digital (Mar 1, 2010)

No lo probe porque no consegui y además me resulta mas económico usar clavos que pueden reemplazarse por cualquier material conductor.


----------



## Beamspot (Mar 1, 2010)

Lo hice con acero inoxidabe y acababa oxidándose. Aún así, no hace falta ni relé ni nada similar: una salida del pic que de una onda cuadrada, pasada a través de un buffer por aquello de la corriente, un condensador en serie, y listo, ya tenemos alterna.

Para medición de niveles en escala, más allá de tres o cuatro puntos, lo habitual suele ser por ultrasonidos, no por conductividad. Mucho más seguro, barato, simple y sin contacto.

Ah, por cierto, si hay que alimentar el circuito y lo hacéis a través de un pequeño transformador de PCB o similar, no hace falta etapa de alterna, el mismo trafo ya lo genera todo.


----------



## Meta (Mar 1, 2010)

Gracias por las sugerencias.

Por lo que he estado leyendo, si usas tanque con ácidos de no se que, es mejor usar tornillos como punta que sea acero inoxidabe y si es bañado de oro mejor.  Si usas cables que también funciona, que sea estañeado y dura mucho más.

Estoy empezando a mirar el tema del ultrasonido por 15 €uros como el SFR05 4.30 metros (el sustituto del SFR04 de 3 metros). Lo haré cuando acabe el primero de cables.






Tengo un bidón de 1.000 litros de agua, en realidad dos como esos. Uno lo haré fijo con cables y el otro con ultrasonido que por lo que veo en el código en asm con el 16F84A, parece fácil (lo pasaré al 16F88).


```
; Programa para un medidor de distancias hasta un objeto utilizando sensor por ultrasonido
; SRF04.
;
; Para el control del sensor en primer lugar se genera un  pulso de 10 µs a nivel alto por
; la línea RA3 que se conecta a la entrada de disparo del sensor. Seguidamente se espera a
; que en el sensor se ponga un nivel alto en la salida ECO que se conecta a la línea RA4 y 
; se utilizan las interrupciones por desbordamiento del Timer 0 para medir el tiempo que
; está en alto el pulso. Seguidamente se visualiza en el módulo LCD el valor de la distancia
; hasta el objeto expresada en centímetros.
;
; Por cada centímetro de distancia al objeto el SRF04 aumenta 60 µs la anchura del pulso.
; En este programa la distancia mínima que se puede medir es 3 cm y la máxima 250 cm.
;
; ZONA DE DATOS **********************************************************************

    LIST        P=16F84A
    INCLUDE        <P16F84A.INC>
    __CONFIG    _CP_OFF &  _WDT_OFF & _PWRTE_ON & _XT_OSC

    CBLOCK  0x0C
    Distancia                        ; Se expresará en centímetros.
    ENDC

#DEFINE  Disparo    PORTA,3            ; Disparo para iniciar la medida.
#DEFINE  Eco        PORTA,4            ; Pulso cuya anchura hay que medir.

MIN_DISTANCIA        EQU    .3
MAX_DISTANCIA        EQU    .250
TMR0_Carga60micros    EQU d'256'-d'27'; Valor obtenido experimentalmente con la
                                    ; ventana Stopwatch para una interrupción del
; Timer 0 cada 60 µs.  Si no mide correctamente por las tolerancias de los componentes habrá
; que hacer un ajuste fino de este valor, comprobándolo sobre las condiciones reales.
;
; ZONA DE CÓDIGOS ********************************************************************

    ORG     0
    goto    Inicio
    ORG    4
    goto    ServicioInterrupcion

Mensajes
    addwf    PCL,F
MensajeDistancia
    DT "   Distancia: ", 0x00
MensajeCentimetro
    DT " cm", 0x00
MensajeDistanciaMenor
    DT "Dist. MENOR de:", 0x00
MensajeDistanciaMayor
    DT "Dist. MAYOR de:", 0x00
Inicio
    call    LCD_Inicializa
    bsf        STATUS,RP0
    bcf        Disparo
    bsf        Eco
    movlw    b'00000000'                ; Prescaler de 2 para el TMR0.
    movwf    OPTION_REG
    bcf        STATUS,RP0
    bcf        Disparo                    ; Inicializa línea de disparo en bajo.
Principal
    clrf    Distancia                ; Inicializa el registro.
    bsf        Disparo                    ; Comienza el pulso de disparo.
    call    Retardo_20micros        ; Duración del pulso.
    bcf        Disparo                    ; Final del pulso de disparo.
Espera_Eco_1
    btfss    Eco                        ; Si ECO=0, espera el flanco de subida de la señal
    goto    Espera_Eco_1            ; de salida del sensor.
    movlw    TMR0_Carga60micros        ; Ya se ha producido el flanco de subida.
    movwf    TMR0                    ; Carga el Timer 0.
    movlw    b'10100000'                ; Autoriza interrupción del TMR0 (T0IE).
    movwf    INTCON
Espera_Eco_0
    btfsc    Eco                        ; Espera flanco de bajada de la señal de la salida
    goto    Espera_Eco_0            ; del SRF04.
    clrf    INTCON                    ; Se ha producido el flanco de bajada. Prohíbe interrup.
    call    Visualiza                ; Visualiza la distancia.
    call    Retardo_2s                ; Espera un tiempo hasta la próxima medida.
Fin    goto    Principal
    
; Subrutina "ServicioInterrupcion" ------------------------------------------------------
;
; Se ejecuta debido a la petición de interrupción del Timer 0 cada 60 µs que es el incremento
; de la anchura de pulso por centímetro de distancia medido. La variable "Distancia" contiene el
; valor de la distancia expresada en centímetros.
;
ServicioInterrupcion
      movlw    TMR0_Carga60micros        ; Carga el Timer 0.
    movwf    TMR0
    movlw    .1                        ; Se utiliza instrucción "addwf", en lugar de "incf"
    addwf    Distancia,F                ; para posicionar flag de Carry.
    movlw    MAX_DISTANCIA            ; En caso de desbordamiento carga su máximo valor.
    btfsc    STATUS,C
    movwf    Distancia
    bcf        INTCON,T0IF
    retfie

; Subrutina "Visualiza" -----------------------------------------------------------------
;
; Visualiza la distancia expresada en centímetros. Se hace de manera que cuando haya que
; visualizar un número mayor de 99 las decenas siempre se visualicen aunque sean cero.
; Y cuando sea menor de 99 las decenas no se visualicen si es cero.
;
; Si la distancia es menor de 3 cm o mayor de 250 cm aparece un mensaje de error.
;
Visualiza
    call    LCD_Borra                ; Borra la pantalla anterior.
    movlw    MIN_DISTANCIA            ; Va a comprobar si es menor del mínimo admisible.
    subwf    Distancia,W                ; (W) = (Distancia) - MIN_DISTANCIA
    btfss    STATUS,C                ; ¿C=1?, ¿(W) positivo?, ¿(Distancia) >= MIN_DISTANCIA?
    goto    DistanciaMenor            ; No ha resultado menor, y salta al mensaje de error.
    movf    Distancia,W                ; Va a comprobar si es mayor del máximo admisible.
    sublw    MAX_DISTANCIA            ; (W)=MAX_DISTANCIA-(Distancia)
    btfsc    STATUS,C                ; ¿C=0?, ¿(W) negativo?, ¿MAX_DISTANCIA < (Distancia)?
    goto    DistanciaFiable            ; No, la medida de la distancia entra dentro del rango.
;
DistanciaMayor
    movlw    MAX_DISTANCIA            ; La distancia es mayor que el máximo.
    movwf    Distancia
    movlw    MensajeDistanciaMayor
    goto    VisualizaDistancia
;
DistanciaMenor
    movlw    MIN_DISTANCIA            ; La distancia es menor del mínimo fiable.
    movwf    Distancia
    movlw    MensajeDistanciaMenor
    goto    VisualizaDistancia
DistanciaFiable
    movlw    MensajeDistancia
VisualizaDistancia
    call    LCD_Mensaje
    movlw    .5                        ; Centra la medida de la distancia en la segunda línea 
    call    LCD_PosicionLinea2        ; de la pantalla.
    movf    Distancia,W
    call    BIN_a_BCD                ; Lo pasa a BCD.
    movf    BCD_Centenas,W            ; Primero las centenas.
    btfss    STATUS,Z                ; Si son cero no visualiza las centenas.
    goto    VisualizaCentenas
    movf    Distancia,W                ; Vuelve a recuperar este valor.
    call    BIN_a_BCD                ; Lo pasa a BCD.
    call    LCD_Byte                ; Visualiza las decenas y unidades.
    goto    Visualiza_cm
VisualizaCentenas
    call    LCD_Nibble                ; Visualiza las centenas.
    movf    Distancia,W                ; Vuelve a recuperar este valor.
    call    BIN_a_BCD                ; Lo pasa a BCD.
    call    LCD_ByteCompleto        ; Visualiza las decenas (aunque sea cero) y
Visualiza_cm                        ; unidades.
    movlw    MensajeCentimetro
    call    LCD_Mensaje
    return

    INCLUDE  <RETARDOS.INC>
    INCLUDE  <LCD_4BIT.INC>
    INCLUDE  <LCD_MENS.INC>
    INCLUDE  <BIN_BCD.INC>
    END
```
El del *12F508* lo tengo casi montado en el Protoboar, en el simulador Proteus v7.6 funciona muy bien. (Ya está el v7.7). En este caso lo haré por cable. Estaba pensando en hacerlo a pilas de 9V. Lo que no se hacer es como hacer que me avise con un Led la falta de batería. (Amp Op).

Sobre el tema del óxido hay sensores de 10 a 12 € cada uno como estos que no comunica el agua con el metal, si el plástico.












http://www.electan.com/catalog/sens....html?osCsid=5273fdc8703c58380331bc69d6d08090






Más información por si acaso ha alguien le interesa.





Dibujando con Flash el dibujo del bidón y SFR05.


----------



## pepechip (Mar 1, 2010)

Hola Angel
En tus directivas, el oscilador no lo tienes bien configurado.
La programacion supongo que sera similar al 12f629, asi que tejo una rutina de un oscilador http://www.microcontroladorespic.co...oladores-pic/temporizador-ciclico/ciclico.asm
Acuerdate a la hora de grabarlo de NO sustituir el valor inicial del Osccal.


Para evitar la corrosion en la sonda es muy facil, tan solo tienes que tener desactivada la sonda de abajo, y conectarla solamente cuando comiences a sacar agua. Si el proceso de sacar agua es muy lento puedes conectarla ciclicamente, por ejemplo 1seg desconectada y 3us para ver si hay agua.
Para ello tendras que estar continuamente configurando este pin como entrada y salida.


----------



## Meta (Mar 1, 2010)

Muchas gracias.

Lo he hecho así, espero que esté bien el oscilador interno. _(Hacías tiempo que no pasabas por aquí como antes, bienvenido)_.

Como dije antes haré el proyecto 1 a cables y puede que con pilas, que al pulsar un botón se active el PIC12F508 y poder ver el nivel que hay en el agua y sin consumir energía constantemente.


```
;+---------------------------------+
;¦ PROCESADOR A EMPLEAR PIC12F50x  ¦
;+---------------------------------+
SELECCIONAR    EQU 0          ;0=PIC12F508 1=PIC12F509
     IF            SELECCIONAR
    LIST        P=12F509
    INCLUDE        <P12F509.INC>
     ELSE
    LIST        P=12F508
    INCLUDE        <P12F508.INC>
     ENDIF 
;+-----------------------------------+
;¦ FUSIBLES, WASDOG, OSCILADOR ETC.. ¦
;+-----------------------------------+
    __CONFIG   _MCLRE_OFF & _CP_OFF & _WDT_OFF & _IntRC_OSC

    CBLOCK    0x08
    Flag
    TEMP
    ENDC

#DEFINE    S1    GPIO,2                ; Sensor S1.
#DEFINE    S2    GPIO,3                ; Sensor S2.
#DEFINE    LV    GPIO,0                ; Led verde.
#DEFINE    LA    GPIO,1                ; Led Amarillo.
#DEFINE    LR    GPIO,4                ; Led Rojo.
#DEFINE    M    GPIO,5                ; Motor.

; ZONA DE CÓDIGOS ********************************************************************

    ORG        0x1FF            ; Calibración del 
    movwf    OSCCAL            ; oscilador interno.

    ORG        0

Inicio
;    movwf   OSCCAL          ;CALIBRA EL OSCILADOR INTERNO 
;    movlw   b'11000010'     ;CONFIGURA TMR0 PRESCALER = 1:8
;    OPTION                     ;OSCILADOR = 4MHZ



    movlw    b'00001100'
    TRIS    GPIO            ;PUERTOS EN ALTO
    clrw

Principal    
    movf     GPIO,W                 ; Lee los sensores.
    andlw     b'00001100'         ; Máscara para quedarse con el valor de los sensores.
    movwf     TEMP                 ; CArga a un registro temporal para hacer el corrimiento
    bcf     STATUS,C             ;limpiamos el carry
    rrf     TEMP,F                 ;primer corrimiento a la derecha
    rrf     TEMP,W                 ;segundo corrimiento a la derecha y se almacena en W
    addwf     PCL,F                 ; Salta a la configuración adecuada.                    
    goto    Configuracion0
    goto    Configuracion1
    goto    Configuracion2
    goto    Configuracion3
Configuracion0
    movlw     b'00000001'    
    clrf    Flag    
    goto    ActivaSalida
Configuracion1
    movlw     b'00000010'    
    btfss    Flag,0        
    goto    ActivaSalida
Configuracion2        
    goto    Configuracion3
Configuracion3
    movlw    .1
    movwf    Flag
    movlw     b'00110000'            
    goto    ActivaSalida
ActivaSalida
    movwf    GPIO                
    goto     Principal

    END
```
Por otro lado, en el segundo bidón que tengo también de 1.000 L. Haré el proyecto 2 con el SFR05 compatible con el SFR04. Viendo el libro, parece sencillo de hacer.








```
;********************************** Sensor_ Ultrasonido_01.asm **************************
;
;    ===================================================================
;      Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"
;      E. Palacios, F. Remiro y L. López.          www.pic16f84a.org
;       Editorial Ra-Ma.  www.ra-ma.es
;    ===================================================================
;
; Programa para un medidor de distancias hasta un objeto utilizando sensor por ultrasonido
; SRF04.
;
; Para el control del sensor en primer lugar se genera un  pulso de 10 µs a nivel alto por
; la línea RA3 que se conecta a la entrada de disparo del sensor. Seguidamente se espera a
; que en el sensor se ponga un nivel alto en la salida ECO que se conecta a la línea RA4 y 
; se utilizan las interrupciones por desbordamiento del Timer 0 para medir el tiempo que
; está en alto el pulso. Seguidamente se visualiza en el módulo LCD el valor de la distancia
; hasta el objeto expresada en centímetros.
;
; Por cada centímetro de distancia al objeto el SRF04 aumenta 60 µs la anchura del pulso.
; En este programa la distancia mínima que se puede medir es 3 cm y la máxima 250 cm.
;
; ZONA DE DATOS **********************************************************************

    LIST        P=16F84A
    INCLUDE        <P16F84A.INC>
    __CONFIG    _CP_OFF &  _WDT_OFF & _PWRTE_ON & _XT_OSC

    CBLOCK  0x0C
    Distancia                        ; Se expresará en centímetros.
    ENDC

#DEFINE  Disparo    PORTA,3            ; Disparo para iniciar la medida.
#DEFINE  Eco        PORTA,4            ; Pulso cuya anchura hay que medir.

MIN_DISTANCIA        EQU    .3
MAX_DISTANCIA        EQU    .250
TMR0_Carga60micros    EQU d'256'-d'27'; Valor obtenido experimentalmente con la
                                    ; ventana Stopwatch para una interrupción del
; Timer 0 cada 60 µs.  Si no mide correctamente por las tolerancias de los componentes habrá
; que hacer un ajuste fino de este valor, comprobándolo sobre las condiciones reales.
;
; ZONA DE CÓDIGOS ********************************************************************

    ORG     0
    goto    Inicio
    ORG    4
    goto    ServicioInterrupcion

Mensajes
    addwf    PCL,F
MensajeDistancia
    DT "   Distancia: ", 0x00
MensajeCentimetro
    DT " cm", 0x00
MensajeDistanciaMenor
    DT "Dist. MENOR de:", 0x00
MensajeDistanciaMayor
    DT "Dist. MAYOR de:", 0x00
Inicio
    call    LCD_Inicializa
    bsf        STATUS,RP0
    bcf        Disparo
    bsf        Eco
    movlw    b'00000000'                ; Prescaler de 2 para el TMR0.
    movwf    OPTION_REG
    bcf        STATUS,RP0
    bcf        Disparo                    ; Inicializa línea de disparo en bajo.
Principal
    clrf    Distancia                ; Inicializa el registro.
    bsf        Disparo                    ; Comienza el pulso de disparo.
    call    Retardo_20micros        ; Duración del pulso.
    bcf        Disparo                    ; Final del pulso de disparo.
Espera_Eco_1
    btfss    Eco                        ; Si ECO=0, espera el flanco de subida de la señal
    goto    Espera_Eco_1            ; de salida del sensor.
    movlw    TMR0_Carga60micros        ; Ya se ha producido el flanco de subida.
    movwf    TMR0                    ; Carga el Timer 0.
    movlw    b'10100000'                ; Autoriza interrupción del TMR0 (T0IE).
    movwf    INTCON
Espera_Eco_0
    btfsc    Eco                        ; Espera flanco de bajada de la señal de la salida
    goto    Espera_Eco_0            ; del SRF04.
    clrf    INTCON                    ; Se ha producido el flanco de bajada. Prohíbe interrup.
    call    Visualiza                ; Visualiza la distancia.
    call    Retardo_2s                ; Espera un tiempo hasta la próxima medida.
Fin    goto    Principal
    
; Subrutina "ServicioInterrupcion" ------------------------------------------------------
;
; Se ejecuta debido a la petición de interrupción del Timer 0 cada 60 µs que es el incremento
; de la anchura de pulso por centímetro de distancia medido. La variable "Distancia" contiene el
; valor de la distancia expresada en centímetros.
;
ServicioInterrupcion
      movlw    TMR0_Carga60micros        ; Carga el Timer 0.
    movwf    TMR0
    movlw    .1                        ; Se utiliza instrucción "addwf", en lugar de "incf"
    addwf    Distancia,F                ; para posicionar flag de Carry.
    movlw    MAX_DISTANCIA            ; En caso de desbordamiento carga su máximo valor.
    btfsc    STATUS,C
    movwf    Distancia
    bcf        INTCON,T0IF
    retfie

; Subrutina "Visualiza" -----------------------------------------------------------------
;
; Visualiza la distancia expresada en centímetros. Se hace de manera que cuando haya que
; visualizar un número mayor de 99 las decenas siempre se visualicen aunque sean cero.
; Y cuando sea menor de 99 las decenas no se visualicen si es cero.
;
; Si la distancia es menor de 3 cm o mayor de 250 cm aparece un mensaje de error.
;
Visualiza
    call    LCD_Borra                ; Borra la pantalla anterior.
    movlw    MIN_DISTANCIA            ; Va a comprobar si es menor del mínimo admisible.
    subwf    Distancia,W                ; (W) = (Distancia) - MIN_DISTANCIA
    btfss    STATUS,C                ; ¿C=1?, ¿(W) positivo?, ¿(Distancia) >= MIN_DISTANCIA?
    goto    DistanciaMenor            ; No ha resultado menor, y salta al mensaje de error.
    movf    Distancia,W                ; Va a comprobar si es mayor del máximo admisible.
    sublw    MAX_DISTANCIA            ; (W)=MAX_DISTANCIA-(Distancia)
    btfsc    STATUS,C                ; ¿C=0?, ¿(W) negativo?, ¿MAX_DISTANCIA < (Distancia)?
    goto    DistanciaFiable            ; No, la medida de la distancia entra dentro del rango.
;
DistanciaMayor
    movlw    MAX_DISTANCIA            ; La distancia es mayor que el máximo.
    movwf    Distancia
    movlw    MensajeDistanciaMayor
    goto    VisualizaDistancia
;
DistanciaMenor
    movlw    MIN_DISTANCIA            ; La distancia es menor del mínimo fiable.
    movwf    Distancia
    movlw    MensajeDistanciaMenor
    goto    VisualizaDistancia
DistanciaFiable
    movlw    MensajeDistancia
VisualizaDistancia
    call    LCD_Mensaje
    movlw    .5                        ; Centra la medida de la distancia en la segunda línea 
    call    LCD_PosicionLinea2        ; de la pantalla.
    movf    Distancia,W
    call    BIN_a_BCD                ; Lo pasa a BCD.
    movf    BCD_Centenas,W            ; Primero las centenas.
    btfss    STATUS,Z                ; Si son cero no visualiza las centenas.
    goto    VisualizaCentenas
    movf    Distancia,W                ; Vuelve a recuperar este valor.
    call    BIN_a_BCD                ; Lo pasa a BCD.
    call    LCD_Byte                ; Visualiza las decenas y unidades.
    goto    Visualiza_cm
VisualizaCentenas
    call    LCD_Nibble                ; Visualiza las centenas.
    movf    Distancia,W                ; Vuelve a recuperar este valor.
    call    BIN_a_BCD                ; Lo pasa a BCD.
    call    LCD_ByteCompleto        ; Visualiza las decenas (aunque sea cero) y
Visualiza_cm                        ; unidades.
    movlw    MensajeCentimetro
    call    LCD_Mensaje
    return

    INCLUDE  <RETARDOS.INC>
    INCLUDE  <LCD_4BIT.INC>
    INCLUDE  <LCD_MENS.INC>
    INCLUDE  <BIN_BCD.INC>
    END
    
========
```
Un curiosidad, según veo este enlace de abajo hecho con el 16F88, tiene varios modo de hacer funcionar el SFR05. Lo programó con C, yo lo haré con ASM.

http://tech-freaks.net/?p=35

Saludo.






*EDITO:*

Ver Flash

Saludo.


----------



## carmant (Sep 2, 2011)

Igual le sirve a alguien, mirad en este hilo

https://www.forosdeelectronica.com/posts/549795/


----------



## GGSD (Abr 17, 2012)

Alguien tiene el circuito de como hacerlo usando el Pic 16F84A y con diodios?


----------



## Meta (Abr 17, 2012)

Hace tiempo lo hice y funciona.

https://www.forosdeelectronica.com/f24/controlar-estaque-agua-pic-31889/index2.html

Saludo.


----------

