# Lectura de un potenciometro en LCD.(PIC16F628A)



## meneypro (Abr 7, 2012)

Hola.

Me gustaria que me ayudaran con una practica que consiste en mostrar en un lcd la lectura de el valor (en porcentaje) de un potenciometro.
Utilizo el PIC16F628A y hasta ahora he intentado con la instruccion POT,conectando  un capacitor de .1uf,el cual se carga y descarga utilizando el potenciometro para regular la corriente que circula,entonces a mayor resistencia el capacitor tarda mas tiempo en cargarse, y la PIC da un valor alto o si se gira el potenciometro a la minima resistencia, el capacitor se cargara mas rapido y la variable dara cero.
He armado el circuito requerido,pero se supone que el potenciometro al estar a su maximo en el LCD marque 255 y al minimo 0, pero al mover el potenciometro va de 0 hasta 255, esto sin haber girado el potenciometro ni a la mitad de su valor.
Haber si me pueden ayudar a que marque el 255 cuando este a su maxima resistencia.Adjunto el circuito y el programa empleado.

Gracias de antemano.


----------



## lpnavy (Abr 7, 2012)

ponle en VCC y el GND al LCD ademas te falto los ":" despues de la etiqueta de inicio "medir"



dato VAR BYTE              

medir:  
    POT portb.0,255,dato     
    LCDOUT $FE, 1," Rango= "    
    LCDOUT, #dato               
    PAUSE 100 
GOTO medir 
END


----------



## meneypro (Abr 7, 2012)

Gracias por la respuesta lpnavy.
Mira ya habia tomado en cuenta eso de los dos puntos y tambien la alimentacion del LCD pero  de igual manera no funciona.

Gracias.


----------



## lpnavy (Abr 7, 2012)

revisa que tengas bien instalado el proteus, envia tu archivo DNS y el codigo para descartarte fallas


----------



## meneypro (Abr 7, 2012)

Gracias por la respuesta lpnavy.

El circuito lo estoy probando en proteus y tambien fisicamente,el resultado es el mismo.
No creo que este mal proteus.


----------



## ricbevi (Abr 7, 2012)

meneypro dijo:


> Gracias por la respuesta lpnavy.
> 
> El circuito lo estoy probando en proteus y tambien fisicamente,el resultado es el mismo.
> No creo que este mal proteus.




Hola...A mí de esta forma me funciona.
Device = 16F628A
        All_Digital= true
    Config INTRC_OSC_NOCLKOUT, WDT_OFF, LVP_OFF, BODEN_OFF, CP_OFF,PWRTE_OFF,MCLRE_OFF
        ' OPTION_REG.7=0
         Declare Xtal= 4
         Declare LCD_Type 0
         Declare LCD_RSPin PORTA.4 'RS en RB1
         Declare LCD_ENPin PORTB.3 'E en RB3
         Declare LCD_DTPin PORTB.4 'Selecion del port B
         Declare LCD_Interface 4 'Modalidad 4 bits
         Declare LCD_Lines 2 '2 linea
         Dim dato As Byte

medir:   
         Pot PORTB.0,255,dato
         Print At 1,1,"RANGO="
         Print @dato, " "
         DelayMS 100
         GoTo medir
         End 



Saludos.

Ric.


----------



## lpnavy (Abr 7, 2012)

a mi me funciona bien, y si lo pruebas fisicamente fijate en los fuses que esten bien configurados a la hora de grabarlo al micro ya que puede acrear errores y no te ande el pic. te dejo la modificacion que le hice.


----------



## meneypro (Abr 7, 2012)

Hola.

Ricbevi,no me habia dado cuenta que adjuntaste el circuito y el archivo hex,lo probe y funciono de maravilla.Me podrias decir cual software de programacion utilizas?
Sabes cual era el error en mi programacion?

Ipnavy con tu circuito la lectura es mas exacta pero tengo el mismo problema de que al estar a 41% el potenciometro el lcd ya marca 255.

Ahora una duda mas, como creen que se tenga que hacer para que en el LCD se muestren valores de 0 a 100 y no de 0 a 255.Me han dicho que con un calculo pero en realidad lo desconozco.


Gracias a ambos.


----------



## lpnavy (Abr 7, 2012)

pues sencillo solo cambia el 255 por un 100 y listo ya que seria tu valor maximo. y Ricbevi usa PROTON en ves del compilador de Microstudio.


----------



## D@rkbytes (Abr 8, 2012)

meneypro dijo:


> Hola.
> 
> Me gustaria que me ayudaran con una practica que consiste en mostrar en un lcd la lectura de el valor (en porcentaje) de un potenciometro.
> Utilizo el PIC16F628A y hasta ahora he intentado con la instruccion POT,conectando  un capacitor de .1uf,el cual se carga y descarga utilizando el potenciometro para regular la corriente que circula,entonces a mayor resistencia el capacitor tarda mas tiempo en cargarse, y la PIC da un valor alto o si se gira el potenciometro a la minima resistencia, el capacitor se cargara mas rapido y la variable dara cero.
> ...


Saludos.
En este ejemplo que adjunto en PICBASIC Se muestra el porcentaje de la posición del potenciometro.
Si quieres que mida de 000 a 255 solo debes omitir la fórmula de mi ejemplo,
y mostrar el valor directo de la variable. Por ejemplo: DEC3 B0
Espero te sirva de ayuda.

Suerte y hasta luego.


----------



## ricbevi (Abr 8, 2012)

meneypro dijo:


> Hola.
> 
> Ricbevi,no me habia dado cuenta que adjuntaste el circuito y el archivo hex,lo probe y funciono de maravilla.Me podrias decir cual software de programacion utilizas?
> Sabes cual era el error en mi programacion?
> ...



Uso como te dijeron Proton y a mi también me falla tú simulación disparándose después de la mitad la lectura a fondo de escala. Como ya te aclararon cambia  Pot PORTB.0,255,dato por Pot PORTB.0,100,dato para tener una escala de 0 a 100 en vez de 0 a 255.
En mí simulación sacada de la ayuda del Proton el extremo del potencio metro no va a la alimentación ya que esto afectaría a forma en que mide la función POT y los valores o del potencio metro o del capacitor lo altere de 100nF a 75nF o el pote de 10K a 7K5 para mayor exactitud en la medición.

Saludos.

Ric.


----------



## meneypro (Abr 12, 2012)

Muchas gracias a todos por su ayuda.


----------



## groamir (Jul 20, 2016)

Hola a todos buscando informacion sobre el tema me encontre con este post  quisiera conectarle a este circuito un rele , que se active al llegar a determinado valor de lectura en el potenciomtero  por ejemplo al llegar al 50% se active el rele  saludos


----------



## D@rkbytes (Jul 20, 2016)

¿Y cuál es el problema?


----------



## groamir (Jul 20, 2016)

De los pines sobrante del pic utilizarlo para activar un rele en que parte del codigo pudiera  insertar la linea de codigo para activar el rele cuando el poteciometro llegue a determinado valor leido o ejemplo 50% , veo que tu mismo lo agregaste , saludos


----------



## ruben90 (Jul 20, 2016)

con una _sentencia if_ lo logras,

```
[B]if[/B](valor_leído == valor) salida_pic = 1;
                    [B]else[/B] salida_pic = 0;
```


----------



## D@rkbytes (Jul 20, 2016)

Pues si se puede. Nada más tienes que hacer la comparación y actuar en consecuencia.



ruben90 dijo:


> con una _sentencia if_ lo logras,
> 
> ```
> [B]if[/B](valor_leído == valor) salida_pic = 1;
> ...


Sería mejor hacer una histéresis por software para evitar una conmutación errática cuando la lectura esté en la transición.


----------



## JUNIORPOICON (Ago 11, 2021)

Estimado D@rkbytes disculpa la ignorancia, me podrias explicar porfavor a que te refieres con histeresis .?
o quizas con algún ejemplo corto, seria de mucha ayuda.

Muchas gracias.


----------



## Scooter (Ago 11, 2021)

Histéresis - Wikipedia, la enciclopedia libre
					






					es.m.wikipedia.org


----------



## JUNIORPOICON (Ago 11, 2021)

*S*i tuvieran alg*ú*n ejemplo estimados seria excelente.
*G*racias.


----------



## cosmefulanito04 (Ago 11, 2021)

Para que entiendas la idea de la histéresis llevado a la programación en un sistema de control simple.

Supongamos que tenés un sistema de refrigeración que debe activarse cuando la ºT supera un cierto umbral (llamémosle temp_max) y debe desactivarse cuando se alcance otro umbral del ºT (llamémosle temp_min). Entonces la idea sería saber en que estado actual está tu control para tomar una decisión según la ºT actual, ej:


```
...
temp_actual=lectura_temp();
...
if(refrigeracion_on<1) //Pregunto si el sistema de refrigeración se encuentra apagado
{
    if(temp_actual>=temp_max) //Pregunto si se alcanzó la temperatura max con el sistema de refrigeración apagado
    {
        refrigeracion_on=1;    //Enciendo el sistema de refrigeración
    }
}// Sistema de refrigeración apagado
else
{
    if(temp_actual<=temp_min)
    {
        refrigeracion_on=0;    //Apago el sistema de refrigeración
    }
}// Sistema de refrigeración encendido
....
```

Entonces la idea de separar temp_max de temp_min, es evitar que el control de refrigeración oscile entre 1 y 0 cuando este cerca de esos valores en el corto plazo. Mientras más cerca esten esos valores, mayor es la probabilidad de esa oscilación y cuando temp_min y temp_max son iguales, es muy probable que el sistema oscile. Obviamente en el funcionamiento normal, vas a tener una oscilación, de encendido y apagado, pero más espaciado en el tiempo, al igual que funciona un aire acondicionado.


----------



## D@rkbytes (Ago 11, 2021)

JUNIORPOICON dijo:


> si tuvieran algún ejemplo, estimados, sería excelente.


Otro ejemplo adjunto.


----------



## cosmefulanito04 (Ago 11, 2021)

```
//Código de D@arkbyte
...
   
while (TRUE)
{
    valor_adc = read_adc();                // Leer al ADC
    voltaje = (valor_adc / 1023.0) * 5;    // Convertir a voltaje.
    porcentaje = (voltaje / 5.0) * 100;    // Convertir a porcentaje.

    #ifdef DEBUG
    printf("Voltaje: %0.2f V\rPorcentaje: %0.2f %c\r\n", voltaje, porcentaje, 0x25);
    delay_ms(500);
    #endif
    // Establecer un rango de actuación con histéresis por software.
    if (porcentaje > 48.5 && porcentaje < 51.0)
        output_high(pin_relay);
    else if (porcentaje < 48.0 || porcentaje > 51.0)
        output_low(pin_relay);
}
```

D@rk, eso más que histéresis sería implementar un rango de valores por el cual se considera la salida en alto y todo fuera de ese rango considerar la salida en 0.


----------



## D@rkbytes (Ago 12, 2021)

Sí, esa fue la intención que le dí a ese programa, pero la manera de actuar se puede modificar.
La intensión es tratar de evitar en lo más que se pueda las oscilaciones durante la transición o umbral.


----------



## Scooter (Ago 12, 2021)

Busca en el foro, se ha hablado bastantes veces de eso.

Puedes también aplicar un control proporciona que para muchos casos es suficiente.


----------



## JUNIORPOICON (Ago 13, 2021)

D@rkbytes dijo:


> Otro ejemplo adjunto.


Muchas gracias por tomarse la molestia en responder  .
Primero quiero comentarles lo que deseo realizar en mi proyecto. 
Programacion en Pic Basic Pro - Pic 16f628A
1. Inicio con retardo de dos minutos, una vez pasado ese tiempo encender Motor1.
2. Que permanezca encendido por 6 horas. Una vez que hayan pasado las 6 horas, que recien empiece a sensar. Para efectos de simulacion estoy usando un potenciometro de 50k, en la vida real es un sensor ptc de 5 a 50 k. Aumenta su ohmeaje cuando la temperatura baja. 
3. que el sensor haga lo siguiente:
cuando este por debajo del 70% de su valor de reistencia encienda el Motor1
o cuando este por encima del 90% de su valor active la Resistencia1
4 y que empiece a trabajar oscilando en esos valores.

Ahora mi problema es que cuando coloco en simulacion el potenciometro de 10k funciona correctamente, sin embargo cuando coloco el potenciometro de 50k , el programa no lee correctamente los valores y en pantalla no aparecen los vlores q deberian ser.

Les voy adjuntar parte de mi programa.
Espero me puedan ayudar. Muchas gracias.




```
@ DEVICE INTRC_OSC_NOCLKOUT,PROTECT_OFF,WDT_OFF,PWRT_ON,MCLR_ON,BOD_OFF,LVP_OFF,CPD_OFF

DEFINE OSC 4

 DEFINE  LCD_DREG    PORTB      ; define pines del LCD  B4  a  B7
 DEFINE  LCD_BITS    4
 DEFINE  LCD_DBIT    4          ; empezando desde el Puerto B4 hasta el B7
 DEFINE  LCD_RSREG   PORTA      ;define el puerto B para conectar el bit RS
 DEFINE  LCD_RSBIT   0          ;este es el puerto B3
 DEFINE  LCD_EREG    PORTA      ;define el puerto B para conectar el bit Enable
 DEFINE  LCD_EBIT    1          ;este es el puerto B2     
 
 CMCON = 7                ; Entradas Analogicas del Puerto A Como Digitales
 TRISA = $FC            ; %11111100
 TRISB = $F                ; %00001111 (POT hace bidireccional al pin RB0)
 B0 VAR word            ; Variable para almacenar el dato de POT
 dato var word
 
 SYMBOL  POTE      = PORTA.2
 SYMBOL  LED1      = PORTB.1
 SYMBOL  LED2      = PORTB.2
 symbol  HORAS     = PORTA.3
 SYMBOL  MINUTOS   = PORTA.4
 
 hora    VAR BYTE : minut   VAR BYTE : segun VAR BYTE                   
 cuenta  VAR BYTE : actual  VAR BYTE : x     VAR BYTE             
 cuenta  = 0 : actual  = 1
 
 CLEAR

eeprom 0,[00,00,00]
READ 0,hora : READ 1,minut : READ 2,segun

      ;setea TMR0 de interrupción cada 32768 microsegundos
OPTION_REG = %1010110   ;setea TMR0 configurando y habilita PORTB pullups
INTCON = %10100000      ;hablilita TMR0 interrupción interna
ON INTERRUPT GOTO interrup

pause 200
    
INICIO:
    IF MINUTOS = 0 THEN gosub incmin                ;botón para igualar minutos
    IF hORAS   = 0 THEN gosub inchr                 ;botón para igualar horas
    IF actual = 1 THEN                              ;chequea si hay que actualizar LCD
    gosub Mostrar
    actual = 0                  ;pantalla actualizada
    ENDIF
GOTO INICIO

Mostrar:
                                    
    POT POTE,127,B0                 ;127 para 10K - 31 para 50K
    B0 = b0*100/255                 ; elvalor sale en porcentaje
    LCDOUT $FE,1," ",dec2 hora,":",dec2 minut,":",DEC2 segun
    LCDOUT  $FE,$C0,"POT= ",dec b0,"%"
    if (hora <= 5) and (minut = 2) then gosub Motor_On
    if hora >= 6 then gosub Sensar
    
    return
      
; ***********************para igualar la hora *****************

  incmin: minut = minut + 1
    IF minut >= 60 THEN minut=0
    gosub Pausa
    return
    
  inchr: hora = hora + 1
    IF hora >= 24 THEN hora=0
    gosub Pausa
    return
    
  Pausa:
  FOR x = 1 TO 25 ; retardo de 200 mls
    PAUSE 10 ;pasos de 10 mls para no perder interrupciones
    NEXT x
    actual = 1 ;indica actualizar pantalla LCD
  return
;************** Handler de interrupciones para incrementar contador ***************

DISABLE             ;deshabilita interrupciones durante el proceso

interrup:
    cuenta = cuenta + 1 ;cuenta las interrupciones del TMR0
    TMR0 = 4 ;resta 4 al contador de 256 del TMR0
    
    IF cuenta < 31 THEN reset ;31 cuentas (32256ms = 999936uS)
    cuenta = 0
    segun = segun + 1
    
    IF segun >= 60 THEN
    segun = 0
    minut = minut + 1
    
    IF minut >= 60 THEN
    minut = 0
    hora = hora + 1
    
    IF hora >= 24 THEN
    hora = 0
    
    ENDIF
    ENDIF
    ENDIF
    WRITE 0, HORA : READ 0,hora : WRITE 1,MINUT : READ 1,minut
    
    actual = 1 ;actualizar LCD
    
reset:
    INTCON.2 = 0 ;resetea la bandera de interrupción del TMR0
    RESUME

Sensar:
   if B0 >= 90 then
        gosub resis_on
   else
   if B0 <= 75 then
        gosub Motor_on
   endif
   endif
return

Motor_On:
    high led1 : low led2
return

Resis_On:
     low led1 : high led2
return

END
```


----------



## ricbevi (Ago 13, 2021)

Hola....Tenes la opción de cambiar el valor RC para que siga tu programa(cuentas) o cambias las cuentas en el programa para que siga a tu cambio RC.

Un ejemplo de que funciona si se adapta el valor del C cuando se cambia R.

No tengo el PBP instalado y si bien tengo el Proton o Positron, no tienen exactamente la misma sintaxis.


Saludos.


----------



## D@rkbytes (Ago 13, 2021)

Para empezar, si requiero lecturas análogas, cambiaría el microcontrolador por uno con ADC, por ejemplo: el PIC16F88
Para el conteo de las horas usaría un RTC como el DS1307 o implementaría uno interno con algún timer.
Y si quiero programar en Basic, cambiaría de entorno, el Basic de Proton es mejor que el de MicroCode.


----------



## unmonje (Ago 13, 2021)

JUNIORPOICON dijo:


> Muchas gracias por tomarse la molestia en responder  .
> Primero quiero comentarles lo que deseo realizar en mi proyecto.
> Programacion en Pic Basic Pro - Pic 16f628A
> 1. Inicio con retardo de dos minutos, una vez pasado ese tiempo encender Motor1.
> ...


Ni se moleste en poner potes de alto valor de resistencia para leer entradas analógicas, porque se le va a venir la relación señal ruido hasta el piso y se le vá a meter señal de alterna de 50 hertz de la red domiciliaria, en rigor evite pasarse de 10 o 20 kohms . Si esta al limite , ponga un capacitor que atenúe todo los de AC y despues rece para que funcione. Yo lloré mucho hasta resolverlo.  


JUNIORPOICON dijo:


> *S*i tuvieran alg*ú*n ejemplo estimados seria excelente.
> *G*racias.


¿Ejemplo de histéresis ? mmmmm veamos :
Supongamos que quiero que mi heladera deje de enfriar a los -10 grados y entonces apague el moto compresor.
Supongamos que llega a los -10 grados y se apaga tal como quería.
5 segundos después  de apagarse la temperatura sube a -9, 99 grados por ende el motor enciende de nuevo.
5 segundos despues  vuelve a -10 grados  y se apaga el motor.
Con este esquema método , la heladera pareceria un árbol de navidad y duraría muy poco innecesariamente.
Para eso se inventó el control de histéresis , para que el motor no se convierta en un histérico asunto.
Dicho en castellano se le llama  *control de umbral o ventana*, es decir que se apagará  en -10 grados, pero que su re encendido, será en 0 grados,  es decir mas lejos del punto límite , lo que da un tiempo razonable de pausa ,  para que el motocompresor no sufra y ademas se descomprima.


----------



## Angel Arriaga (Nov 12, 2021)

Tengo un problema con esta misma practica; lo que me sucede a mi es que pese a funcionar correctamente, me surge el mismo error una y otra vez en proteus y no entiendo a que se deba, espero que puedan ayudarme. Les adjunto evidencia, gracias.


----------



## D@rkbytes (Nov 13, 2021)

Prueba con el ejemplo adjunto.


----------



## Angel Arriaga (Nov 13, 2021)

D@rkbytes dijo:


> Prueba con el ejemplo adjunto.


Muchas gracias! si funciono


----------

