Autor Tema: mikroC presentación de datos en coma flotante.  (Leído 2725 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado Pablolbap

  • PIC10
  • *
  • Mensajes: 37
mikroC presentación de datos en coma flotante.
« en: 19 de Abril de 2015, 23:01:13 »
Estoy usando la librería FloatToStr y me presenta en pantalla el float convertido a string correctamente, pero en notación científica; por ejemplo: 499.xxxxe-2 y lo necesito mostrar como 4.99xxxx simplemente, sin la potencia de 10.
Agradecería mucho cualquier ayuda. Si es necesario subo el código, aunque creo que se entiende el problema.
Saludos cordiales a todos.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: mikroC presentación de datos en coma flotante.
« Respuesta #1 en: 19 de Abril de 2015, 23:55:02 »
Creo que la unica forma es quitandole los demas numeros al float, siguiendo el ejemplo de mikro c:

Código: C
  1. float ff1 = -374.2;
  2. float ff2 = 123.456789;
  3. float ff3 = 0.000001234;
  4. char txt[15];
  5. ...
  6. FloatToStr(ff1, txt);  // txt is "-374.2"
  7. FloatToStr(ff2, txt);  // txt is "123.4567"
  8. FloatToStr(ff3, txt);  // txt is "1.234e-6"


Veo 2 soluciones posibles a mi parecer

  • Trabajar con el numero:


Para que quede se podria truncar a solo 2 espacios despues de la coma.

Código: C
  1. FloatToStr((int)(100 * ff2)) / 100.0),txt);

Entonces ff2 seria primero multiplicado por 100 y guardado como entero quedando 12345 y luego dividido por 100.0 para ser nuevamente flotante. 123.45

  • La otra seria trabajar con string:


En ves de usar la funcion FloatToStr usar la funcion sprintf() de stdio.h

Código: C
  1. sprintf(txt,"%4.2f",ff2);

Son las que se me ocurren, no se que tal funcionaran.
« Última modificación: 20 de Abril de 2015, 02:58:19 por KILLERJC »

Desconectado Pablolbap

  • PIC10
  • *
  • Mensajes: 37
Re: mikroC presentación de datos en coma flotante.
« Respuesta #2 en: 20 de Abril de 2015, 11:20:56 »
Muy agradecido por contestar KILLERJC, me parecen buenas ideas las probaré y luego comento.
Nuevamente gracias por la atención y saludos cordiales a todos. :)

Desconectado Pablolbap

  • PIC10
  • *
  • Mensajes: 37
Re: mikroC presentación de datos en coma flotante.
« Respuesta #3 en: 22 de Abril de 2015, 23:59:49 »
Estoy haciendo un voltímetro autorango con el ADC del PIC16F88 en mikroC.
En realidad, si pruebo cada escala separadamente no me da ningún problema.
Es cuando quiero trabajar con todas las escalas de manera automática cuando me da ese problema;
 que realmente no es grave sino inconveniente el tipo de presentación en potencias de 10, como en notación científica.
Internamente son tres escalas: de 0 a 5V, de 0 a 50V y de 0 a 500V.
Así que agradezco su atención y si alguien tiene alguna sugerencia, será muy bienvenida.
Saludos cordiales a todos.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: mikroC presentación de datos en coma flotante.
« Respuesta #4 en: 23 de Abril de 2015, 01:06:21 »
Para entender como hacerlo debes saber un autorango como funciona. Comenzando por el rango mas pequeño y si se llega al maximo, pasa al otro rango mas arriba y vuelve a efectuar la conversion, si nuevamente es maximo el valor , vuelve a hacerlo.

Si tuvieras 3 entradas con 0 a 5V , 0 a 50V , 0 a 500V.

Mediria primero la de 0 a 5V si es un valor aceptable lo muestro, si esta en el maximo omitiria esa lectura y mediria de 0 a 50V, si me da un valor que no es el maximo entonces muestro, sino paso al otro rango y muestro finalmente el otro.
Deberias tener protecciones que hagan que no se pueda superar esos 5V en los pines.

Desconectado Pablolbap

  • PIC10
  • *
  • Mensajes: 37
Re: mikroC presentación de datos en coma flotante.
« Respuesta #5 en: 23 de Abril de 2015, 15:51:24 »
Gracias KILLERJC por la idea. Yo comenzaba por la escala más alta (0~500V) hasta llegar a la más baja (0~5V).
Éste es un copy/paste de un ejemplo de un libro. En el libro lo hace con una sola escala de 0~15V: el divisor de tensión está formado por dos resistencias, una de 20K y la otra de 10K que es la que va a tierra.
Ya lo había logrado hacer funcionar bien para las tres escalas, con el único inconveniente que para las escalas bajas me lo mostraba en notación científica. Pero de tanto quererlo modificar y no lo guardé, ahora veo que la única escala que funciona es la más alta. Para los switchs anlógicos uso el IC DG417 que conmuta los diferentes valores del divisor de acuerdo a la escala:
//AD_1.c
// Lcd pinout settings for LCD connection.
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D4 at RB0_bit;
// Pin direction.
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D7_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB0_bit;
 //Fin de la configuración de los puertos.
int temp_res;
float voltaje;
char txt[15];
void main(){
OSCCON=0x40; // Oscilador interno a 1Mhz (TCI=4uS).
while (OSCCON.IOFS==0);  //Esperar mientras el oscilador se estabiliza.
PORTA=0x00;              //Inicialización.
ANSEL=0x04;              //Bit AN2 como entrada analógica.
TRISA=0x04;              //RA2 entrada; R4, R3 y R1 salidas.
RA1_bit=1;
RA3_bit=1;
RA4_bit=0;
RA5_bit=1;

Lcd_Init();              //Inicializa el LCD.
Lcd_Cmd(_LCD_CLEAR);     //Borra el display.
Lcd_Cmd(_LCD_CURSOR_OFF);//Apaga el cursor.
Lcd_Out(1,2, "VDCM 500V máx");
Lcd_Out(2,15, "V");
do {
   temp_res=ADC_Read(2);        //Obtiene 10 bits de la conversión del canal 2.
   voltaje=(float)(temp_res*0.0048828125); // Lo convierte en voltaje de 0 a 5V.
   if (voltaje>5.0){            //Si voltaje real es mayor que 500V,
       Lcd_Cmd(_LCD_CLEAR);     //Borra el display.
       Lcd_Cmd(_LCD_CURSOR_OFF);//Apaga el cursor.
       Lcd_Out(1,5, "WARNING!"); //envía mensaje de alarma.
       Delay_ms(500);   }
   else if (voltaje>0.5)       //Si voltaje real es mayor que 50V,
       voltaje*=100.0;          //voltaje de 0 a 5V lo convierte a voltaje real.
       else if (voltaje>0.05) { //Si voltaje real es mayor que 5V,
           RA4_bit=1;           //desconecta switchs de escala 0 a 500V,
           RA3_bit=0; }         //conecta    switchs de escala 0 a 50V.
           else if(voltaje>0.5) //Si voltaje real es mayor que 5V,
               voltaje*=10.0;   //voltaje de 0 a 5V lo convierte a voltaje real.
               else {           //Si no:
                   RA4_bit=1;   //Desconecta switch de escala 0 a 500V,
                   RA3_bit=1;   //desconecta switch de escala 0 a 50V,
                   RA1_bit=0; } // y conecta switch de escala 0 a 5V.
                   voltaje*=1.0;
   FloatToStr(voltaje,txt);     //Convierte a voltaje real.
   Lcd_Out(2,2, txt);
   } while(1);
}
                        Cualquier observación se agradece. Saludos.

Desconectado Pablolbap

  • PIC10
  • *
  • Mensajes: 37
Re: mikroC presentación de datos en coma flotante.
« Respuesta #6 en: 01 de Mayo de 2015, 22:49:43 »
Ya me funciona bien, excepto cerca de cero:
/*Voltímetro digital con ADC del PIC16F88 de tres escalas: 0~5V, 0~50V y 0~500V.
  Utilizo el IC DG417 como switch analógico para el cambio de escalas. */
// Lcd pinout settings for LCD connection.
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D4 at RB0_bit;
// Pin direction.
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D7_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB0_bit;
 //Fin de la configuración de los puertos.
int temp_res;       //Para guardar ADC_Read(2) temporalmente.
float voltaje;      //Para guardar el voltaje medido.
char txt[15];       //Para la conversión a formato texto.
void main(){
OSCCON=0x40;             // Oscilador interno a 1Mhz (TCI=4uS).
while (OSCCON.IOFS==0);  //Esperar mientras el oscilador se estabiliza.
PORTA=0x00;              //Inicialización.
ANSEL=0x04;              //Bit AN2 como entrada analógica.
TRISA=0x04;              //RA2 entrada; R4, R3 y R1 salidas.
Lcd_Init();                      //Inicializa el LCD.
Lcd_Cmd(_LCD_CLEAR);             //Borra el display.
Lcd_Cmd(_LCD_CURSOR_OFF);        //Apaga el cursor.
Lcd_Out(1,2, "VDCM 500V máx");   //Presenta leyenda fija.
Lcd_Out(2,15, "V");
do {
RA1_bit=1;                       //Inicializa switch escala 0~5V apagado.
RA3_bit=1;                       //Inicializa switch escala 0~50V apagado.
RA4_bit=0;                       //Inicializa switch 0~500V encendido.
   temp_res=ADC_Read(2);         //Obtiene 10 bits de la conversión del canal 2.
   if (temp_res>102)             //Si voltaje real es mayor que 50V,
        voltaje=(float)(temp_res*0.488); // Lo convierte en voltaje de 0 a 500V.
   else {                        //Si no:
        RA4_bit=1;                    //Desconecta switch de escala 0 a 500V.
        RA3_bit=0;                    //Conecta switch de escala 0 a 50V,
        temp_res=ADC_Read(2);         //Obtiene 10 bits de la conversión del canal 2.
        if (temp_res>10)                       //Si voltaje real es mayor que 5V,
           voltaje=(float)(temp_res*0.0488);   //Lo convierte en voltaje de 0 a 50V.
        else {                                 //Si no:
             RA3_bit=1;                        //Desconecta switch de escala 0 a 50V.
             RA1_bit=0;                        //Conecta switch de escala 0 a 5V.
             temp_res=ADC_Read(2);             //Obtiene 10 bits de la conversión del canal 2.
             voltaje=(float)(temp_res*0.00488);}}// Lo convierte en voltaje de 0 a 5V.
   FloatToStr(voltaje,txt);     //Convierte voltaje a string.
   Lcd_Out(2,2, txt);           //Presenta lectura de voltaje real.
   } while(1);                  //Lazo sinfín.
}
      Saludos cordiales y gracias por la atención.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: mikroC presentación de datos en coma flotante.
« Respuesta #7 en: 02 de Mayo de 2015, 00:21:41 »
Bueno al menos lo hiciste funcionar, tal ves cerca de 0V hay varias caidas de tension o necesites mas tiempo de sampleo por las resistencias que hay