Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

15/07/2012 #1


LM35 + PIC programación en PIC C
Hola a todos

Estoy haciendo un proyecto de temperatura con lm35 y el 16F877A programando en PIC C, el código lo conseguí en Internet y le cambie algunas cosas y lo e terminado. Lo simule en proteus funciona de maravilla sin ningún tipo de errores. Pero el problema es cuando lo pruebo físicamente ya que las lecturas varían mucho y muestran números muy elevados o muy pequeños, las lecturas varían constantemente sin permanecer fijo, ejemplo esta en 70°C y pasa a 120°C o a 10°C o 0°C. No se que puede estar pasando.
Aquí les dejo el código para que lo observen:

Código:
#include <LM_35.h>
#include <LCD.c>

void main()
{
   lcd_init();
   setup_adc_ports(AN0);
   setup_adc(ADC_CLOCK_INTERNAL);
   //setup_pp(PMP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_ccp1(CCP_OFF);
   setup_comparator(NC_NC_NC_NC);

   //TODO: User Code
   
   float temper,medicion;

   printf(LCD_PUTC, "\f");    // limpia o borra el LCD
   lcd_gotoxy(1,1);
   printf(LCD_PUTC, "Termometro");
   delay_ms(2000);
   
   printf(LCD_PUTC, "\f");
      lcd_gotoxy(1,1);
      printf(LCD_PUTC, "Tempet: ");
      delay_ms(2000);
   
   while (true){
   
      lcd_gotoxy(1,1);
      printf(LCD_PUTC, "");
      
      setup_adc_ports(AN0);
      setup_adc(ADC_CLOCK_INTERNAL);
      set_adc_channel (0);                // Elige canal a medir RA0
      delay_us (10);
      medicion=read_adc ();              // Hace conversión AD 
      setup_adc (adc_off);                // Apaga ADC
      temper=medicion*(0.48875);     // Pasa binario a °C
  
      printf(lcd_putc,"%02.3f",temper);   // xxx.x °C
      delay_ms (1000);
      }

   

}
15/07/2012 #2


yo te recomendaria hacer esto lo primero, para evitar repetir procesos en el bucle while.
-estas tres lineas las pondria en los encabezados:
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel (0); // Elige canal a medir RA0
-quitaria esta linea:
setup_adc (adc_off); // Apaga ADC
- y bueno lo de pasar de bianrio a ºC mejor que lo expliques que yo no entinedo esa conversion jajaja

y bueno tal vez podrias cambiar la veocidad del conversor analogico setup_adc(ADC_CLOCK_INTERNAL);

tambien puede ser fallo en el montaje
15/07/2012 #3

Avatar de Rigeliano

Como es el circuito que montaste. A mi me parece que si lo conectas directo al PIC este va llegar a solo 1V cuando tenga 100 grados con lo cual pierdes presicíon, el ADC siempre va oscilar pero si oscila por ejemplo +-20mV son 40 grados de diferencia entre las lecturas maximas y minimas, creo que deberias de amplificar primero la señal X3 por lo menos para que cuando tengas 150C este te de un maximo de 4.5V.
15/07/2012 #4


Rigeliano dijo: Ver Mensaje
Como es el circuito que montaste. A mi me parece que si lo conectas directo al PIC este va llegar a solo 1V cuando tenga 100 grados con lo cual pierdes presicíon, el ADC siempre va oscilar pero si oscila por ejemplo +-20mV son 40 grados de diferencia entre las lecturas maximas y minimas, creo que deberias de amplificar primero la señal X3 por lo menos para que cuando tengas 150C este te de un maximo de 4.5V.
Pues si lo estoy conectando directamente al PIC, en la simulación funciona bien pero ya físico varia mucho sucesivamente de 80°C a 15°C de 35°C a 100°C inclusive de 70°C a 0°C
Ahí adjunto el plano del circuito.

---------- Actualizado después de 4 minutos ----------

Limako dijo: Ver Mensaje
yo te recomendaria hacer esto lo primero, para evitar repetir procesos en el bucle while.
-estas tres lineas las pondria en los encabezados:
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel (0); // Elige canal a medir RA0
-quitaria esta linea:
setup_adc (adc_off); // Apaga ADC
- y bueno lo de pasar de bianrio a ºC mejor que lo expliques que yo no entinedo esa conversion jajaja

y bueno tal vez podrias cambiar la veocidad del conversor analogico setup_adc(ADC_CLOCK_INTERNAL);

tambien puede ser fallo en el montaje

jejejeje cambio la linea que me dijiste y funciono en la simulación pero ya en la parte física no siguió el mismo error. Revisare lo del montaje.
Lo del proceso de conversión lo tome de una pagina y aquí esta la explicación:

el "0.48875" sale de dividir 5/1023 y el resultado de eso multiplicarlo por 100
el 5 sale de los 5 voltios aplicado a el voltage de referencia, los 1023 salen
de los 10 bit de resolucion del conversor analogico digital que seleccionamos.
Si utlizaramos la resolucion de 8 bits del conversor analogico digital, la
formula fuera (5/255)*100 ya que con 8 bits el numero maximo posible es de 0-255
Imágenes Adjuntas
Tipo de Archivo: jpg LM35+PIC.jpg (151,1 KB (Kilobytes), 291 visitas)
15/07/2012 #5

Avatar de Rigeliano

Prueba con un condensador entre el ADC y tierra 100nF por ejemplo y si con eso no basta entonces tienes que amplificar la señal como te dije y recalcular tus valores de salida.
15/07/2012 #6
Moderador

Avatar de Dano

Rigeliano dijo: Ver Mensaje
Como es el circuito que montaste. A mi me parece que si lo conectas directo al PIC este va llegar a solo 1V cuando tenga 100 grados con lo cual pierdes presicíon, el ADC siempre va oscilar pero si oscila por ejemplo +-20mV son 40 grados de diferencia entre las lecturas maximas y minimas, creo que deberias de amplificar primero la señal X3 por lo menos para que cuando tengas 150C este te de un maximo de 4.5V.
+1

O usas un amplificador, o modificas V+ REF
16/07/2012 #7


El lm35 a temperatura máxima te tira 1.5v osea que si usas +vref a 5 voltios tenes 1023 bytes máximos que con 1.5v de tu sensor estas usando 307 bytes nomas. Después de eso se te mete interferencia y por eso tenes tanta oscilación.

Hace como te dicen ellos Pone VRef a 1.5voltios o utiliza un amplificador no inversor que te entregue a la salida 5v cuando en la entrada tengas 1.5
17/07/2012 #8


Hola a todos
Hice lo que me sugirieron puse una etapa de amplificación de la señal que salia del lm35 y deje el vref a 5V.
Normalmente donde vivo la temperatura oscila entre 28°C - 37°C, al probarlo físicamente arrojaba una temperatura de 90°C lo cual es muy elevada fuera de los rangos normales pero ya no oscilaba tanto como anteriormente.
Se me dio por quitar la etapa y de amplificación y conecte la salida del lm35 al PIC directamente como lo tenia anteriormente y sorprendentemente esta funcionando correctamente marcando 34°C que era la temperatura en ese momento.
La verdad no se que habrá pasado... pero ya funcionara jejejejeje
De todas maneras muchas gracias a todos porque me han aclarado muchas dudas y e aprendido un poco mas sobre esto.

---------- Actualizado después de 3 minutos ----------

Ahora probare con sensores un poco mas profesionales que el lm35 por así decirlo.
Con uno que tiene incorporado un sensor de temperatura y humedad.
Con otro de solo humedad.
Mas adelante les comentare como me fue.
26/09/2012 #9


Me encuentro en un lio, pues estoy realizando un sensor de temperatura con el lm35 para así visualizar su información en el display lcd y adyacentemente reducir la temperatura para mantenerla estable.
Sin embargo solo he tenido éxito en las simulaciones, ya que al montar el circuito este no me funciona.

Así que de verdad me vendría bien una ayuda, para saber cual es mi error.
Este es mi programa:

Código:
#include <16F876A.h>
#fuses NOWDT,XT
#use delay(clock=4000000)

#include <ce_lcd.c>

void main() {
   
   lcd_init();
   delay_ms(6);
   
   printf(lcd_putc,"Sensor On");
   delay_ms(500);
   
   int x=0,temp=0;
   setup_adc_ports(AN0_VREF_VREF);
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   set_adc_channel(0);
   lcd_init();
   delay_ms(100);
   lcd_gotoxy(0,1);
    do //define un bucle infinito
   {
   
   x=read_adc();                                
   temp=(x*2)/5;
  
   lcd_gotoxy(1,1);                             
   printf(lcd_putc,"TEMPERATURA (C°) ");       
   lcd_gotoxy(1,2);                            
   printf(lcd_putc,"%03u",temp);                
   delay_ms(500);
   output_toggle(pin_b2);
   
   if
   (temp>20)
   {
   output_high(pin_b0);
   output_low(pin_b1);
   }  
   
   else {
   
   output_low(pin_b0);
   output_low(pin_b1);
   }
   
   }while(TRUE);
   
   
}  
   

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


ce_lcd:

   

struct lcd_pin_map {                
           BOOLEAN unused;           
           BOOLEAN rw;               
           BOOLEAN rs;               
           BOOLEAN enable;           
           int     data : 4;         
        } lcd;


#if defined use_portb_lcd
   #locate lcd = getenv("sfr:PORTB")    
   #define set_tris_lcd(x) set_tris_b(x)
#else
   #locate lcd = getenv("sfr:PORTC")    
   #define set_tris_lcd(x) set_tris_c(x)
#endif


#define lcd_type 2           
#define lcd_line_two 0x40    


BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
                            
                            


                           
                            

struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; 
struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; 



BYTE lcd_read_byte() {
      BYTE low,high;
      set_tris_lcd(LCD_READ);
      lcd.rw = 1;
      delay_cycles(2);
      lcd.enable = 1;
      delay_cycles(10);
      high = lcd.data;
      lcd.enable = 0;
      delay_cycles(10);
      lcd.enable = 1;
      delay_us(10);
      low = lcd.data;
      lcd.enable = 0;
      set_tris_lcd(LCD_WRITE);
      return( (high<<4) | low);
}


void lcd_send_nibble( BYTE n ) {
      lcd.data = n;
      delay_us(50);
      lcd.enable = 1;
      delay_us(50);
      lcd.enable = 0;
      delay_ms(1);
}


void lcd_send_byte( BYTE address, BYTE n ) {

      lcd.rs = 0;
      while ( bit_test(lcd_read_byte(),7) ) ;
      lcd.rs = address;
      delay_us(50);
      lcd.rw = 0;
      delay_us(50);
      lcd.enable = 0;
      lcd_send_nibble(n >> 4);
      lcd_send_nibble(n & 0xf);
      delay_ms(1);
}


void lcd_init() {
    BYTE i;
    set_tris_lcd(LCD_WRITE);
    lcd.rs = 0;
    lcd.rw = 0;
    lcd.enable = 0;
    delay_ms(50);
    for(i=1;i<=3;++i) {
       lcd_send_nibble(3);
       delay_ms(10);
    }
    lcd_send_nibble(2);
    for(i=0;i<=3;++i)
       lcd_send_byte(0,LCD_INIT_STRING[i]);
}


void lcd_gotoxy( BYTE x, BYTE y) {
   BYTE address;

   if(y!=1)
     address=lcd_line_two;
   else
     address=0;
   address+=x-1;
   lcd_send_byte(0,0x80|address);
}

void lcd_putc( char c) {
   switch (c) {
     case '\f'   : lcd_send_byte(0,1);
                   delay_ms(2);
                                           break;
     case '\n'   : lcd_gotoxy(1,2);        break;
     case '\b'   : lcd_send_byte(0,0x10);  break;
     default     : lcd_send_byte(1,c);     break;
   }
}

char lcd_getc( BYTE x, BYTE y) {
   char value;

    lcd_gotoxy(x,y);
    while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low
    lcd.rs=1;
    value = lcd_read_byte();
    lcd.rs=0;
    return(value);
}
24/10/2012 #10


Hola comunidad electrónica!! tengo un problemilla, cuando compilo este programa que adjunto no me da error pero cuando lo pruebo en proteus no me funciona, no se que me falta en el programa o me sobra. Quiero que me lea el valor de temperatura (LM35) y lo muestre por la barra de leds según la temperatura, a más temperatura mas leds encendidos. Espero que me podáis dar ideas para solucionarlo y que funcione.
Archivos Adjuntos
Tipo de Archivo: txt programaleds.txt (2,2 KB (Kilobytes), 128 visitas)
24/10/2012 #11


Bueno, mirando por encima y suponiendo que no tienes ningun error de programación (no uso ccs), decirte que el lm35 da una tensión proporcional a la temperatura, creo recordar que 10mV por grado.

A todo esto estamos suponiendo que no tienes ningun circuito que adapte las señales
Ahora en tu codigo estas leyendo esta tensón con "temp=read_adc();" y luego comparas esta lectura con distintos valores que suponemos temperaturas.

Ahora que esta pasando realmente, seguramente solo se te encienda el pin_B7.
Suponemos 30º
10mV por grado son: 30*0.01 = 0.3V
lectura ADC de 10bits con referencia 5v tenemos 5v/1024 = ~ 0.004883v cada bit
entonces cuando hacemos "temp=read_adc();" el valor de temp será 0.3/0.004883 = 61.43 (0000111101)

Si te fijas el resultado no coincide con los numeros que estas comparando. Soluciones varias.
-Adaptar la entrada para que la lectura te coincida con los grados (es una tonteria, dificil, perdida de resolucion, inestable por la poca tensión que representaria cada bit.......)
-Una vez hecha la lectura hacer la ecuación para convertir ese numero en grados
-En cada "if" comparar el resultado con el nº ya calculado (para 30º el 61)

Edit. Lo que sí es recomendable es adaptar la entrada amplificando la tensión del LM35 o bajando la referencia del pic para aprobechar mas la resolución.

Un saludo
24/10/2012 #12


gracias tannke!! no habia caido en eso que me comentas de la tension asi que voy a modificarlo y haber si funciona bien. un saludo
07/11/2012 #13

Avatar de Psyke

termometro digital con LM35
Hola a todos, yo hice mi termómetro digital con 2 displays de 7 segmentos y esta funcionando de maravillas, adjunto el enlace del código y a continuación les muestro como modificarlo para mostrar el valor en un display LCD, espero no tener errores ya que no estoy en mi computadora.
Hay que agregarle unas modificaciones para que mida correctamente temperatuas menores a 10 grados y mayores a 99

http://db.tt/3KvYgsLP
Código:
#include <16F877A.h>
#device adc=10
#fuses XT,NOWDT,NOPUT,NOPROTECT,NOWRT,NOBROWNOUT
#use delay(clock=4000000)

void main ()
{
int16 q;
float p,Temp;
unsigned int Unidad, Decena;
int Numeros[10] = {0b00111111,0b00000110,0b01011011,0b01001111,0b01100110,0b01101101,0b01111101,0b00000111,0b01111111,0b01101111};

setup_adc_ports (AN0);
setup_adc(ADC_CLOCK_INTERNAL);


      while(true){
      set_adc_channel(0);
      delay_us(20);
      q = read_adc();
      p = (float)(q * 5) / 1024;
      Temp = (p * 100) / 3;
       //  if(Temp<=99)
       //  {
         Unidad=(int)Temp % 10;
         Decena=(int)Temp / 10;
         output_d(Numeros[Decena]);
         output_b(Numeros[Unidad]);
         delay_ms(800);
         }
      //else
         //   {
          //  Decena=(int)(Temp - 100) / 10;
          //  Unidad=(int)(Temp - 100) - (Decena * 10);
         //   }
       //           
  }
Para visualizarlo en un display LCD debemos borrar todo lo que dice

Unidad=(int)Temp % 10;
Decena=(int)Temp / 10;
output_d(Numeros[Decena]);
output_b(Numeros[Unidad]);

Y debemos agregar el #include <lcd.c> y colocamos un
Printf(lcd_putc, "\f temperatura=%d, temp);
Espero no haberme equivocado, suerte a todos y cualquier problema me escriben
07/11/2012 #14


Si vas a usar otros sensores y quieres ver también la humedad, te recomiendo que mires el SHT11 de Sensirion, te da la temperatura y la humedad y no pasa por convertidor A/D, se comunica en 'digital', de esta forma puedes 'obviar' los problemas de tener una buena tensión de referencia y márgenes de conversión que no aprovechan todo el recorrido. Yo he pasado por esa experiencia y al final me he hecho 'fan' de estos circuitos.
21/11/2012 #15


Buenos días!! estoy haciendo un proyecto en el cual quiero que por el LCD me muestre siempre la temperatura actual (dada por un lm35) y la temperatura mínima y máxima deseada, pero que cuando descienda la temperatura de la mínima deseada o suba de la máxima, me muestre durante 2 segundos otro mensaje en la pantalla del LCD y vuelva a mostrar la actual.
He conseguido que me muestre el mensaje cuando baja de la mínima o sube de la máxima pero la pantalla ya no varía, quiero que me vuelva a mostrar la temperatura actual y no consigo como hacerlo, haber si alguien podría darme ideas. gracias!!

Código:
#include <16f876A.h>
#fuses XT,NOWDT   
#device adc=10                               //Utilizamos 10 bits para la conversion A/D.
#use delay(clock=4000000)
#use standard_io(a)                          //Defino puerto A para su utilización como entradas o salidas.
#use standard_io(b)                          //Defino puerto b para su utilización como entradas o salidas.
#use standard_io(c)                          //Defino puerto c para su utilización como entradas o salidas.
#include <LCD.c>                             //Libreria del LCD
#include <stdio.h>                           
#include <string.h>
#define use_portb_lcd TRUE                   //Para usar el puerto B para el LCD
#locate lcd = getenv("sfr:PORTB")            //Para usar el puerto B para el LCD

//#define subirmax PIN_A1
//#define bajarmax PIN_A2
//#define subirmin PIN_A4
//#define bajarmin PIN_A5

void main()
{ 
float temp,leer;                             //Variable para leer valores obtenidos por el convertidor A/D.                            
int max=30;                                  //Para ajustar la maxima
int min=25;                                  //y la minima

lcd_init();

set_tris_a(0xff);                          //Entrada.
set_tris_b(0x00);                          //Salida.

while(TRUE){
setup_adc_ports(AN0);                       //Entrada analógica utilizada, pin0 del puerto A.
setup_adc (adc_clock_div_32);               //Necesario para que funcione bien el adc.

set_adc_channel (0);                  //Elige canal a medir RA0
leer=read_adc ();                    //Hace conversión A/D 
//setup_adc (adc_off);           //Apaga ADC
temp=(leer*(0.48873));               // EL NUMERO (0.48875) viene de dividir (5/1023) y el resultado de la conversión

lcd_gotoxy(1,1);                          //escribe en la 1ª linea del LCD
lcd_putc(" T actual: ");
delay_us(100);
printf(lcd_putc,"%f",temp);          //muestra los grados según el lm35

lcd_gotoxy(1,2);                       //escribe en la 2ª linea, 1ª posicion del LCD
lcd_putc("max: ");
delay_us(100);
printf(lcd_putc,"%d",max);       //muestra la temperatura maxima elegida

lcd_gotoxy(9,2);                       //escribe en la 2ª linea, 9ª posicion del LCD
lcd_putc("min: ");
delay_us(100);
printf(lcd_putc,"%d",min);       //muestra la temperatura minima elegida

//while((temp<min)||(temp>max)){        
while (temp<min)
      {
         lcd_gotoxy(1,1);     //mostrar 2 segundos
         printf(lcd_putc,"      Frio!     "); 
         lcd_gotoxy(1,2);  
         printf(lcd_putc,"   Calentando   "); 
         delay_us(2000);
        //lcd_putc(" /f");                // Limpio LCD
      }    
while(temp>max)
      {
         lcd_gotoxy(1,1);    //mostrar 2 segundos
         printf(lcd_putc,"     Calor!     "); 
         lcd_gotoxy(1,2);  
         printf(lcd_putc,"   Enfriando   "); 
         delay_us(2000); 
       //lcd_putc(" /f");                 //Limpio LCD
       }
      //else
      {
         //lcd_gotoxy(1,1);  
        //printf(lcd_putc,"Temperatura OK  ");
      }
}

//setup_adc_ports(AN1);                       //Entrada analógica utilizada, pin0 del puerto A.
//setup_adc_ports(AN2);                       //Entrada analógica utilizada, pin0 del puerto A. 

//while(~input(subirmax));
//while(input(subirmax));
//delay_us(5);
//max=max+1;

//while(~input(subirmin));
//while(input(subirmin));
//delay_us(5);
//min=min+1;
}
21/11/2012 #16


Hola,

el circuito, ¿lo estás simulando o es real?. Una idea que puede ser una tontería pero por si las moscas. Estas comparando temp (float), con min y max(int). ¿Podrías verificar via debugger o simulación que esa comparación se hace bien?.

Saludos
21/11/2012 #17


De momento lo estoy simulando el proteus; en cuanto a la comprobación sí la hace correctamente ya que cuando la temperatura baja de 25º a 24º, por ejemplo, me cambia la pantalla del lcd pero cuando vuelve a subir a 25º o 26º la mantiene y lo que quiero es que la cambie. un saludo!!
22/11/2012 #18


Hola de nuevo,

ya tenemos el código, si pones por aquí el esquema que estas usando, intentaré ponerlo en marcha en el simulador y comentarte el posible error. Los bucles 'while' como los estas aplicando no son muy aconsejables en programación ya que te dejan 'congelada' la aplicación en una zona y te impide leer las teclas (por ejemplo). Una solución podría ser leer las teclas mediante una interrupción por un timer, aunque esto no tiene nada que ver con el problema que comentas te serviría más adelante.

Saludos
23/11/2012 #19


Aquí pongo donde lo estoy probando en proteus.
**todos los pulsadores que aparecen no los uso (de momento), los tengo puestos para usarlos en un futuro
Imágenes Adjuntas
Tipo de Archivo: jpg proyecto_lcd.jpg (62,5 KB (Kilobytes), 124 visitas)
23/11/2012 #20


Hola de nuevo,

he 'montado' el circuito y compilado el código, el fallo es evidente pero hasta que no me he puesto, no lo he visto. Cuando entra en un bucle de mayor o menor, no vuelves a leer la temperatura y la variable 'temp' no se actualiza aunque la temperatura varíe. Te lo adelanto por si quieres ponerte a ello, yo modificaré el código y lo pondré en un post próximo.

Saludos

---------- Actualizado después de 17 minutos ----------

Hola,

aquí tienes el código con ligeras correcciones, he cambiado algo los mensajes para simplificar y he sacado fuera del while principal el inicio del lcd, solo es necesario hacerlo una vez al principio.

Como te comenté, los while juegan malas pasadas. Otra cosa respecto al esquema, cuando los pulsadores no están pulsados en la entrada no tienes ni '1' ni '0', deberías ponerles una resistencia a masa en las entradas, así cuando no pulses, el valor será de '0'. Proteus puede que lo tolere, pero en un circuito real tendrías problemas.

Saludos

Código:
#include <16f876A.h>
#fuses XT,NOWDT
#device adc=10                               //Utilizamos 10 bits para la conversion A/D.
#use delay(clock=4000000)
#use standard_io(a)                          //Defino puerto A para su utilización como entradas o salidas.
#use standard_io(b)                          //Defino puerto b para su utilización como entradas o salidas.
#use standard_io(c)                          //Defino puerto c para su utilización como entradas o salidas.
#include <stdio.h>
#include <string.h>
#define use_portb_lcd TRUE                   //Para usar el puerto B para el LCD
#include <LCD.c>                             //Libreria del LCD
#locate lcd = getenv("sfr:PORTB")            //Para usar el puerto B para el LCD

//#define subirmax PIN_A1
//#define bajarmax PIN_A2
//#define subirmin PIN_A4
//#define bajarmin PIN_A5

void main()
{
float temp,leer;                             //Variable para leer valores obtenidos por el convertidor A/D.
int max=30;                                  //Para ajustar la maxima
int min=25;                                  //y la minima

lcd_init();

set_tris_a(0xff);                          //Entrada.
set_tris_b(0x00);                          //Salida.

// Setup de ADC
setup_adc_ports(AN0);                       //Entrada analógica utilizada, pin0 del puerto A.
setup_adc (adc_clock_div_32);               //Necesario para que funcione bien el adc.

// Bucle sin fin... programa principal
while(TRUE){
  set_adc_channel (0);                  //Elige canal a medir RA0
  leer=read_adc ();                    //Hace conversión A/D
  temp=(leer*(0.48873));               // EL NUMERO (0.48875) viene de dividir (5/1023) y el resultado de la conversión

  lcd_gotoxy(1,1);                          //escribe en la 1ª linea del LCD
  //-lcd_putc(" T actual: ");
  //-delay_us(100);
  //-printf(lcd_putc,"%f",temp);          //muestra los grados según el lm35
  printf(lcd_putc," T actual: %f",temp);

  lcd_gotoxy(1,2);                       //escribe en la 2ª linea, 1ª posicion del LCD
  //- lcd_putc("max: ");
  //-delay_us(100);
  //-printf(lcd_putc,"%d",max);       //muestra la temperatura maxima elegida

  //-lcd_gotoxy(9,2);                       //escribe en la 2ª linea, 9ª posicion del LCD
  //-lcd_putc("min: ");
  //-delay_us(100);
  //-printf(lcd_putc,"%d",min);       //muestra la temperatura minima elegida
  printf(lcd_putc,"max: %d min: %d",max,min);

  while(temp<min){
       lcd_gotoxy(1,1);     //mostrar 2 segundos
       printf(lcd_putc,"      Frio!     ");
       lcd_gotoxy(1,2);
       printf(lcd_putc,"   Calentando   ");
       delay_us(2000);
       set_adc_channel (0);                  //Elige canal a medir RA0
       leer=read_adc ();                    //Hace conversión A/D
       temp=(leer*(0.48873));               // EL NUMERO (0.48875) viene de dividir (5/1023) y el resultado de la conversión
      }

  while(temp>max){
      lcd_gotoxy(1,1);    //mostrar 2 segundos
      printf(lcd_putc,"     Calor!     ");
      lcd_gotoxy(1,2);
      printf(lcd_putc,"   Enfriando   ");
      delay_us(2000);
      set_adc_channel (0);                  //Elige canal a medir RA0
      leer=read_adc ();                    //Hace conversión A/D
      temp=(leer*(0.48873));               // EL NUMERO (0.48875) viene de dividir (5/1023) y el resultado de la conversión
      }

}

//setup_adc_ports(AN1);                       //Entrada analógica utilizada, pin0 del puerto A.
//setup_adc_ports(AN2);                       //Entrada analógica utilizada, pin0 del puerto A.

//while(~input(subirmax));
//while(input(subirmax));
//delay_us(5);
//max=max+1;

//while(~input(subirmin));
//while(input(subirmin));
//delay_us(5);
//min=min+1;
}
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.