PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Temperatur aus Binärwert berechnen



jonas
14.10.2006, 13:32
Hallo zusammen!
Ich will mit einem ATMega8 ein Thermometer bauen. Als Messumformer dient mir eine Messbrücke mit diversen Verstärkerstufen, die mir an den Analogeingang des mega8 eine Spannung von 0 bis 5V liefert. Nun will ich aus dem Binärwert des A/D-Wandlers die Temperatur mit folgenden Formeln berechnen:

Ue=(5/1023)*Binärwert
U2=-((Ue*Re)/Rk-U1)
R1=(R2*Ub)/U2-R2
temp=(R1-R0)/(R0*3,85*10^-3)

Soweit ich weiß kann der Controller keine Kommazahlen berechnen, damit ich aber die Nachkommastellen nicht verliere, habe ich das Komma einfach weiter nach rechts verschoben:

bin=get_adc();
Ue=((5/1023)*bin)*100;
U2=-(((Ue*22662)/1000000)-458);
R1=((100000*500)/U2)-100000;
temp=(R1-10000)/(10000*(385/100000));
temp=temp/100;

Wenn ich alles mit dem Taschenrechner durchtippe, müsste das eigentlich funktionieren, aber leider ist dem nicht so. Vielleicht kann mir jemand sagen, wo mein Fehler liegt? Oder hat jemand eine viel einfachere Lösung für mein Problem?
Ich hoffe mir kann jemand helfen und danke schonmal im voraus![highlight=red:c8a4bbd28a][/highlight:c8a4bbd28a]

PicNick
14.10.2006, 13:43
Ohne Float hast du das erste Problem bei 5/1023, das gibt immer NULL.

Wenn erweitern, muß du ganz vorne anfangen, bei den 5 V. da sollte wenigsten 50000 stehen.

PasstScho
14.10.2006, 15:09
Hallo,
Der Prozessor kann zwar keine floats, aber C hat sie ihm beigebracht.
Du könntest also alles wie gewohnt mit floats machen, nur ist es auf dem Prozessor langsamer als das etwas umständlichere Rechnen mit ints.
Wie PicNick schon sagt, musst du deine Rechnung dementsprechend etwas überdenken.
Ich weiß jetzt nicht, ob das ein Auszug aus deinem code ist, aber imo würde die Rechnung mit ints auch erleichtert werden, wenn du alles in eine Zeile packen würdest.

MfG Alex

ogni42
14.10.2006, 16:42
Da Du eine Temperatur berechnen willst - die sich ja normalerweise nicht soooo schnell ändert - ist es wahrscheinlich am Einfachsten und vom Softwaredesign am Schönsten, wenn Du floats nimmst:



#define U_MAX 5.0
#define ADC_MAX 1023.0

uint16_t adcVal = get_adc();
float inputVoltage = U_MAX*adcVal/ADC_MAX;
// der Rest entsprechend, ohne die ganzen Skalierungen


Kleiner Hinweis am Rande: die beiden defines würde man heutzutage auf einem uC mit viel RAM durch Konstanten ersetzen, aber bei kleinen AVRs spart das auf diese Art etwas RAM.

SprinterSB
15.10.2006, 12:50
Am ehesten angesagt ist wohl die Lösung von PicNick. Man erweitert das ganze Zeug und rechnet mit genzen Zahlen, hier mit 32 Bit.

Als Erweiterungsfaktor bietet sich 65536 (=2^16) an, man rechnet dann also mit 16 Bit vor dem Komma und mit 16 Nachkommastellen.

Mit Ints zu rechnen ist sogar genauer, als mit floats zu rechnen! Denn ein float ist 32 Bit breit, braucht aber noch Bits für den Exponenten. Diese Exponenten-Bits werden in einer 16.16 Fixpnukt-Rechnung nicht gebraucht und tragen zur besseren Genauigkeit bei.

Das Austexten einer Fixpunkt-Rechnung ist natürlcih etwas nerviger. Aber es ist deutlich schneller und spart mächtig Code. Wenn man im Programm sonst keine Floats braucht (sind eigentlich fast immer Overkill), dann kostet die eine float-Zeile von oben mindetsens satte 1400 Bytes Flash. Das sind rund 20% des Flash! Ob man das mit #define oder als const hinschreibt ist übrigens Banane.

ogni42
15.10.2006, 13:06
Wenn Platz genug im Chip ist, nehme ich immer den algorithmisch einfachsten Weg. Getreu den Regeln der Optimierung


Rules of Optimization:
Rule 1: Don't do it.
Rule 2 (for experts only): Don't do it yet.
- M.A. Jackson

"More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity."
- W.A. Wulf

"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil."
- Donald Knuth


Eine dritte Regel möchte ich noch ergänzen:
Rule 3: Think if you really need it.

Wenn Fixpunkt, dann so wie SprinterSB es vorgeschlagen hat: Mit 8 oder 16 bit erweitern. Das erleichtert die Umrechnung erheblich.

jonas
17.10.2006, 17:19
danke erstmal für die vielen antworten!

leider hab ich momentan keine zeit auszuprobieren, obs funktioniert.
ich meld mich dann wieder, wenn ich näheres weiß.