Termometro digital en C

Ya veo, quizás sea por eso, porque lo estuve haciendo funcionar con 4.3 voltios.
No creo que sea por eso.
Hice una prueba alimentando al LM35 con una fuente variable, y por abajo de 3 voltios ya empezó a fallar.
De 3 voltios para arriba hasta el máximo soportado de 35 V. no hubo problemas y las lecturas fueron normales y constantes.

Cambia el sensor LM35 por uno nuevo, pero trata de conseguirlo en otra tienda.
 
Estimados.
realice un programa de lectura analogica con un pic16f877a en mikroc... la cosa es que estoy hasta el momento leyendo dos lm35 y dos sensores de corriene, la cosa es que al momento de leer los sensores de corriente el display ya no muestra nada. y debo agregarle dos lecturas mas de unos divisores de tension. me pueden ayudar a detectar el problema.

Adjunto un rar con archivo y simulacion.

[Edita tus comentarios en lugar de crear nuevos]

Estimados no tengo problemas con la lectura de lm35 tampoco con los sensores de corriente solo que luego e un momento el display ya no muestra nada. no se porque movieron a este tema.
 

Adjuntos

  • Variables 2.rar
    83.5 KB · Visitas: 18
Última edición por un moderador:
hola lee, viendo el programa que subiste puedo comentarte que tienes código innecesario en la rutina principal y en la interrupción no hiciste el uso adecuado del la lectura del adc.
la funcion adc_read(); configura, inicia espera a que termine la convercion y lee el adc por o cual el uso de esa función dentro de la interrupción es innecesaria.
Detalles como estos pudieron causar que el compilador no haga una buena gestión del LCD.
Te te muestro este código que puede ayudarte a conseguir lo que necesitas.
Código:
//DEFINICION PINES LCD
    sbit LCD_RS at RC3_bit;
    sbit LCD_EN at RC5_bit;
    sbit LCD_D7 at RD7_bit;
    sbit LCD_D6 at RD6_bit;
    sbit LCD_D5 at RD5_bit;
    sbit LCD_D4 at RD4_bit;
//DFINICION TRIS LCD
    sbit LCD_RS_Direction at TRISC3_bit;
    sbit LCD_EN_Direction at TRISC5_bit;
    sbit LCD_D7_Direction at TRISD7_bit;
    sbit LCD_D6_Direction at TRISD6_bit;
    sbit LCD_D5_Direction at TRISD5_bit;
    sbit LCD_D4_Direction at TRISD4_bit;

void main()
{
   //DEFINICION VARIABLES
   unsigned int adc_value1;
   unsigned int adc_value2;
   signed int adc_value3;
   signed int adc_value4;
   unsigned char texto1[15];
   unsigned char texto2[15];
   unsigned char texto3[15];
   unsigned char texto4[15];
   float Mv1;
   float Mv2;
   float Mv3;
   float Mv4;
   
   TRISA=0XFF;
   PORTA=0X00;

   Lcd_Init();
   Lcd_Cmd(_LCD_CURSOR_OFF);
   Lcd_Cmd(_LCD_CLEAR);
   Lcd_Out(1,2,"INVERSOR DC/AC");
   Lcd_Out(2,4,"1500 WATT");
   Delay_ms(2000);
   Lcd_Cmd(_LCD_CLEAR);
   Lcd_Out(1,3,"INICIANDO...");
   Delay_ms(2000);
   Lcd_Cmd(_LCD_CLEAR);
   while(1)
   {
         adc_value1=ADC_read(0);
         Mv1 = adc_value1*0.488;
         FloatToStr(Mv1,texto1);
         //texto1[4]=0;
         Lcd_Out(1,10,texto1);
         Lcd_Out(1,1,"T.IGBT1:");
         Lcd_Chr(1,15,223);
         Lcd_Chr(1,16, 'C');


         adc_value2=ADC_read(1);
         Mv2 = adc_value2*0.488;
         FloatToStr(Mv2,texto2);
         //texto2[4]=0;
         Lcd_Out(2,10,texto2);
         Lcd_Out(2,1,"T.IGBT2:");
         Lcd_Chr(2,15,223);
         Lcd_Chr(2,16, 'C');


         Delay_ms(3000);
         Lcd_Cmd(_LCD_CLEAR);

         adc_value3=ADC_read(2);
         Mv3 =(adc_value3-512)*0.0586;
         FloatToStr(Mv3,texto3);
         //texto3[4]=0;
         Lcd_Out(1,7,texto3);
         Lcd_Out(1,1,"I.DC:");
         Lcd_Out(1,12,"AMP ");

         adc_value4=ADC_read(3);
         Mv4 =(adc_value4-512)*0.0586;
         FloatToStr(Mv4,texto4);
         //texto4[4]=0;
         Lcd_Out(2,7,texto4);
         Lcd_Out(2,1,"I.DC:");
         Lcd_Out(2,12, "AMP ");

         Delay_ms(3000);
         Lcd_Cmd(_LCD_CLEAR);
   }
}
PD. Existe un problema con la funcion que convierte un numero real a cadena de texto y es que cuando el valor es pequeño ejemplo 0.00012xx la convercion lo expresa como 1.2xxe-4.
 

Adjuntos

  • ejemplo.rar
    104.9 KB · Visitas: 18
Muchas gracias Saint_ por responder... realizare dichos cambios y te comento como me va.
saludos

Muchas gracias Saint_ por responder... realizare dichos cambios y te comento como me va.
saludos



Saint_ Gracias, efectivamente el programa funciona ala perfección, y me e dado cuenta los errores que tenia mi código... ahora solo le agregare las entradas análogas que me falta y lo terminare para cargarlo.

Gracias y saludos.:apreton:
 
Última edición:
Estuve realizando agregándoles los nuevos sensores a dicho programa y aun sigue el problema al agregarle nuevas lecturas análogas... e tenido cuidado con la transformación y no entiendo que pasa? me pueden guiar porfa....

Código:
//DEFINICION PINES LCD
    sbit LCD_RS at RC3_bit;
    sbit LCD_EN at RC5_bit;
    sbit LCD_D7 at RD7_bit;
    sbit LCD_D6 at RD6_bit;
    sbit LCD_D5 at RD5_bit;
    sbit LCD_D4 at RD4_bit;
//DFINICION TRIS LCD
    sbit LCD_RS_Direction at TRISC3_bit;
    sbit LCD_EN_Direction at TRISC5_bit;
    sbit LCD_D7_Direction at TRISD7_bit;
    sbit LCD_D6_Direction at TRISD6_bit;
    sbit LCD_D5_Direction at TRISD5_bit;
    sbit LCD_D4_Direction at TRISD4_bit;

void main()
{
   //DEFINICION VARIABLES
   unsigned int adc_value1;
   unsigned int adc_value2;
   signed int adc_value3;
   signed int adc_value4;
   unsigned int adc_value5;
   unsigned int adc_value6,x,z;
    char texto1[16];
    char texto2[16];
    char texto3[16];
    char texto4[16];
    char texto5[16];
    char texto6[16];
   float Mv1;
   float Mv2;
   float Mv3;
   float Mv4;
   float Mv5;
   float Mv6;

   TRISA=0XFF;
   PORTA=0X00;

   Lcd_Init();
   Lcd_Cmd(_LCD_CURSOR_OFF);
   Lcd_Cmd(_LCD_CLEAR);
   Lcd_Out(1,2,"INVERSOR DC/AC");
   Lcd_Out(2,4,"1500 WATT");
   Delay_ms(2000);
   Lcd_Cmd(_LCD_CLEAR);
   Lcd_Out(1,3,"INICIANDO...");
   Delay_ms(2000);
   Lcd_Cmd(_LCD_CLEAR);
   
   while(1)
   {
         adc_value1=ADC_read(0);//TEMPERATURA 1°
         Mv1 = adc_value1*0.488;
         FloatToStr(Mv1,texto1);
         Lcd_out(1,10,texto1);
         Lcd_Out(1,1,"T.IGBT1:");
         Lcd_Chr(1,15,223);
         Lcd_Chr(1,16, 'C');

         adc_value2=ADC_read(1);//TEMPERATURA 2°
         Mv2 = adc_value2*0.488;
         FloatToStr(Mv2,texto2);
         Lcd_out(2,10,texto2);
         Lcd_Out(2,1,"T.IGBT2:");
         Lcd_Chr(2,15,223);
         Lcd_Chr(2,16, 'C');

         Delay_ms(2000);
         Lcd_Cmd(_LCD_CLEAR);

         adc_value3=ADC_read(2);//CORRIENTE BATERIA
         Mv3 =(adc_value3-512)*0.0586;
         FloatToStr(Mv3,texto3);
         Lcd_Out(1,7,texto3);
         Lcd_Out(1,1,"I.DC:");
         Lcd_Out(1,14,"AMP ");

         adc_value4=ADC_read(3);//CORRIENTE SALIDA INVERSOR
         Mv4 =(adc_value4-512)*0.0586;
         FloatToStr(Mv4,texto4);
         Lcd_out(2,7,texto4);
         Lcd_Out(2,1,"I.AC:");
         Lcd_Out(2,14, "AMP");
         
            Delay_ms(2000);
         Lcd_Cmd(_LCD_CLEAR);

         adc_value5=ADC_read(4);//VOLATAJE BATERIA
         Mv5 =(adc_value5*49)/1024.0;
         FloatToStr(Mv5,texto5);
         Lcd_Out(1,7,texto5);
         Lcd_Out(1,1,"V.DC:");
         Lcd_Out(1,13, "VOLTS");

         adc_value6=ADC_read(5);//VOLTAJE SALIDA INVERSOR
         Mv6 =(adc_value6*462)/1024.0;
         FloatToStr(Mv6,texto6);
         Lcd_Out(2,7,texto6);
         Lcd_Out(2,1,"V.AC:");
         Lcd_Out(2,13, "VOLTS");

         Delay_ms(2000);
         Lcd_Cmd(_LCD_CLEAR);
         

   }
}
 
Como usas mikroC, seguramente tendrás un problema con los bancos de memoria.
Este problema no lo resuelve el compilador automáticamente como lo hacen otros.

Declara los arreglos de tus variables en un banco de memoria, de ésta forma:
char texto1[16] absolute 0x20;
Así para todos tus arreglos.
No importa que uses la misma dirección, porque sólo usas los arreglos para mostrar texto.
Y si quieres ahorrar memoria, es mejor que uses un único arreglo.

Lo que importa son las variables que usarás para retener valores.
Declarando un único arreglo de conversión, optimizas la memoria del microcontrolador.
 
Estimado D@rkbyte, e realizados dichos cambios en las variables y ahora si se muestran todos los resultados en el lcd, pero sin mentirte aun no estoy 100% claro con el problema... seguiré leyendo y estudiando para comprender bien el compilador.

muchas gracias D@rkbytes :apreton:

Saludos
 
Yo lo pondria asi para sacar las rutinas de lectura de las de display si con esos cambios aun no muestra nada quita las rutinas de lectura y prueba de nuevo si aun asi no muestra ni el hola revisa las rutinas de display

Código:
//DEFINICION PINES LCD
    sbit LCD_RS at RC3_bit;
    sbit LCD_EN at RC5_bit;
    sbit LCD_D7 at RD7_bit;
    sbit LCD_D6 at RD6_bit;
    sbit LCD_D5 at RD5_bit;
    sbit LCD_D4 at RD4_bit;
//DFINICION TRIS LCD
    sbit LCD_RS_Direction at TRISC3_bit;
    sbit LCD_EN_Direction at TRISC5_bit;
    sbit LCD_D7_Direction at TRISD7_bit;
    sbit LCD_D6_Direction at TRISD6_bit;
    sbit LCD_D5_Direction at TRISD5_bit;
    sbit LCD_D4_Direction at TRISD4_bit;

void main()
{
   //DEFINICION VARIABLES
   unsigned int adc_value1;
   unsigned int adc_value2;
   signed int adc_value3;
   signed int adc_value4;
   unsigned int adc_value5;
   unsigned int adc_value6,x,z;
    char texto1[16];
    char texto2[16];
    char texto3[16];
    char texto4[16];
    char texto5[16];
    char texto6[16];
   float Mv1;
   float Mv2;
   float Mv3;
   float Mv4;
   float Mv5;
   float Mv6;

   TRISA=0XFF;
   PORTA=0X00;

   Lcd_Init();
   Lcd_Cmd(_LCD_CURSOR_OFF);
   Lcd_Cmd(_LCD_CLEAR);
   Lcd_Out(1,2,"INVERSOR DC/AC");
   Lcd_Out(2,4,"1500 WATT");
   Delay_ms(2000);
   Lcd_Cmd(_LCD_CLEAR);
   Lcd_Out(1,3,"INICIANDO...");
   Delay_ms(2000);
   Lcd_Cmd(_LCD_CLEAR);
   
   while(1)
   {
         adc_value1=ADC_read(0);//TEMPERATURA 1°
         adc_value2=ADC_read(1);//TEMPERATURA 2°
         adc_value3=ADC_read(2);//CORRIENTE BATERIA
         adc_value4=ADC_read(3);//CORRIENTE SALIDA INVERSOR
         adc_value5=ADC_read(4);//VOLATAJE BATERIA
         adc_value6=ADC_read(5);//VOLTAJE SALIDA INVERSOR

         Mv1 = adc_value1*0.488;
         FloatToStr(Mv1,texto1);
         Lcd_out(1,10,texto1);
         Lcd_Out(1,1,"T.IGBT1:");
         Lcd_Chr(1,15,223);
         Lcd_Chr(1,16, 'C');

         Mv2 = adc_value2*0.488;
         FloatToStr(Mv2,texto2);
         Lcd_out(2,10,texto2);
         Lcd_Out(2,1,"T.IGBT2:");
         Lcd_Chr(2,15,223);
         Lcd_Chr(2,16, 'C');

         Delay_ms(2000);
         Lcd_Cmd(_LCD_CLEAR);

         Mv3 =(adc_value3-512)*0.0586;
         FloatToStr(Mv3,texto3);
         Lcd_Out(1,7,texto3);
         Lcd_Out(1,1,"I.DC:");
         Lcd_Out(1,14,"AMP ");

         Mv4 =(adc_value4-512)*0.0586;
         FloatToStr(Mv4,texto4);
         Lcd_out(2,7,texto4);
         Lcd_Out(2,1,"I.AC:");
         Lcd_Out(2,14, "AMP");
         
            Delay_ms(2000);
         Lcd_Cmd(_LCD_CLEAR);

         Mv5 =(adc_value5*49)/1024.0;
         FloatToStr(Mv5,texto5);
         Lcd_Out(1,7,texto5);
         Lcd_Out(1,1,"V.DC:");
         Lcd_Out(1,13, "VOLTS");

         Mv6 =(adc_value6*462)/1024.0;
         FloatToStr(Mv6,texto6);
         Lcd_Out(2,7,texto6);
         Lcd_Out(2,1,"V.AC:");
         Lcd_Out(2,13, "VOLTS");

         Delay_ms(2000);
         Lcd_Cmd(_LCD_CLEAR);
         Delay_ms(10);

   }
}
 
Estimados Amigos del foro retomando mi proyecto, ahora cada ves que las variables leídas superen un valor x necesito que me enciendan un led rojo que indica alguna avería y caso contrario un led verde el cual señala todo ok. el ema es que no me funciona correctamente, por eso este mensaje.

Código:
//DEFINICION PINES LCD
    sbit LCD_RS at RC3_bit;
    sbit LCD_EN at RC5_bit;
    sbit LCD_D7 at RD7_bit;
    sbit LCD_D6 at RD6_bit;
    sbit LCD_D5 at RD5_bit;
    sbit LCD_D4 at RD4_bit;
//DFINICION TRIS LCD
    sbit LCD_RS_Direction at TRISC3_bit;
    sbit LCD_EN_Direction at TRISC5_bit;
    sbit LCD_D7_Direction at TRISD7_bit;
    sbit LCD_D6_Direction at TRISD6_bit;
    sbit LCD_D5_Direction at TRISD5_bit;
    sbit LCD_D4_Direction at TRISD4_bit;
    #define LEDVERDE PORTB.RB6
    #define LEDROJO PORTB.RB7
    #define ON 1
    #define OFF 0

void main()
{
   //DEFINICION VARIABLES
   unsigned int adc_value1;
   unsigned int adc_value2;
   signed int adc_value3;
   signed int adc_value4;
   unsigned int adc_value5;
   unsigned int adc_value6;
   char texto1[16]absolute 0x20;
   char texto2[16]absolute 0x21;
   char texto3[16]absolute 0x22;
   char texto4[16]absolute 0x23;
   char texto5[16]absolute 0x24;
   char texto6[16]absolute 0x25;
   char texto7[16]absolute 0x26;
   float Mv1 absolute 0x26;
   float Mv2 absolute 0x26;
   float Mv3 absolute 0x28;
   float Mv4 absolute 0x29;
   float Mv5 absolute 0x30;
   float Mv6 absolute 0x31;
   float Mv7 absolute 0x32;

   TRISA=0XFF;
   PORTA=0X00;
   TRISB=0;
   PORTB=0;


   Lcd_Init();
   Lcd_Cmd(_LCD_CURSOR_OFF);
   Lcd_Cmd(_LCD_CLEAR);
   Lcd_Out(1,2,"INVERSOR DC/AC");
   Lcd_Out(2,4,"1500 WATT");
   Delay_ms(2000);
   Lcd_Cmd(_LCD_CLEAR);
   Lcd_Out(1,3,"INICIANDO...");
   Delay_ms(2000);
   Lcd_Cmd(_LCD_CLEAR);


   while(1)
   {

         adc_value1=ADC_read(0);//TEMPERATURA 1°
         Mv1 = adc_value1*0.488;
         FloatToStr(Mv1,texto1);
         if ( Mv1 > 70.0 )
         {
         LEDROJO = ON;
         LEDVERDE = OFF;
         }
         else
         {
         LEDROJO = OFF;
         LEDVERDE = ON;
         }
         Lcd_out(1,10,texto1);
         Lcd_Out(1,1,"T.IGBT1:");
         Lcd_Chr(1,15,223);
         Lcd_Chr(1,16, 'C');

         adc_value2=ADC_read(1);//TEMPERATURA 2°
         Mv2 = adc_value2*0.488;
         FloatToStr(Mv2,texto2);
         if ( Mv2 > 70.0 )
         {
         LEDROJO = ON;
         LEDVERDE = OFF;
         }
         else
         {
         LEDROJO = OFF;
         LEDVERDE = ON;
         }
         Lcd_out(2,10,texto2);
         Lcd_Out(2,1,"T.IGBT2:");
         Lcd_Chr(2,15,223);
         Lcd_Chr(2,16, 'C');


         delay_ms(2000);
         Lcd_Cmd(_LCD_CLEAR);

         adc_value3=ADC_read(2);//CORRIENTE BATERIA
         Mv3 =((adc_value3-512)*0.0586);
         FloatToStr(Mv3,texto3);
         if ( Mv3 > 20.0 )
         {
         LEDROJO = ON;
         LEDVERDE = OFF;
         }
         else
         {
         LEDROJO = OFF;
         LEDVERDE = ON;
         }
         Lcd_Out(1,7,texto3);
         Lcd_Out(1,1,"I.DC:");
         Lcd_Out(1,14,"AMP ");

         adc_value4=ADC_read(3);//CORRIENTE SALIDA INVERSOR
         Mv4 =((adc_value4-512)*0.0586);
         FloatToStr(Mv4,texto4);
         if ( Mv4 > 20.0 )
         {
         LEDROJO = ON;
         LEDVERDE = OFF;
         }
         else
         {
         LEDROJO = OFF;
         LEDVERDE = ON;
         }
         Lcd_out(2,7,texto4);
         Lcd_Out(2,1,"I.AC:");
         Lcd_Out(2,14, "AMP");

         Delay_ms(2000);
         Lcd_Cmd(_LCD_CLEAR);

         adc_value5=ADC_read(4);//VOLATAJE BATERIA
         Mv5 =((adc_value5*49.0)/1024.0);
         FloatToStr(Mv5,texto5);
         if ( Mv5 < 24.0 )
         {
         LEDROJO = ON;
         LEDVERDE = OFF;
         }
         else
         {
         LEDROJO = OFF;
         LEDVERDE = ON;
         }
         Lcd_Out(1,7,texto5);
         Lcd_Out(1,1,"V.DC:");
         Lcd_Out(1,13, "VOLTS");

         adc_value6=ADC_read(5);//VOLTAJE SALIDA INVERSOR
         Mv6 =(adc_value6*462.9)/1024.0;
         FloatToStr(Mv6,texto6);
         if ( Mv6 < 200.0 )
         {
         LEDROJO = ON;
         LEDVERDE = OFF;
         }
         else
         {
         LEDROJO = OFF;
         LEDVERDE = ON;
         }
         Lcd_Out(2,7,texto6);
         Lcd_Out(2,1,"V.AC:");
         Lcd_Out(2,13, "VOLTS");

         Delay_ms(2000);
         Lcd_Cmd(_LCD_CLEAR);

   }
}
 
Anteriormente te mencioné que podías usar un único arreglo para mostrar las conversiones.
Esto es porque solo se usa para mostrar texto en pantalla, no para retener valores.

O sea que puedes usar el mismo arreglo para todas las conversiones que vayas a mostrar.

Ejemplo:
Código:
    char texto[16] absolute 0x20;

    Mv1 = adc_value1*0.488;
    FloatToStr(Mv1,texto);
    Lcd_out(1,10,texto);
    // Etc.
    Mv2 = adc_value2*0.488;
    FloatToStr(Mv2,texto);
    Lcd_out(2,10,texto);
    //Etc.
    Mv3 =((adc_value3-512)*0.0586);
    FloatToStr(Mv3,texto);
    Lcd_Out(1,7,texto);
    // Etc.
    Mv4 =((adc_value4-512)*0.0586);
    FloatToStr(Mv4,texto);
    Lcd_out(2,7,texto);
    // Etc.
Y las variables "Float" no las declares para código absoluto. (En un único banco de memoria)
Estimados amigos del foro, retomando mi proyecto, ahora cada vez que las variables leídas superen un valor x, necesito que me enciendan un led rojo que indica alguna avería y caso contrario, un led verde el cual señala todo ok.
Puedes usar algo así, por ejemplo:
Código:
    if(Var1 < 0xXX && Var2 > 0xXX && Var3 < 0xXX)
    {
        // Código a ejecutar.
    }
    {
    else
    {
        // Código a ejecutar.
    }
 
Estimado D@rkbytes gracias por siempre ayudar, te comento que e realizado los cambios y ya todo funciona ok, pero tuve que cambiar los pines del lcd del puerto d al puerto b, por el diseño de la placa y al simularlo ya no me funciona. E revisado todo y no encuentro nada extraño. me puedes dar alguna sugerencia...
Código:
//DEFINICION PINES LCD
    sbit LCD_RS at RB0_bit;
    sbit LCD_EN at RB1_bit;
    sbit LCD_D7 at RB2_bit;
    sbit LCD_D6 at RB3_bit;
    sbit LCD_D5 at RB4_bit;
    sbit LCD_D4 at RB5_bit;
//DFINICION TRIS LCD
    sbit LCD_RS_Direction at TRISB0_bit;
    sbit LCD_EN_Direction at TRISB1_bit;
    sbit LCD_D7_Direction at TRISB2_bit;
    sbit LCD_D6_Direction at TRISB3_bit;
    sbit LCD_D5_Direction at TRISB4_bit;
    sbit LCD_D4_Direction at TRISB5_bit;
    
    #define LEDVERDE PORTD.RD2
    #define LEDROJO PORTD.RD3
    #define FALLA PORTD.RD4
    #define ON 1
    #define OFF 0

void main()
{
   //DEFINICION VARIABLES
   unsigned int adc_value1;
   unsigned int adc_value2;
   signed int adc_value3;
   signed int adc_value4;
   unsigned int adc_value5;
   unsigned int adc_value6;
   char texto1[16]absolute 0x20;
   char texto2[16]absolute 0x21;
   char texto3[16]absolute 0x22;
   char texto4[16]absolute 0x23;
   char texto5[16]absolute 0x24;
   char texto6[16]absolute 0x25;
   char texto7[16]absolute 0x26;
   float Mv1 ;
   float Mv2 ;
   float Mv3 ;
   float Mv4 ;
   float Mv5 ;
   float Mv6 ;
   int bandera1;
   int bandera2;


   TRISA=0XFF;
   PORTA=0X00;
   TRISD=0x00;
   PORTD=0x00;
   INTCON = 0;
   Lcd_Init();
   Lcd_Cmd(_LCD_CURSOR_OFF);
   Lcd_Cmd(_LCD_CLEAR);
   Lcd_Out(1,2,"INVERSOR DC/AC");
   Lcd_Out(2,4,"1500 WATT");
   Delay_ms(2000);
   Lcd_Cmd(_LCD_CLEAR);
   Lcd_Out(1,3,"INICIANDO...");
   Delay_ms(2000);
   Lcd_Cmd(_LCD_CLEAR);


   while(1)
   {
         bandera1=0;
         adc_value1=ADC_read(0);//TEMPERATURA 1°
         Mv1 = adc_value1*0.488;
         FloatToStr(Mv1,texto1);
         Lcd_out(1,10,texto1);
         Lcd_Out(1,1,"T.IGBT1:");
         Lcd_Chr(1,15,223);
         Lcd_Chr(1,16, 'C');
           if(Mv1 > 0x46 )
           {
           bandera1 = 1;
           }


         adc_value2=ADC_read(1);//TEMPERATURA 2°
         Mv2 = adc_value2*0.488;
         FloatToStr(Mv2,texto2);
         Lcd_out(2,10,texto2);
         Lcd_Out(2,1,"T.IGBT2:");
         Lcd_Chr(2,15,223);
         Lcd_Chr(2,16, 'C');
           if(Mv2 > 0x46 )
           {
           bandera1 = 2;
           }


         delay_ms(2000);
         Lcd_Cmd(_LCD_CLEAR);

         adc_value3=ADC_read(2);//CORRIENTE BATERIA
         Mv3 =((adc_value3-512)*0.0586);
         FloatToStr(Mv3,texto3);
         Lcd_Out(1,7,texto3);
         Lcd_Out(1,1,"I.DC:");
         Lcd_Out(1,14,"AMP ");
          if( Mv3 > 0x0A )
           {
           bandera1 = 3;
           }

         adc_value4=ADC_read(3);//CORRIENTE SALIDA INVERSOR
         Mv4 =((adc_value4-512)*0.0586);
         FloatToStr(Mv4,texto4);
         Lcd_out(2,7,texto4);
         Lcd_Out(2,1,"I.AC:");
         Lcd_Out(2,14, "AMP");
         if( Mv4 > 0x06 )
           {
           bandera1 = 4;
           }

         Delay_ms(2000);
         Lcd_Cmd(_LCD_CLEAR);

         adc_value5=ADC_read(4);//VOLATAJE BATERIA
         Mv5 =((adc_value5*49.0)/1024.0);
         FloatToStr(Mv5,texto5);
         Lcd_Out(1,7,texto5);
         Lcd_Out(1,1,"V.DC:");
         Lcd_Out(1,13, "VOLTS");
         if( Mv5 < 0x18 )
           {
           bandera1 = 5;
           }

         adc_value6=ADC_read(5);//VOLTAJE SALIDA INVERSOR
         Mv6 =(adc_value6*462.9)/1024.0;
         FloatToStr(Mv6,texto6);
         Lcd_Out(2,7,texto6);
         Lcd_Out(2,1,"V.AC:");
         Lcd_Out(2,13, "VOLTS");
          if( Mv5 > 0xD2 )
           {
           bandera1 = 6;
           }

         Delay_ms(1900);
         Lcd_Cmd(_LCD_CLEAR);
         

    
     if( bandera1 > 0 )
    {
      LEDROJO = ON;
      FALLA = ON;
      LEDVERDE = OFF;
    }

    else
    {
       FALLA = OFF;
       LEDROJO = OFF;
       LEDVERDE = ON;
    }
    

   }
}
 
Estimado D@rkbytes, gracias por siempre ayudar.
Te comento que he realizado los cambios y ya todo funciona ok, pero tuve que cambiar los pines del lcd del puerto d al puerto b, por el diseño de la placa y al simularlo ya no me funciona.
He revisado todo y no encuentro nada extraño. ¿Me puedes dar alguna sugerencia?
Revisa bien las conexiones de la pantalla al puerto B, porque no debe existir otro problema.

No has realizado los cambios para usar un solo arreglo en las conversiones.
 
Sabes que e revisado las conexiones del LCD y esta todo bien además ni en el proteus me funciona el lcd! Y respecto a los arreglos, realice los cambios pero no funciona correctamente el programa!
 
No encuentro otra cosa que pueda estar fallando, solo las conexiones.

Te adjunto la simulación que tengo funcionando para que revises las conexiones.
 

Adjuntos

  • 16F877A Inversor.rar
    84.6 KB · Visitas: 6
estimado, debo reconocer que tenia un problema de conexión en el lcd. Bueno ahora todo funciona de maravillas. te agradezco toda tu ayuda. y la buena onda. gracias.
 
Buenas, tengo un problema con un termostato programado en mikrobasic con un 16f887, (tambien lo he probado en mikroC) el codigo lo proporciona mikrobasic en el propio manual con un DS18B20 que va desde los -55º hasta los 128º configurado el DS18B20 a 12bits que da una resolucion de 0.0625º y funciona perfecto.
Pero por mas que trato de activar o desactivar un puerto segun una temperatura determinada, no lo consigo, lo he conseguido a medias porque se produce una activacion tanto en la temperatura positiva como la negativa, es decir, si configuro los grados para que el puerto se desactive a los -5º, tambien se desactiva a los 5º y asi con cualquier condicion y temperatura, si pongo 20º tambien sucede en los -20º
he creado una variable tipo short para trabajar desde los -127º a los 127º llamada grados que es la que decide a que temperatura se activa el puerto que quiero controlar de esta manera

Código:
Dim grados as short

if (temp_whole div grados) >=1
then portd.3=1
else portd.3=0
end if
grados = -5 ' Esta variable es la que determina a que temperatura se activa el puerto 
' y hay que insertarla despues de main:


He probado multitud de condiciones pero no soy capaz de averiguar como activarlo solo en la temperatura que quiero sin que suceda tambien en la temperatura opuesta.
Me podriais echar una mano para solucionarlo?
Tambien me seria de ayuda en Mikroc porque estoy pasando mi olvidada experiencia en pic basic pro a mikroBasic y mikroC
Os proporciono los 2 codigos, tanto en MikroBasic como en MikroC a ver si algunos de los que programais en alguno de los 2 lenguajes me puede echar una mano
Si lo probais con otro PIC, no es ningun problema ya que me es bastante sencillo adaptar un codigo de un determinado PIC a otro tipo de PIC.
Pero donde no soy capaz es en lo que os he explicado, echadme una mano plz.
Thx de antemano.

El codigo en mikrobasic es este:
Código:
' Cabecera******************************************************
program example_12 ' Nombre de programa

dim LCD_RS as sbit at RB4_bit ' Conexiones del módulo LCD
LCD_EN as sbit at RB5_bit
LCD_D4 as sbit at RB0_bit
LCD_D5 as sbit at RB1_bit
LCD_D6 as sbit at RB2_bit
LCD_D7 as sbit at RB3_bit
LCD_RS_Direction as sbit at TRISB4_bit
LCD_EN_Direction as sbit at TRISB5_bit
LCD_D4_Direction as sbit at TRISB0_bit
LCD_D5_Direction as sbit at TRISB1_bit
LCD_D6_Direction as sbit at TRISB2_bit
LCD_D7_Direction as sbit at TRISB3_bit ' Final de conexiones del módulo LCD

' Ajustar la constante TEMP_RESOLUTION a la resolusión correspondiente del sensor: 
' DS18x20 utilizado: 18S20: 9 (ajustes por defecto pueden ser 9,10,11 o 12); 18B20: 12

const TEMP_RESOLUTION as byte = 12 ' Constante TEMP_RESOLUTION es de tipo byte

dim text as char[9]               ' Variable text es de tipo char
temp as word                      ' Variable temp es de tipo word
sub procedure Display_Temperature( dim temp2write as word )
  const RES_SHIFT = TEMP_RESOLUTION - 8
  dim temp_whole as byte          ' Variable temp_whole rd fr tipo byte
  temp_fraction as word           ' Variable temp_fraction es de tipo word
  text = "000.0000"

  if (temp2write and 0x8000) then ' Comprobar si la temperatura es negativa 
    text[0] = "-"
    temp2write = not temp2write + 1
  end if

  temp_whole = word(temp2write >> RES_SHIFT) ' Extraer temp_whole
  
  if ( temp_whole div 100 ) then ' Convertir temp_whole en caracteres
    text[0] = temp_whole div 100 + 48
  else
    text[0] = "0"
  end if

  text[1] = (temp_whole div 10) mod 10 + 48         ' Extraer dígito de decenas
  text[2] = temp_whole mod 10 + 48                  ' Extraer dígito de unidades
  temp_fraction = word(temp2write << (4-RES_SHIFT)) ' Extraer temp_fraction
  temp_fraction = temp_fraction and 0x000F          ' y convertirlo en
  temp_fraction = temp_fraction * 625               ' unsigned int
  text[4] = word(temp_fraction div 1000) + 48       ' Extraer dígito de miles 
  text[5] = word((temp_fraction div 100) mod 10 + 48) ' Extraer dígito de centenas 
  text[6] = word((temp_fraction div 10) mod 10 + 48)  ' Extraer dígito de decenas
  text[7] = word(temp_fraction mod 10) + 48         ' Extraer dígito de unidades
  Lcd_Out(2, 5, text)                               ' Visualizar temperatura en el Lcd

end sub

main:     ' Inicio de programa
ANSEL = 0 ' Configurar pines analógicos como digitales de E/S        
ANSELH = 0

text = "000.0000"
Lcd_Init()               ' Inicializar el Lcd
Lcd_Cmd(_LCD_CLEAR)      ' Borrar el Lcd
Lcd_Cmd(_LCD_CURSOR_OFF) ' Apagar el cursor
Lcd_Out(1, 1, " Temperature: ")

Lcd_Chr(2,13,178) ' Visualizar el carácter de grado, 'C' para centígrados
' Distintos visualizadores LCD tienen diferentes códigos de caracteres para el grado 
Lcd_Chr(2,14,"C") ' si ve la letra griega Alfa, introduzca 178 en vez de 223

while 1 ' Leer la temperatura en el bucle principal
  Ow_Reset(PORTE, 2)       ' Señal de reinicio de Onewire 
  Ow_Write(PORTE, 2, 0xCC) ' Ejecutar el comando SKIP_ROM
  Ow_Write(PORTE, 2, 0x44) ' Ejecutar el comando CONVERT_T
  Delay_us(120)

  Ow_Reset(PORTE, 2)
  Ow_Write(PORTE, 2, 0xCC) ' Ejecutar el comando SKIP_ROM
  Ow_Write(PORTE, 2, 0xBE) ' Ejecutar el comando READ_SCRATCHPAD

  temp = Ow_Read(PORTE, 2)
  temp = (Ow_Read(PORTE, 2) << 8) + temp

  Display_Temperature(temp) ' Formatear y visualizar el resultado en el LCD

  Delay_ms(520)             ' Retardo de 520 ms 
wend
end.                        ' Final de programa

Y en mikroC es este:
Código:
/*Cabecera******************************************************/

// Conexiones del módulo LCD
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// Final de conexiones del módulo LCD

const unsigned short TEMP_RESOLUTION = 12;
char *text = "000.0000";
unsigned temp;

void Display_Temperature(unsigned int temp2write) {
  const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
  char temp_whole;  
  unsigned int temp_fraction;
  
  // comprobar si la temperatura es negativa
  if (temp2write & 0x8000) {
  text[0] = '-';
  temp2write = ~temp2write + 1;
  }
  
  // extraer temp_whole
  temp_whole = temp2write >> RES_SHIFT ;
  
  // convertir temp_whole en caracteres
  if (temp_whole/100)
     text[0] = temp_whole/100 + 48;
  else
    text[0] = '0';
	
  text[1] = (temp_whole/10)%10 + 48;     // Extraer dígito de decenas
  text[2] = temp_whole%10 + 48;          // Extraer dígito de unidades
  
  // extraer temp_fraction y convertirlo en unsigned int
  temp_fraction = temp2write << (4-RES_SHIFT);
  temp_fraction &= 0x000F;
  temp_fraction *= 625;
  
  // convertir temp_fraction en caracteres
  text[4] = temp_fraction/1000 + 48;     // Extraer dígito de miles
  text[5] = (temp_fraction/100)%10 + 48; // Extraer dígito de centenas
  text[6] = (temp_fraction/10)%10 + 48;  // Extraer dígito de decenas
  text[7] = temp_fraction%10 + 48;       // Extraer dígito de unidades
  
  // Visualizar temperatura en el LCD
  Lcd_Out(2, 5, text);
}

void main() {
  ANSEL = 0;                // Configurar los pines AN como digitales
  ANSELH = 0;
  C1ON_bit = 0;             // Deshabilitar los comparadores
  C2ON_bit = 0;
  
  Lcd_Init();               // Inicializar el LCD
  Lcd_Cmd(_LCD_CLEAR);      // Borrar el LCD
  Lcd_Cmd(_LCD_CURSOR_OFF); // Apagar el cursor
  Lcd_Out(1, 1, " Temperatura: ");
  
  // Visualizar el carácter de grado, 'C' para centígrados
  Lcd_Chr(2,13,223); // distintos visualizadores LCD tienen diferentes códigos
  
  // de caracteres para el grado
  // si ve la letra griega Alfa, intente introducir 178 en vez de 223
  Lcd_Chr(2,14,'C');
  
  //--- bucle principal
  do {
    //--- realizar lectura de temperatura
    Ow_Reset(&PORTE, 2);       // Señal de reinicio de Onewire
    Ow_Write(&PORTE, 2, 0xCC); // Ejecutar el comando SKIP_ROM
    Ow_Write(&PORTE, 2, 0x44); // Ejecutar el comando CONVERT_T
    Delay_us(120);
    Ow_Reset(&PORTE, 2);
    Ow_Write(&PORTE, 2, 0xCC); // Ejecutar el comando SKIP_ROM
    Ow_Write(&PORTE, 2, 0xBE); // Ejecutar el comando READ_SCRATCHPAD
    temp = Ow_Read(&PORTE, 2);
    temp = (Ow_Read(&PORTE, 2) << 8) + temp;
	
    //--- Formatear y visualizar el resultado en el LCD
    Display_Temperature(temp);
    Delay_ms(500);
  } while (1);
}
 
Última edición:
Hola, necesito ayuda con mi código.
Mi termómetro controla un dispositivo refrigerador con las siguientes condiciones:
Código:
Si la temperatura es mayor de 15 °C, el duty cycle es del 100%
Si la temperatura es igual o menor de 15 °C, el duty cycle es del 50%

pero al llegar a los 15 °C el valor varía entre los 16 °C y 15 °C, nunca llega a los 14 °C.
¿Cómo podría evitarlo? Lo deseado sería que al llegar a los 15 °C, el duty cycle sea del 50%, pero no varíe.

Este es el código:
Código:
unsigned int valor_adc;
unsigned short unidad, decena, temp, menu;

float  resolucion = 0.0;
float temperatura = 0.0;

const unsigned short digito[] =
{ 0x3F, 0x05, 0x5E, 0x4F, 0x65, 0x6B, 0x7B, 0x0D, 0x7F, 0x6F, 0x78};

bit num, bandera;

void display(void) {
decena = temperatura /10;
unidad = temperatura - (decena *10);
num++;

if(!num) {
PORTB = digito[decena] << 1;
PORTA.f2 = 1;
} 
else {
PORTB = digito[unidad] << 1;
PORTA.f4 = 1;
}
 delay_ms(1);
PORTA.f2 = 0;
PORTA.f4 = 0;
}

void main(void) {
NOT_RBPU_bit = 0;
  INTEDG_bit = 0;

TRISA = 0x09;
TRISB = 0x01;
TRISC = 0x00;

 ANSEL = 0x09;
ANSELH = 0x00;
ADCON0 = 0xC0;
ADCON1 = 0x90;

    PR2 = 0xF9;
  T2CON = 0x05;
CCP2CON = 0x0C;

PORTA = 0;
PORTB = 0;
PORTC = 0;

while(1) {
if(temp > 15) bandera = 0;                            //Aquí están las condiciones
         else bandera = 1;
if(bandera == 0) CCPR2L = 0xFA;
            else CCPR2L = 0x7D;
ADON_bit = 1;
delay_us(20);
  GO_bit = 1;
while(GO_bit == 1);
valor_adc = (ADRESH << 8) + ADRESL;

 resolucion = (2.5/1023) / 0.01;
temperatura = resolucion * valor_adc;
     delay_us(100);
temp = temperatura;

display();
}
}

o sí debo plantearlo de manera diferente, gracias.
 
Última edición:
Hola a todos, tengo un problema hay ejemplos en youtube de como utilizar el NTC pero la mayoria con 10K, hay algunos con 100K pero utilizo las formulas que hay tanto en videos como algunos ejemplos y ninguno me da bien los valores de temperatura, hasta valores negativos tenfo cuando hace unos 28 Grados centigrados.

Alguien tendrá la formula para que pueda utilizar o un fragmento del programa para raspbery PI Pico W que me imagino que es igual a la Pico normal, que pueda utilizar asi mido bien la temperatura.

Ya probe con varios metodos con BETA del termistor sin utilizar eso, pero pareciera que tengo mal las formulas capaz tiene alguien un fragment de programa que esten midiendo con una PI Pico y una NTC de 100k que pueda facilitarme. para poder probar. Por favor. Gracias , Aclaro utilizo MicroPython
 
utilizo las formulas que hay tanto en videos....

Es que no es el método a seguir. Normalmente las hojas de datos te dan la curva característica del sensor, de ahí puedes extrapolar los valores. Sino, multímetro y termómetro en mano, se va modificando la temperatura y se crea la tabla, es tedioso pero solo se hace una vez o, al menos, hasta que se cambia a otro tipo de sensor totalmente distinto.

Hay métodos no tan "lineales" que midiendo dos puntos se traza una recta y se usa como medida, lamentablemente la respuesta es mas una curva pero es una aproximación rápida cuando no se necesita mucha precisión.
 
Atrás
Arriba