LusoRobótica - Robótica em Português

Software => Software e Programação => Tópico iniciado por: DanBar em 06 de Fevereiro de 2010, 23:14

Título: Float to String
Enviado por: DanBar em 06 de Fevereiro de 2010, 23:14
Bem não sei se é cansaço ou burrice minha mas estou com dificuldade em transformar valores float (temperatura) em string.

eu fiz esta função :

Código: [Seleccione]
void floatToStr(char * outstr, float value, int places) {
  dtostrf(value,sizeof(value),places,outstr);
}

mas o que acontece é que os valores ficam arredondados! isto é eu quero que apareca a temperatura no lcd apenas com uma casa decimal e quando faço isso:

Código: [Seleccione]
char StrTemp[20];

lcd.printIn( floatToStr(StrTemp, temperatura, 1) ;
 

no lcd realmente aparece a temperatura com 1 digito, mas o valor dele não é real.

Alguém sabe de outra função que posso transformar Float em String e retirar digitos do float.
 :-\
Título: Re: Float to String
Enviado por: Njay em 06 de Fevereiro de 2010, 23:26
Não conheço a dtostrf(), mas de certeza que é sizoef(value) e não o tamanho de outstr?
Título: Re: Float to String
Enviado por: DanBar em 06 de Fevereiro de 2010, 23:35
Bem deixa-me ver. Eles dizem que é o "width". portanto deve ser o tamanho do valor ? certo.

Citar
The dtostre() function returns the pointer to the converted string s.

char* dtostrf   (   double    __val,
signed char    __width,
unsigned char    __prec,
char *    __s   
)         
The dtostrf() function converts the double value passed in val into an ASCII representationthat will be stored under s. The caller is responsible for providing sufficient storage in s.

Conversion is done in the format "[-]d.ddd". The minimum field width of the output string (including the '.' and the possible sign for negative values) is given in width, and prec determines the number of digits after the decimal sign. width is signed value, negative for left adjustment.

The dtostrf() function returns the pointer to the converted string s.

aprendi aqui: http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html (http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html)
Título: Re: Float to String
Enviado por: DanBar em 07 de Fevereiro de 2010, 00:08
Bem experimentei assim :

Citar
char StrTemp[6]; // 000.00
floatToStr(StrTemp,MaxTempExt,1);
lcd.printIn(StrTemp);


// ****************************************************************************************************
//
// Funcao: floatToStr - Transforma a variavel float em string
// Retorno: nada (guarda numa variavel de array char []
//
// ****************************************************************************************************
void floatToStr(char * outstr, float value, int places) {
  dtostrf(value,sizeof(value),places,outstr);
}

e o resultado foi este:

Citar
Temperatura Ambiente: 21.75 C
MaxTemp:21.75 lcd:21.8
MinTemp:21.75 lcd:21.8

Temperatura Ambiente: 21.69 C
MaxTemp:21.75 lcd:21.8
MinTemp:21.69 lcd:21.7

MaxTemp:21.75 lcd:21.8
MinTemp:21.69 lcd:21.7

MaxTemp:21.75 lcd:21.8
MinTemp:21.69 lcd:21.7

MaxTemp:21.75 lcd:21.8
MinTemp:21.69 lcd:21.7

MaxTemp:21.75 lcd:21.8
MinTemp:21.69 lcd:21.7


A função arredonda a casa decimal, para cima ou para baixo...Acho que posso viver com isto assim para já  ::)
Título: Re: Float to String
Enviado por: TigPT em 07 de Fevereiro de 2010, 01:36
Feito à pressa mas creio que é isto que queres:

Código: [Seleccione]
void floatToStr(char *s, float value, int place, char separator){
*s = "" + (int)value + separator + (int)((value%1)*(10*places));
}

Exemplo de chamada:

Código: [Seleccione]
floatToStr(stringDestino, 10.43324, 1, ",");
//deve de retornar "10,4" mas as horas que são já não prometo nada.
Título: Re: Float to String
Enviado por: DanBar em 07 de Fevereiro de 2010, 02:11
Dá me invalid conversion from 'const char*' to 'char'  :-[

Código: [Seleccione]
char StrTemp[6];

floatToStr(StrTemp, MaxTempExt, 1, ".");

void floatToStr(char * outstr, float value, int place, char separator){
*outstr = "" + (int)value + separator + (int)((value%1)*(10*places));
}
Título: Re: Float to String
Enviado por: TigPT em 07 de Fevereiro de 2010, 02:13
Código: [Seleccione]
floatToStr(stringDestino, 10.43324, 1, ","); está errado, é
Código: [Seleccione]
','
Título: Re: Float to String
Enviado por: DanBar em 07 de Fevereiro de 2010, 02:15
Lol agora dá-me

 invalid operands of types 'float' and 'int' to binary 'operator%
Título: Re: Float to String
Enviado por: TigPT em 07 de Fevereiro de 2010, 02:17
Experimenta isto mas é só para despiste:
Código: [Seleccione]
*outstr = "" + (int)value + separator + (int)((value % 1.0)*(10*places));
Título: Re: Float to String
Enviado por: DanBar em 07 de Fevereiro de 2010, 02:18
dá o mesmo erro
Título: Re: Float to String
Enviado por: TigPT em 07 de Fevereiro de 2010, 02:23
Vai uma martelada mas por agora o que queres é isso a trabalhar...
Código: [Seleccione]
*outstr = "" + (int)value + separator + (int)((value-(int)value)*(10*places));
Ui que até me doi.. o GCC optimiza :P
Título: Re: Float to String
Enviado por: TigPT em 07 de Fevereiro de 2010, 02:24
Não é "places", é "place"
Título: Re: Float to String
Enviado por: DanBar em 07 de Fevereiro de 2010, 02:28
Sim mas dá erro:

Código: [Seleccione]
void floatToStr(char * outstr, float value, int places, char separator){
  *outstr = "" + (int)value + separator + (int)((value-(int)value)*(10*places));
}

 invalid conversion from 'const char*' to 'char'
Título: Re: Float to String
Enviado por: TigPT em 07 de Fevereiro de 2010, 02:30
Tira daqui o pointer:
Código: [Seleccione]
void floatToStr(char * outstr, float value, int places, char separator){
  outstr = "" + (int)value + separator + (int)((value-(int)value)*(10*places));
}
preguicite aguda n me apetece pensar... a ver se me vou deitar.
Título: Re: Float to String
Enviado por: DanBar em 07 de Fevereiro de 2010, 02:31
Como é string posso passar os valor com isto?

strcat(outstr,(int)value);
strcat(outstr,separator);
strcat(outstr,(int)((value-(int)value)*(10*places)));
Título: Re: Float to String
Enviado por: DanBar em 07 de Fevereiro de 2010, 02:32
Já tinha experimentado tirar o pointer, dava erro na mesma
Título: Re: Float to String
Enviado por: DanBar em 07 de Fevereiro de 2010, 02:34
Vai te deitar amigo. Eu resolvo isso depois. Também já não dou uma para a caixa
Título: Re: Float to String
Enviado por: TigPT em 07 de Fevereiro de 2010, 02:42
É que não estou a visualizar as funções de manipulação de strings k o arduino tem incluidas... estou habituado a trabalhar em alto nível... Estava a esquecer-me que tem que ser um código de baixo nível.


Fica aqui só umas ideias para amanhã ver... o meu mal é sono!
Código: [Seleccione]
void floatToStr(char * outstr, float value, int places, char separator){

  outstr = "" + (int)value + separator + (int)((value-(int)value)*(10*places));
}

void rIntToStr(int value, char *str){
if (value == 0) return;
rIntToStr(value/10, str++);
str = value % 10;
}
Título: Re: Float to String
Enviado por: DanBar em 07 de Fevereiro de 2010, 03:01
Este era o meu antigo código :

Código: [Seleccione]
void Lcd_PrintFloat(float Number, byte decimals){
  int frac;
  int rnd;
  char NumStr[20];
  rnd = (unsigned int)(Number*1000)%10;
  frac=(unsigned int)(Number*100)%100;  //get three numbers to the right of the deciaml point.
  if (rnd>=5) frac=frac+1;
    itoa((int)Number,NumStr,10);           // I changed it to 2 decimal places
    strcat(NumStr,".");
    if (frac<10)  {itoa(0,&NumStr[strlen(NumStr)],10); }   // if fract < 10 should print .0 fract ie if fract=6 print .06
    itoa(frac,&NumStr[strlen(NumStr)],10); //put the frac after the deciaml
lcd.printIn(NumStr); 
}

Mas com este código aparece sempre 2 digitos.


Este é o que estou a utilizar agora (foto)

Código: [Seleccione]
void floatToStr(char * outstr, float value, int places) {
  dtostrf(value,sizeof(value),places,outstr);
}
Título: Re: Float to String
Enviado por: Njay em 07 de Fevereiro de 2010, 03:43
Citar
The minimum field width of the output string (including the '.' and the possible sign for negative values) is given in width

Portanto, se queres 2 digitos inteiros positivos mais o ponto mais 1 digito decimal, o valor para width deve ser 4 (caracteres). Só por acaso, sizeof(float) é tipicamente 4.

Citar
and prec determines the number of digits after the decimal sign.

Como só queres 1 digito decimal, _prec deve ser 1.

Esqueçam essas funções "floatToStr", em C não há concatenação de strings suportado de base pela linguagem. "" + ... não existe; bom, na verdade até o podem fazer, se fizerem casts, mas "" representa o ponteiro, o ponteiro para a localização de memória que guarda a string constante "". Mas não é nada do que vocês querem.
Título: Re: Float to String
Enviado por: msr em 07 de Fevereiro de 2010, 13:43
Em geral quando quero fazer conversões ou concatenar uma quantidade de valores numa string uso a função sprintf().
O uso é desta forma: sprintf(str,"%d %f",val1,val2);

Mas não sei se dará para fazer o mesmo no Arduino.
Dá uma vista de olhos neste link: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1200716061 (http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1200716061)
Título: Re: Float to String
Enviado por: DanBar em 07 de Fevereiro de 2010, 22:48
Já funciona:

Código: [Seleccione]
char StrTemp[6];
floatToStr(StrTemp,MaxTempExt,1);

void floatToStr(char * outstr, float value, int places) {
 int f_int;
 int pows_of_ten[4] = {1, 10, 100, 1000};
 int multiplier, whole, fract, d, n;
 char DispString[32];
 char fraction[32];

 multiplier = pows_of_ten[places];
 if (value < 0.0)
 {
   value = -value;
   strcat(outstr,"-");
 }
 whole = (int) value;
 fract = (int) (multiplier * (value - (float)whole));
 itoa(whole,outstr,10);
 strcat(outstr,".");
 for (n=places-1; n>=0; n--) // print each digit with no leading zero suppression
 {
   d = fract / pows_of_ten[n];
   itoa((int)d,&outstr[strlen(outstr)],10);
 }
}

Obrigado pelo link msr  ;)
Título: Re: Float to String
Enviado por: DanBar em 07 de Fevereiro de 2010, 22:51
Resultado:

Citar
Temperatura Ambiente: 21.87 C
MaxTemp:21.87 lcd:21.8
MinTemp:21.87 lcd:21.8

Temperatura Ambiente: 21.94 C
MaxTemp:21.94 lcd:21.9
MinTemp:21.87 lcd:21.8

Temperatura Ambiente: 21.87 C
MaxTemp:21.94 lcd:21.9
MinTemp:21.87 lcd:21.8

MaxTemp:21.94 lcd:21.9
MinTemp:21.87 lcd:21.8

MaxTemp:21.94 lcd:21.9
MinTemp:21.87 lcd:21.8

Temperatura Ambiente: 24.62 C
MaxTemp:24.62 lcd:24.6
MinTemp:21.87 lcd:21.8

Temperatura Ambiente: 23.69 C
MaxTemp:24.62 lcd:24.6
MinTemp:21.87 lcd:21.8
Título: Re: Float to String
Enviado por: TigPT em 07 de Fevereiro de 2010, 22:59
Está a truncar em vez de arredondar... depois com mais calma vejo disso contigo! ;)
Título: Re: Float to String
Enviado por: DanBar em 07 de Fevereiro de 2010, 23:45
Talvez não me tenha explicado bem. Era mesmo isso que eu queria desde o inicio "truncar" e não "aredondar"  ;D

Mas posso sempre decidir depois:

Código: [Seleccione]
void floatToStr(char * outstr, float value, int places, boolean rounds) {
 if (rounds){ // arredondar
    dtostrf(value,sizeof(value),places,outstr);
 } else { // truncar
   int f_int;
   int pows_of_ten[4] = {1, 10, 100, 1000};
   int multiplier, whole, fract, d, n;
   char DispString[32];
   char fraction[32];
   multiplier = pows_of_ten[places];
   if (value < 0.0) {
     value = -value;
     strcat(outstr,"-");
   }
   whole = (int) value;
   fract = (int) (multiplier * (value - (float)whole));
   itoa(whole,outstr,10);
   strcat(outstr,".");
   for (n=places-1; n>=0; n--){ // print each digit with no leading zero suppression
     d = fract / pows_of_ten[n];
     itoa((int)d,&outstr[strlen(outstr)],10);
   }
 }
}