Hallo Leute,
für die Linearisieurung meiner Hallmessdaten möchte ich folgende
Gleichung errechnen:
Xsoll= 1,7692*Xist+555,2;
1) der Compiler nimmt es an, und macht keine errors, aber es wird dem
Xsoll einfach eine "1" zugewiesen,
es heisst er erkennt die Kommazahl etwa nicht!
2) der Offset macht mir schon Verlust meiner Genauigkeit, soll ich den
einfach wegmachen, oder nehme ich ihn auch in die Gleichung?
Danke im Voraus!
Abderrahim wrote:
> Gleichung errechnen:> Xsoll= 1,7692*Xist+555,2;> 1) der Compiler nimmt es an, und macht keine errors, aber es wird dem> Xsoll einfach eine "1" zugewiesen,
Hallo,
die Schreibweise für "Kommazahlen" in C ist Punkt statt Komma, also:
Xsoll= 1.7692*Xist+555.2;
müsste ein brauchbares Ergebnis liefern, wenn Xsoll als float oder
double deklariert ist.
Schöne Grüsse,
dl7avf
ich benutze einen Motorola mit einer 10Bit Auflösung des AD
heisst das ich schreibe einfach die Formel:
Xsoll= ((1.7692*1023)*Xist+(555,2*1023))/1023; ?
Abderrahim wrote:
> Hallo Leute,> für die Linearisieurung meiner Hallmessdaten möchte ich folgende> Gleichung errechnen:> Xsoll= 1,7692*Xist+555,2;> 1) der Compiler nimmt es an, und macht keine errors, aber es wird dem> Xsoll einfach eine "1" zugewiesen,> es heisst er erkennt die Kommazahl etwa nicht!
Mit dem Komma handelst du dir wohl ein Problem ein. Schreibe stattdessen
Xsoll= 1.7692*Xist+555.2;.
Die Tipps der anderen sind natürlich richtig und sauber, aber lösen dein
Problem nur über Umwege.
>Vielleicht hätte auch schon das Ersetzen des Kommas durch einen Punkt>zum erwarteten Ergebnis geführt.
nein, mein Compiler versteht das Komma und kein Punkt als das
Kommazeichen
> nein, mein Compiler versteht das Komma und kein Punkt als das> Kommazeichen
Ist der von Microsoft?
Und selbst da kann ich mir das nicht vorstellen.
Schließlich gibt es einen Sprachstandard für C,
der sicherlich schon älter ist als Du.
(Bitte verzeih die Hetze).
bitte kurz mal auf meinem Code schauen:
val_x = current_value_x;
val_y = current_value_y;
//Gleichchung fuer Linearisierung
Lin_current_value_x = (1,7692*1023)*val_x;
Lin_current_value_y = 1,7692*val_y ;
Es wurde so kompiliert und zum emulator geschickt!
kann jemand dies vielleicht erklären?
Danke für die nette Hilfe!
Aber bitte mit 1024 multiplizieren, das läuft dann auf einen Shift
hinaus.
Man muss einfach sein Denken ein wenig umstellen auf binär.
So wie Benedikt oder so ähnlich würde ich es auch machen.
@Benedikt:
Xsoll= ((1.769265536*65536L)*Xist+(555,2*65536L))/65536L;
Hast Du die Konstante 1.76 vergenauert um 5 Stellen? ;-)
@Abderrahim
Vielleicht könntest Du uns mal verraten, welche Umgebung Du verwendest?
eProfi wrote:
> Aber bitte mit 1024 multiplizieren, das läuft dann auf einen Shift> hinaus.
Wobei das in diesem Fall egal sein dürfte, wenn nur die Konstante damit
multipliziert wird. Denn das optimiert ein guter Compiler und
multipliziert zur Compilezeit.
> @Benedikt:> Xsoll= ((1.769265536*65536L)*Xist+(555,2*65536L))/65536L;> Hast Du die Konstante 1.76 vergenauert um 5 Stellen? ;-)
???
ich benutze einen Freescale CodeWarrior
Wieso soll ich mal 65536 multipl.?
Ich habe bloß eine 10Bit Auflösung keine 16.
Was meinst du mit :
> > Hast Du die Konstante 1.76 vergenauert um 5 Stellen?
habe das probiert:
Lin_current_value_x = (17692*val_x)/10000;
Lin_current_value_x = (word)((1,7692*1000)*val_x)/1000;
bekomme das Gleiche Ergebnis!
Mein "Val_x" ist 407, also der "Lin_current_value_x" sollte auf ungefähr
2 langen, bekomme aber 3 wackelnde Werte: 3..30..54
bin total verwirrt!
Kann jemand helfen?
ist definitiv Käse! Das hat es noch nie im C-Standard gegeben und das
wird es auch nie geben.
Syntaktisch ist das korrekt, das nennt man KOMMAOPERATOR; gerechnet
wird aber anders:
> Poste mal die Deklarationen der Variablen
word current_value_x;
word current_value_y;
word Lin_current_value_x;
word Lin_current_value_y;
word Offset=111;
word val_x;
word val_y;
> => 17692 * 407 = 7'200'644 = (uint16) 57219
was heisst hier (7'200'644)?
> (uint16) (17692*407) / 10000 = (57219/10000) = 5
Leute irgendwie folge ich euch euch nicht mehr,
bin ganz Anfänger im Ding, und da sehe schon solche Komentare:
>Wenn du mit C arbeitest, kannstu dich aufn Kopf stellen:
Das verletzt!
Ja in diese Richtung,
deshalb habe ich ein (word) benutzt:
Lin_current_value_x = (word)((1,7692*1000)*val_x)/1000;
oder soll es anders formuliert sein?
>Swen Pauli hats geschrieben, Kommaoperator.>Ersetz das Komma durch einen Dezimalpunkt,>und Deine Probleme sollten verschwinden...>die Schreibweise für "Kommazahlen" in C ist Punkt statt Komma, also:>Vielleicht hätte auch schon das Ersetzen des Kommas durch einen Punkt>zum erwarteten Ergebnis geführt.>Mit dem Komma handelst du dir wohl ein Problem ein. Schreibe stattdessen>Syntaktisch ist das korrekt, das nennt man KOMMAOPERATOR; gerechnet>wird aber anders:
Abderrahim, wenn das am Komma liegt gibt's Freibier für alle!
Was sagt denn der Compiler, wenn du einen Dezimalpunkt statt eines
Kommas verwendest?
>>Wenn du mit C arbeitest, kannstu dich aufn Kopf stellen:>Das verletzt!
Warum? Das ist wirklich Käse! Entweder dein Code oder dein Compiler.
Du sagst selbst, dass die Materie neu für dich ist - dann folge doch
einfach mal dem Rat der Leute, die das schon was länger machen. Im
schlimmsten Falle irren wir uns alle und haben was gelernt, im besten
Falle funktioniert dein Code und du hast was gelernt.
Gruß
Kai
ps: stell dir den Beitrag weiter oben vor ;) - ihr seid ja schon einen
Schritt weiter
mit der Float nimmt er es auch nicht an!
Leute bin euch wircklich sehr dankbar,
ich melde mich nochmal heute, muß jetzt verlassen,
wünsche euch schöne Nacht und schönen Feiertag !
Also:
1) In den "Kommazahlen" immer "." statt "," schreiben
2) in den Projekteinstellungen/Kompileroptionen schauen, wie man deinem
Compiler beibringt, die nötigen Float-Funktionen mit einzubinden.
Alternativ: die oben vorgeschlagene Fixpunktarithmetik verwenden.
3) Bildformate lesen, und das nächste Mal die Screenshots als PNG
anhängen.
Fertig.
Autor: Matthias Lipinsky (lippy)
Datum: 21.05.2008 20:38
wollte sagen, dass durch das Ergebnis der Multiplikation 17692 * 407 =
7'200'644 nicht in eine word-Variable passt und deswegen nur noch die
16 unteren Bits (uint16) 57219 drinstehen werden.
Das ist einer der häufigsten Fehler beim Programmieren.
Du musst auf (long int) casten oder eine temporäre long int-Variable
für das Ergebnis definieren.
Lin_current_value_x = (long int)(17692*val_x/10000);
oder
Lin_current_value_x = 17692L * val_x / 10000;
Besser, da 10000 für einen µC eine krumme Zahl (0x2710) ist:
unsigned int Lin_current_value_x;
Lin_current_value_x = (1.7692*1024L * val_x + 555.2*1024L) / 1024;
oder
Lin_current_value_x = (1.7692*32768L * val_x + 555.2*32768L) /
32768;
Sobald der Compiler einmal ein L sieht, führt er alle Berechnungen
des Ausdruckes als long aus.
@Benedikt:
Xsoll= ((1.7692*1023)*Xist+(555,2*1023))/1023;
Ja, multiplizieren kann er schon beim Compilen, aber dividieren muss er
zur Runtime.
eins hab ich nicht geachtet, und vielleicht ist das der Grund warum ich
die Fehler bekam,
"val_x" ist eine word-Variable.
Kann sein dass der Compiler keine words mit floats multiplizieren kann?
Hi Thomas,
wie gesagt meine Variablen sollen words oder dwords sein, damit ich sie
später von einer Funktion aufrufen kann:
SetGet(signed_word Xsoll,signed_word Ysoll,dword *R,word *W)
Na schön. Dann verlierst du aber MASSIV an Genauigkeit beim Abspeichern
in ein Ganzzahlformat. Dem kannst du abhelfen, indem du das Ergebnis
aufbläst (heisst: Multiplizieren um mit so vielen Zehnerpotenzen wie
möglich, ohne dass was überläuft) und dieses bei der weiteren Berechnung
berücksichtigst. Wenns ne Spannung ist, kann man das Ergebnis z.B. in mV
statt Volt angeben oder auf was beliebiges andres normieren.
Zum Rechnen mit Ints statt Floats gibts hier auch nen Wikieintrag.