PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : double -----> string formatieren ..wie?



RIFMAN
25.04.2007, 08:18
hallo zusamen,

wie kann ich ein double zu string umwandeln.
ich versuch zur Zeit ein Programm zu schreiben, das mir eine analoge Spannung misst und auf LCD anzeigt, und das Formatieren ist mein einziges Problem, ich habe es auch mit sprintf probiert klappt aber auch nicht!
ich habe es so gelöst :

#include <avr/io.h>
#include <inttypes.h>
#include <stdio.h>
#include "lcd.h"


void LCD(uint16_t result)

{
char buffer[5];
int t;
int x;

t = result / 1000;
x = result - (t * 1000);
sprintf(buffer,"%d.%d V",t,x);
// itoa(result,buffer,10);
lcd_gotoxy(7,1);
lcd_puts(buffer);

}


uint16_t readADC(uint8_t channel)

{
uint8_t i;
uint16_t result = 0;

ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);// Den ADC aktivieren und Teilungsfaktor auf 64 stellen

ADMUX = channel;// Kanal des Multiplexers waehlen

ADMUX |= (1<<REFS1) | (1<<REFS0);// Interne Referenzspannung verwenden (also 2,56 V)

ADCSRA |= (1<<ADSC); // Den ADC initialisieren..
while(ADCSRA & (1<<ADSC));// und einen sog. Dummyreadout machen

for(i=0; i<3; i++) // Jetzt 3x die analoge Spannung and Kanal channel auslesen
{

ADCSRA |= (1<<ADSC);// Eine Wandlung
while(ADCSRA & (1<<ADSC));// Auf Ergebnis warten...
result += ADCW;
}


ADCSRA &= ~(1<<ADEN);// ADC wieder deaktivieren

result /= 3;// und dann Durchschnittswert ausrechnen.

return result;
}

int main(void)
{
lcd_init(LCD_DISP_ON);
lcd_puts("Die Spannung =");

while(1)
{
uint16_t result = readADC(0); //Auslesen der analogen Spannungen an Pin 0,
result*=2,56/1024;
LCD(result); // also ADC0. In result steht das Ergebnis.
}
return 0;
}




aber irgendwie habe ich das Gefühl, dass es einfacher geht
hat jemand eine Idee.

Danke.

Pascal
25.04.2007, 09:07
Was willst du denn genau machen?
Du fragst, wie man ein double in einen string wandeln kann. Aber du hast in deinem code kein einziges double drinstehen, also kann es doch gar kein Problem damit geben. Außerdem gibts beim avr-gcc meines Wissens nach kein double, sondern nur float.

RIFMAN
25.04.2007, 09:34
Mein Programm daoben war nur eine alternative, und mit float ging es auch nicht.
Danke.

robocat
25.04.2007, 11:09
sprintf(buffer,"floats: %4.2f %+.0e %E \n", 3.1416, 3.1416, 3.1416);

warum sollte das nicht gehen?

hier ist das komma falsch, muss ein punkt sein:

result*=2,56/1024;

du kannst natürlich auch mit der kirch ums dorf:

void LcdDouble(double d)
{
unsigned long i,z,l=d;
char b=0;
if(d==0){printf("0");return;}
else if(d<0){printf("-");l*=-1;}

// ganzzahlanteil
for(i=1000000000;;i/=10)
{
if((z=l/i)>0)b=1;
if(b)printf("%c",'0'+z);
l-=z*i;
if(i==1)break;
}

// nachkommastellen
printf(",");
l=(long)((d-(long)d)*10000000);
for(i=1000000;;i/=10)
{
if((z=l/i)>0)b=1;
if(b)printf("%c",'0'+z);
l-=z*i;
if(i==1)break;
}
}

die funktion hat natürlich ihre grenzen. sehr kleine oder sehr grosse floats werden nicht korrekt dargestellt. ist nur als kleines beispiel zu betrachten.

gruesse

RIFMAN
25.04.2007, 12:36
Danke robocat!

was bedeutet denn

%4.2f %+.0e %E \n", 3.1416, 3.1416, 3.1416

robocat
25.04.2007, 13:25
das %f bedeutet float, double kriegt man mit %lf.

hier (oder mit google "c printf") findet man mehr dazu:
http://home.fhtw-berlin.de/~junghans/cref/FUNCTIONS/format.html

RIFMAN
25.04.2007, 13:34
Danke!

ich habe es entsprechend geändert aber ich bekomme : ? V auf dem LCD angezeigt!

#include <avr/io.h>
#include <inttypes.h>
#include <stdio.h>
#include "lcd.h"


void LCD(int result)

{
char buffer[5];
double d;
//int t;
//int x;

//d = result * (2.56/1024)*10000;
d = result* (2.56/1024);
//t = d / 10000;
//x = d - (t * 10000);
sprintf(buffer,"%4.2lf V",d);
// itoa(result,buffer,10);
lcd_gotoxy(7,1);
lcd_puts(buffer);

}


uint16_t readADC(uint8_t channel)

{
uint8_t i;
uint16_t result = 0;

ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);// Den ADC aktivieren und Teilungsfaktor auf 64 stellen

ADMUX = channel;// Kanal des Multiplexers waehlen

ADMUX |= (1<<REFS1) | (1<<REFS0);// Interne Referenzspannung verwenden (also 2,56 V)

ADCSRA |= (1<<ADSC); // Den ADC initialisieren..
while(ADCSRA & (1<<ADSC));// und einen sog. Dummyreadout machen

for(i=0; i<3; i++) // Jetzt 3x die analoge Spannung and Kanal channel auslesen
{

ADCSRA |= (1<<ADSC);// Eine Wandlung
while(ADCSRA & (1<<ADSC));// Auf Ergebnis warten...
result += ADCW;
}


ADCSRA &= ~(1<<ADEN);// ADC wieder deaktivieren

result /= 3;// und dann Durchschnittswert ausrechnen.

return result;
}

int main(void)
{
int result;

lcd_init(LCD_DISP_ON);
lcd_puts("Die Spannung =");

while(1)
{
result = readADC(0); //Auslesen der analogen Spannungen an Pin 0,
LCD(result); // also ADC0. In result steht das Ergebnis.
}
return 0;
}


was mach ich denn falsch?
MfG

robocat
25.04.2007, 14:17
Pascal sagte ja oben, dass es in avr-gcc kein double gibt (weiss ich etz selber net genau). versuch es mal mit float, also:

...
char buffer[7];
float f = result* (2.56/1024);
sprintf(buffer,"%.2f V",f);
...

buffer würde ich vergrössern auf 7 bytes, weil die längstmögliche ausgabe "2,56 V" ist, also 6 zeichen, und ein \0 setzt sprintf noch hinten dran, damit klar ist, wo der string aufhört.

hofft, dass es nun klappt: die katz

RIFMAN
25.04.2007, 14:36
leider es klappt immer noch nicht!


Pascal sagte ja oben, dass es in avr-gcc kein double gibt (weiss ich etz selber net genau). versuch es mal mit float


doch es gibt schon in avr-gcc den Type double, und das ist mein Beweis;als ich die Variable d als type float definiert habe, habe ich diese Warnung bekommen:
../AD_Wandler.c:19: warning: format '%.2f' expects type 'double', but argument 3 has type 'float'
MfG
Danke!

RIFMAN
26.04.2007, 08:15
kann keiner helfen?

robocat
27.04.2007, 11:32
du wirst wohl ein wenig experimentieren müssen, weil ich im moment keine stdio.h (für sprintf) verwenden kann, wahrscheinlich müsste ich mein studio oder den gcc mal updaten.

- versuch den buffer zu vergrössern
- versuch einen float-wert mit %f oder %lf darzustellen
- das selbe mit einem double-wert
- versuch mal, ob es die funktion ftoa gibt, um einen float in ascii zu wandeln

gruesse