Forum: Mikrocontroller und Digitale Elektronik Float-Variablen...


von Christian (Gast)


Lesenswert?

Hallo,

Vor einiger Zeit habe ich mich mit einem Beitrag zum Ablesen von
analogen Signalen an einem Eingange des PIC16F876 an euch gewandt.

Noch mal kurz zur Beschreibung.
An einem LCD soll eine Temperatur, die mit einem AD22100 gemessen und
angezeigt werden. Des weiteren soll zwischen bestimmten Temperaturen
ein Relais, was an einem Ausgang angeschlossen ist, anziehen und eine
Zirkulationspumpe betreiben. Das mal zur Prinzipfunktion.
Kurz, es soll eine Differenzschaltung werden.

Soweit so gut.
Ich habe die gewünschten Ziele FAST erreicht.
Die gemessenen analogen Signalen werden in Ganzahlen von 0-1000
umgewandelt und als solche am LCD angezeigt.
Nun kommt das FAST.
Ich muss jetzt diese Ganzzahlen auch als Temperaturwerte von -50°C bis
100°C umwandeln und sie dann als Vor- und Nachkommazahlen ausgeben.
Leider kann ich mit meinem Compiler "CC5" keine Float Variablen
verarbeiten, oder geht es doch???

Danke für die Hilfe.
Christian

Wenn das ganze fertig und funktionsfähig ist, stelle ich den Bauplan
und das dazugehörige Programm hier zur Verfügung.

von Christian (Gast)


Lesenswert?

Warum kannst Du das nicht mit Integern und Festpunkt-Arithmetik machen?

von Christian (Gast)


Lesenswert?

... wie meinst du das genau Festpunkt-Arithmetik.
ich kann weder negativen noch Kommazahlen bearbeiten...

von Christian (Gast)


Lesenswert?

Na, negative ganze Zahlen wird Dein C-Compiler ja wohl können.

Mit Festpunkt-Arithmetik meine ich folgendes: Rechne mit Ganzzahlen,
denke Dir das Komma an einer bestimmten Stelle und füge es bei der
Ausgabe dann ein. Beispiel: Du brauchst nur eine Nachkommastelle, also
definierst du z.B. 500 als 50.0, 123 wäre dann 12.3 usw. Bei der
Addition und Subtraktion musst Du nichts besonderes beachten
(500+123=623 entspr. 62.3), bei Multiplikation und Division eben auf
die Position des Kommas aufpassen.

von Karl H. (kbuchegg)


Lesenswert?

Christian hat ja schon Vorarbeit geleistet, was es mit
Foxpoint Arithmetik auf sich hat.

Nehmen wir mal an, du möchtest 1 Kommastelle haben
(mehr macht nicht wirklich Sinn).
D.h. -50.0 wird als -500 dargestellt, 100 logischerweise als 1000.
Du brauchst also eine Umrechnung die aus 0 -500 macht, während
1000 als 1000 abgebildet wird.

Wir nehmen mal, dass es einen linearen Zusammenhang gibt.
Das es also eine Formel gibt:  y = k*x + d, sodass wenn du einen
Wert von 0 einsetzt da dann -500 rauskommt, während wenn du für
x 1000 einsetzt für y 1000 rauskommt.

Die Frage ist also: wie gross ist in der linearen Formel das
k und wie gross ist das d.

Das ist nicht weiter schwer zu bestimmen. Denn es muss ja
gelten:

  -500 = k * 0 + d       sowie
  1000 = k * 1000 + d

aus der ersten Gleichung folgt unmittelbar:
    d = -500

In die 2. Gelichung eingesetzt

  1000 = k * 1000 - 500
  1500 = k * 1000
    k = 1500 / 1000

Deine Umrechnung lautet also

    y = 1500 / 1000 * x - 500

x .. dein Wert vom ADC im Bereich 0 .. 1000
y .. der Gradwert in Form von Zehntelgrad ( 1 Kommastelle )

zuerst rechnest du also den Wert um. Um die ganzen Grad zu erhalten
dividierst du durch 10. Die gibst du aus, malst ein Komma dahinter
und nimmst noch die Einerstelle von y dazu (die kriegst du zb. indem
du dir Rest bei der Division durch 10 ausgeben lässt ( y % 10 ).

von Christian (Gast)


Lesenswert?

... also ich habe keine Ahnung was ihr für´n Compiler habt, aber meiner
macht da Problemme...

Habe versucht das was der Karl Heinz vorgeschlagen hat. Funktioniert
hinten und vorne nicht.

Ich schlafe noch ne Nacht drüber und probiere es morgen noch mal und
melde mich dann.

Servus.

von Philipp B. (philipp_burch)


Lesenswert?

Vielleicht solltest du den betreffenden Code mal posten...

von Christian (Gast)


Angehängte Dateien:

Lesenswert?

... na da ist ja doch noch jemand wach.
ich habe mal vorab den Code gepostet. Die überflüssigen Variablen
einfach ignorieren.
Was mir Probleme bereitet ist die Tatsache das kein Modulo funktioniert
und das dass Ergebnis aum Papier ein anderes ist wie das was mir am LCD
angezeigt wird.
Ich habe die Variablen die verwendet werden einzeln ausgegeben, um  da
eine Kontrolle der einzelnen zu haben.

danke.

von Karl H. (kbuchegg)


Lesenswert?

> Habe versucht das was der Karl Heinz vorgeschlagen hat. Funktioniert
> hinten und vorne nicht.

Wie wäre es, wenn du einfach mal C lernen würdest?
Dann müsste man dir nicht alles bis ins letzte vorkauen.

> b=1500/1000

Was denkst du ist das Ergebnis hievon?

Hinweis: 1500 ist ein Integer. 1000 ist ein Integer.
Also wird die Division wie durchgeführt (in welchem
Zahlenraum)?
Was ist daher das Ergebnis?

von Karl H. (kbuchegg)


Lesenswert?

Noch ein Hinweis:
Da du keine float zur Verfügung hast, wirst du
dein Ausdruck

    1500 / 1000 * x

wahrscheinlich nicht so berechnen können dass du
zuerst 1500 / 1000 ausrechnest.

Du könntest aber eine alte Regel beherzigen, die da lautet:
Schiebe Divisionen in deiner Formel so weit nach rechts wie
es geht:

    1500 * x / 1000

macht methematisch dasseble. Im Rechner, beim arbeiten im
int  Raum macht das aber einen gewaltigen Unterschied.

Ein Unterschied ist zb. der dass bei einem x Wert von 1000
de Multiplikation 1500 * 1000 einen Wert von 1500000 ergibt,
der klarerweise ausserhalb des für int (bei 16 Bit) erlaubten
Bereiches von -32768 bis +32767 liegt. Das ist Gott sei
Dank in diesem Fall, mit den konkreten Zahlen noch kein Problem,
denn 1500 und 1000 kann man wunderbar so zurecht kürzen, so dass
das alles passt.

von Karl H. (kbuchegg)


Lesenswert?

Und noch ein Hinweis:

Wenn du negative Zahlen erwartest, dann wird es wohl nicht so schlau
sein, alle Variablen als unsigned zu definieren.

von Christian (Gast)


Lesenswert?

Hallo Karl Heinz.

Es ist verständlich dass man manchmal keine Lust hat sich mit
belanglosen, langweilligen und lästigen Beiträge herum schlagen
möchte.
Trotzdem gibt es Leute die nicht auf eurem Niveau sind und scheinbar
einige Schwierigkeiten beim Lösen mancher Probleme haben.
Deshalb wenden sie sich an Foren um ihren kleinen oder auch grösseren
Projekten in Zusammenarbeit mit anderen Teilnehmern zu lösen.

> Wie wäre es, wenn du einfach mal C lernen würdest?
> Dann müsste man dir nicht alles bis ins letzte vorkauen.
> Was denkst du ist das Ergebnis hiervon?

Ich erwarte nicht dass man mir alles bis ins letzte vorkaut. Auch weiss
ich dass mein Wissenstand bez. der C-Programmierung nicht besonders gut
ist. Aus diesem Grund habe ich meinen Beitrag bei euch gestellt.
Erwartet wird, dass die Leute die etwas konstruktives zum Lösen von
Problemen beitragen möchten, es auch direkt tun und nicht Kritik am den
Beitragstellen ausüben.  Es wäre einfacher lieber nichts zu schreiben.
Dies bringt nur Unbeliebtheit bezüglich Foren und Ihre Mitgliedern.
Macht nicht den Fehler über Kritik an anderen, euren Stand in der
Kompetenz dieses Forums kaputt zu machen.

------------------------------------------------------------------------ 
-

So und jetzt möchte ich noch ein mal kurz mein Problem darstellen, denn
anscheinen ist es noch nicht ganz verstanden worden.

Den Vorschlag mit der Gleichung habe ich angenommen und es auch
eingebaut.
Leider mag mein Compiler keine Gleichungen mit mehreren Faktoren ausser
zwei. So dass ich es aufteilen musste. Nicht weiter schlimm.

> Was denkst du ist das Ergebnis hievon?

1 ist die Lösung, weil das Int-Variablen sind, aber darum geht es gar
nicht.
Viel mehr habe ich Probleme mit der Division und dem Modulo bei
Int-Werten. Klar es werden ständig Floats geliefert mit denen der
Int-Datentyp nicht umgehen kann.
Deshalb habe ich auch den "uns16" Datentypen verwendet um einiges
auszuschliessen.

Also, welche Möglichkeiten gibt es in diesem Fall int-Werte in Floats
so umzuwandeln dass man mit ihnen sinnvoll rechnen kann?

Danke.

von Karl heinz B. (kbucheg)


Lesenswert?

> Es ist verständlich dass man manchmal keine Lust hat sich mit
> belanglosen, langweilligen und lästigen Beiträge herum schlagen
> möchte.

Das ist überhaupt kein Problem. Unzählige Beiträge und
Anleitungen in diesem Forum beweisen das Gegenteil.

Aber wenn du mir unterstellst, dass das, was ich von mir
gebe <Zitat>
> Funktioniert hinten und vorne nicht.
</Zitat>
und selbst läppische Fehler machst, darfst du dich nicht
wundern wenn ich pampig werde.

von Karl heinz B. (kbucheg)


Lesenswert?

> Leider mag mein Compiler keine Gleichungen
Das ist bitter. Macht aber weiter nichts, mann kann die Formel
auch auf etappen implementieren. Nur halt mit der Division
zum Schluss.

> 1 ist die Lösung, weil das Int-Variablen sind, aber darum geht es
> gar nicht.

Doch. Genau darum geht es wenn deine Ergebnisse nicht stimmen.

> Viel mehr habe ich Probleme mit der Division und dem Modulo bei
> Int-Werten.

Dann solltest du das mal präzisieren. Ev. mal konkrete Werte
benennen, durchdividieren und das Ergebnis posten. Aber ehrlich:
Ich kann mir nicht vorstellen, dass dein Compiler Code für
eine Division bzw. Modulo nicht hinkriegt. So ein Compiler wäre
in der Tat praktisch unbrauchbar.

> Also, welche Möglichkeiten gibt es in diesem Fall int-Werte in
> Floats so umzuwandeln dass man mit ihnen sinnvoll rechnen kann?

Es gibt nur die Möglichkeit Gleitkommaarithmetik durch
Fixkommaarithmetik zu ersetzen. Wie bereits weiter oben
gezeigt.

von Wolfram (Gast)


Lesenswert?

>Erwartet wird, dass die Leute die etwas konstruktives zum Lösen von
>Problemen beitragen möchten, es auch direkt tun und nicht Kritik am
den
>Beitragstellen ausüben.
Da war jemand sehr konstruktiv zu dir, du scheinst es aber nicht zu
merken oder zu verstehen. Tut mir leid aber wenn man in dein Program
reinschaut, dann kann man dir nur ans Herz legen ein C- Buch zu lesen.
Das ist keine Kritik, sondern ein konstruktiver Vorschlag den du
verstehen wirst, wenn du dir nach dem Buchstudium nochmal dein Programm
anschaust.
-----------------------------------------------
>Also, welche Möglichkeiten gibt es in diesem Fall int-Werte in Floats
>so umzuwandeln dass man mit ihnen sinnvoll rechnen kann?
mal probieren es anders zu erklären:
dein Problem ist du willst/kannst nicht mit floats arbeiten.
Bevor du den Taschenrechner benutzt hast, must du irgendwann in der
Schule mal Bruchrechnung gehabt haben. Exakt das tust du hier.
Bruchrechnung hat den Vorteil das man über und unter dem Bruchstrich
ganze Zahlen hat und keine Kommazahlen. Du denkst dir jetzt an jede
Zahl mit der du arbeitest einen festen Nenner(Zahl unter Bruchstrich)
angehängt. Willst du nun mit einer Nachkommastelle arbeiten wäre dieser
Nenner 10. Für die ganze math. Operationen gilt das was du in der Schule
zu Bruchrechnung gelernt hast. Eins musst du noch in deinen Brechnungen
beachten: Es kann nirgends eine Kommazahl entstehen, wenn du also die
Operationsreihenfolge ungünstig wählst hast du Verluste.

von Christian (nicht der OP) (Gast)


Lesenswert?

@Christian, der die Frage gestellt hat:

Du schreibst ständig, Dein Compiler könne dies nicht und könne das
nicht. Keine Floats, keine negativen Zahlen, keine Statements mit mehr
als einem Operator. Nun kenne ich den CC5X nicht, aber ich kann mir das
alles nicht vorstellen. Welche Fehlermeldung gibt's denn z.B. bei
"y=1500 * x / 1000;"? Oder ist es ein Fall von PEBKAC?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.