Autor |
|
|
|
BID = 540018
Rambodischien Schreibmaschine
Beiträge: 1341 Wohnort: Österreich
|
|
Hallo ich bin es wieder.
Ich habe eine grundlegende Frage:
Wie schaff ich es aus einem char[] den in einen Doublewert umzuwandeln und wieder zurück.
Ich habe es so probiert:
atof((char*)Text) das müsste der Asciizeichen in einen Doubelwert umrechnen. (Also wenn ich Text = 345 m -> 345).
Nur eine Funktion von einem Doublewert zu Asciizeichen ist mir nichts bekannt.
Ich habe ein wenig recherchiert und bin auf diese Funktion gestossen:
dtostrf(doublewert,5,1,(char*)Zielchar)
Ich habe auch die libm.a eingebunden.
Nur leider kann ich die Daten auf meinem LCD nicht ausgeben. Gibt es vielleicht eine einfachere Funktion?
Was macht überhaupt die libm.a bzw. für was ist die zu gebrauchen?
P.S.: Das ganze ist in C und mit AVR Studio
Danke
_________________
Mfg Rambodischien |
|
BID = 540038
photonic Schreibmaschine
Beiträge: 1301 Wohnort: Zürich, Schweiz
|
|
Die Umwandlung kannst du z.B auch mit sprintf erreichen, besonders geeignet wenn der Wert in einen String eingebettet werden sollte (z.B Einheiten oder Bezeichnungen dazu ausgeben).
|
|
BID = 540045
Rambodischien Schreibmaschine
Beiträge: 1341 Wohnort: Österreich
|
Danke für den Tipp. Leider kriege ich das nicht zum laufen.
Hier einmal der Code:
Code : |
#include "Headerfiles.h"
char *ZText;
char stsi[7];
char dh[3];
uint8_t y=0;
uint8_t x=0;
double aktuellhoehe;
double althoehe=0;
double steigensinken;
uint8_t diffint;
void diffhoehe(char* chhoehe)
{
aktuellhoehe=atof(chhoehe);
steigensinken=aktuellhoehe-althoehe;
sprintf(stsi,"%.1",steigensinken);
althoehe=aktuellhoehe;
ZText=chhoehe; //Übergabe des Textes
lcd_text(0x40);
ZText=(char*)stsi;
lcd_text(0x00);
while((char*)stsi)
{
if(stsi[y]=='.')
{
y++;
}
dh[x]=stsi[y];
y++;
}
summer_hoehe(atoi((char*)dh));
}
|
|
Erklärung: Der Funktion wird ein char* mit folgendem Format gegeben: 245.5 m.
Daraus will ich das Steigen und Sinken auf 1 Kommastelle genau ausgeben.
Für eine weiter Funktion benötige ich aber das Steigen bzw. Sinken als int-Wert z.B.: Sinken: -3.4 -> -34.
_________________
Mfg Rambodischien
|
BID = 540080
photonic Schreibmaschine
Beiträge: 1301 Wohnort: Zürich, Schweiz
|
|
BID = 540362
Rambodischien Schreibmaschine
Beiträge: 1341 Wohnort: Österreich
|
Danke für die Links.
Ich habe es nun versucht mit:
sprintf(stsi,"%.1f",steigensinken);
Aber leider zeigt mein Display alles andere als Zahlen an.
steigensinken ist die Differenz in double der aktuellen GPS-Höhe zur letzten GPS-Höhe.
_________________
Mfg Rambodischien
|
BID = 540432
DonComi Inventar
Beiträge: 8605 Wohnort: Amerika
|
Och nöö,
Wozu den AVR so stark mit dieser bekloppten Library belasten?
Woher kommen die Kommazahlen überhaupt?
Ich habe auch schon mit Kommazahlen gerechnet, in Wirklichkeit habe ich aber einfach nur mit sehr großen Zahlen gerechnet und das Komma so gesetzt... AVRs sind einfach nicht dafür geschaffen, Kommazahlen zu berechnen.
Du darfst nicht vergessen, dass du auf einem sehr begrenzten System programmierst. Auf anderen Plattformen ist das ja eher unkritisch.
_________________
|
BID = 540450
photonic Schreibmaschine
Beiträge: 1301 Wohnort: Zürich, Schweiz
|
Solange der AVR nichts besseres zu tun hat und innerhalb der verfügbaren Ressourcen mit Gleitkommazahlen das tut was man erwartet, warum nicht? Manchmal geht es einfach nicht anders, Ich brauchte z.B mal ein Gleitkomma-Polynom 4. Ordnung um die Nichtlinearität eines Drehspulmessinstrumentes wegzurechnen. Kein Problem für den AVR innerhalb der geforderten Spezifikationen. Sprintf ist leider eine der übelsten Ressourcenschleudern die es für AVRs gibt, da ist Gleitkommarechnen noch harmlos...
Effizientes Programmieren ist natürlich immer eine gute Arbeitsweise, und je nach Projekt absolut unumgänglich. Kommt halt immer auf die Anwendung an, ob man sich einen solchen Programmierstil leisten kann, falls ja habe ich da keine Hemmungen.
Tut das LCD sonst was es soll, wenn du eine einfache Stringkonstante darauf schickst? Also liegt das Problem in der Datenkonversion oder in der Ansteuerung des LCD selbst?
[ Diese Nachricht wurde geändert von: photonic am 9 Aug 2008 1:28 ]
|
BID = 540497
Rambodischien Schreibmaschine
Beiträge: 1341 Wohnort: Österreich
|
Hi
Ich würde gerne soviel wie möglich Ressourcen sparen.
Das LCD gibt ist richtig initialisiert und funktioniert auch.
Das Problem ist die Datenkonversion.
Die Daten kommen von einem GPS-Empfänger im folgendem Format mittels einem Pointer (char*):
z.B.: 234.5 m oder 1234.3 m
_________________
Mfg Rambodischien
|
BID = 540527
DonComi Inventar
Beiträge: 8605 Wohnort: Amerika
|
Hallo Rambodieschen,
Also kommen die Daten als Zeichenekette.
Mit deinem Wissen über Zahlen sollte man doch so eine Routine auch selbst schreiben können, die auch mit double arbeitet, ohne die großen Libs nutzen zu müssen.
Wenn es immer nur eine Nachkommastelle währe, dann wäre die Sache recht einfach. Du würdest kein double sondern einen long int oder noch länger nehmen und einfach das Komma soweit nach rechts verschieben (die Zahl quasi mit 10 multiplizieren), bis das Komma wegfällt.
Mit einem AVR mit Hardwaremultiplizierer gehen Multiplikationen sauschnell.
In Gedanken speicherst du noch die Position des Kommas mit und rechnest mit Ganzzahlen weiter - das ist einfacher für einen AVR, weil er nicht nativ mit Fest- oder Gleitkommazahlen (float) rechnen kann.
Den String nun in einen Int ohne Komma zu bekommen ist ja leicht. Du fängst an einem definierten Punkt an (z.B. am Ende) und errechnest durch Summierung und Multiplikation mit der entsprechenden Wertigkeit die Zahl (235,5 sind 5*10^0 + 5*10^1 + 3*10^2 + 2*10^3 mit der Kommaposition nach dem Eineranteil. Aufs Display schreibst du dann einfach '2''3''5'',''5', auch wenn es als Ganzzahl gespeichert ist
Du kannst auch, um einen eigenen Datentyp zu erzeugen, sowas benutzen:
struct pseudoDouble {
unsigned long int mantisse;
unsigned char kommapos;
};
Damit hast du vom Aufbau schon fast sowas wie einen Gleitkommazahl gebacken. Jetzt noch eine Funktion zum Ausgeben dieser Zahlen, z.B. sowas:
void printpD(struct pseudoDouble *val, void (*toDest)(char *));
(der Funktionszeiger *toDest kann später auf verschiedene Funktionen zur Zeichenausgabe benutzt werden, z.b. terminal_char für Ausgabe per RS232, oder lcd_char für Ausgabe auf Display oder du nimmst anstelle dieses Funktionszeiger einen Zeiger auf einen Puffer, wo du den String reinschreibst. Der Vorteil der Funktionszeiger ist ja eindeutig: ich schreibe die Daten nicht in den Speicher sondern auf andere Geräte, z.B. eben in den RAM des Displays oder in die UART. Damit vergebe ich keinen Puffer im RAM).
Um die Daten aus dem String in den neuen Datentyp zu konvertieren benötigst du noch eine Funktion, die z.B. so aussehen könnte:
stopd(char *string, struct pseudoDouble * output);
Der String wird umgerechnet und in die Struktur output geschrieben.
Dann noch einige Funktionen, die mit diesem Datentypen rechnen können und fertig
(In C++ würde man eine Klasse schreiben, die die Operatoren überladen würde. Man könnte dann "ganz normal" damit rechnen das aber nur nebenbei)
_________________
|
BID = 540716
Rambodischien Schreibmaschine
Beiträge: 1341 Wohnort: Österreich
|
Danke für den Denkanstoß.
Jetzt bin ich gerade dabei ein wenig am probieren und stoße auf ein Problem:
Code : |
#include "Headerfiles.h"
char *ZText;
char stsi[3];
uint8_t y=0;
uint8_t x=0;
int aktuellhoehe;
int althoehe=0;
int steigensinken;
uint8_t diffint;
char Null[]={0x00};
void diffhoehe(char* chhoehe)
{
ZText=chhoehe; //Übergabe des Textes
lcd_text(0x40);
itoa(100,stsi,10);
strcat(stsi,Null);
ZText=(char*)stsi;
lcd_text(0x00);
summer_hoehe(steigensinken);
}
|
|
Wiso zeigt mir das Display immer nur am Anfang 100 danach aber bringt es mir immer nur Schrott heraus.
Woran kann das liegen?
_________________
Mfg Rambodischien
|
BID = 540992
Rambodischien Schreibmaschine
Beiträge: 1341 Wohnort: Österreich
|
Weiß es niemand
_________________
Mfg Rambodischien
|
BID = 541218
Rambodischien Schreibmaschine
Beiträge: 1341 Wohnort: Österreich
|
Habe jetzt die Funktion in einem anderen c-File aufgerufen und siehe da es funktioniert keine Ahnung wieso aber es funktioniert.
Jetzt habe ich noch eine Frage:
Ich habe die Library libm.a mit eingebunden und diese Library schafft es den Speicherverbrauch von 100.2% auf fast 70% zu senken.
Ist das normal, was macht diese Library überhaupt?
Gibt es mehr von der Sorte damit ich noch mehr Speicher zur Verfügung habe?
Danke an DonComi und photonic für die Unterstützung
_________________
Mfg Rambodischien
|
BID = 541892
DonComi Inventar
Beiträge: 8605 Wohnort: Amerika
|
Die libm.a ist eine Bibliothek für mathematische Operationen, Funktionen allgemein etc.
Bestimmte Linkerflaggen können bewirken, dass nicht die ganze Library eingebunden wird, sondern nur die benötigten Resourcen.
Daher könnte dein "Gewinn" an Platz kommen, muss aber nicht.
Da ich ab vor einer Woche nur noch am WE Internet habe, werde ich deinen Quellcode nicht debuggen, jeder Programmierer verbringt mehr Zeit im Debug als beim eigentlichen Programmieren. Auch du wirst es selbst lösen müssen
Ich empfehle dir dringend, mal die Bedienungsanleitung für deine Binutils durchzulesen, also den Compiler, Assembler, Linker etc. Da stehen Sachen drin, von denen du noch nichts gehört hast, die aber ungemein beim Arbeiten helfen.
Aus diesem Grunde habe ich mich schon lange von Programmier-IDEs verabschiedet. Mit shell oder make ist man flexibler.
_________________
[ Diese Nachricht wurde geändert von: DonComi am 15 Aug 2008 16:45 ]
|