Hallo, mein 24 bit DAC liefert 0,5 VREF 2^23 -1 als "Vollausschlag". Mein Drucksensor liefert eine bestimmte Spannung unterhalb von 0,5 * VREF als Vollausschlag. Jetzt würde ich gerne das Ergebnis (steht in einem int32_t) zur Displayausgabe in die physikalische Einheit umrechen (hier Druck, Pascal). Dabei würde ich gerne auch zwei Kommastellen ausgeben! Wie mache ich das am besten, ohne float benutzen zu müssen? Den Artikel über Festkommaarithmetik habe ich mir durchgelesen, aber nicht ganz verstanden. Der direkte Zusammenhang zwischen physikalischer Größe und DAC Datenregister wäre: druck = dac / 56,1486412316 Danke schonmal für Tips in die richtige Richtung.
Als Tip, wo du noch etwas selber rechnen musst: Den Wert teilen durch 56 ist ja zu ungenau, durch de exakten Wert teilen geht nicht ohne Gleitkommarechnung. Also ein kleiner Umweg: durch 56.1486412316 teilen ist dasselbe wie mit 0.01780987 multiplizieren. Das sieht zwar auch nach Gleitkomma aus, aber man kann ja auch mit 0.1780987 multiplizieren und sich mekren, daß das Ergebnis um 10 zu groß ist, oder mit 1.780987 und sich den Faktor 100 merken, oder mit 17.80987 multiplizieren und 1000 merken... Dein AD-Wert nutzt die 32 Bit ja nicht aus. Also kannst du sehen, wie weit du das obige Spiel treiben kannst, bevor die 32 Bit nicht mehr reichen. Mit der größtmöglichen Zahl multiplizierst du jetzt (ganzzahlig), konvertierst z.B. mit ultoa() in einen String und gibst den aus, allerdings mit einem eingefügten Dezimalpunkt oder Komma an der Stelle, die sich aus dem gemerkten Korrektutfaktor ergibt (z.B. 4. Stelle von hinten bei 10000).
Danke für den Tip. Aber von 24 bit bis 32 bit sind ja nur 8 bit Unterschied, der maximale Faktor also 256. Oder vertue ich mich da? Dann könnte ich maximal mit 178 multiplizieren und dann durch 100 teilen. Wenn ich das richtig sehe, hätte ich dann meine zwei Dezimalstellen, oder? Wenn auch mit einem leichten Rechenfehler.
Ruben schrieb: > Danke für den Tip. Aber von 24 bit bis 32 bit sind ja nur 8 bit > Unterschied, der maximale Faktor also 256. Oder vertue ich mich da? Dann > könnte ich maximal mit 178 multiplizieren und dann durch 100 teilen. Rechnerisch sind das nur 8 Bit, praktisch wette ich, daß du mindestens 16 bit Unterschied nutzen kannst. Die Hardware, die an einem 24-Bit-AD-Wandler auch noch das letzte Bit sinnvoll nutzbar macht, möchte ich sehen. Vermutlich enthalten die unteren 8 bit nur reines Rauschen. Oliver
Ich stelle mir gerade die Anzeige von 24 Bit als Dezimalzahl mit 2 Stellen hinter dem Komma vor: Max Wert : 167 772,15 hPa (sollte Druck sein?) Min Wert : 0,01 MfG Klaus
Ich habe das so verstanden: (2^23-1) / 56,1486412316 Pa = 8388607 / 56,1486412316 Pa = 149400,00 Pa = 1494,0000 hPa Das ist zwar für Luftdruck ein bisschen hoch, aber man braucht ja noch Reserven :-) @Ruben Überleg dir aber mal: - wieviel Volt diese Nachkommstellen haben? - welche Genauigkeit hat der ADC? - wie ist der ADC kalibriert? - wie hoch ist das Rauschen? - welche Genauigkeit hat der Sensor? Die Unsicherheit bei (Spitzen-)Kalibrierlaboratorien liegt bei ca. 0,02 hPa im atmosphärischen Bereich. Du wirst die Nachkommstellen nicht wirklich brauchen.
Nur mal so am Rande, wieso eigentlich bei einem 24-Bit ADC (2^23)-1 und nicht (2^24)-1? Knut
Weil er vorzeichenbehaftet ist. von +(2^23)-1 bis -2^23
@Falk: >Siehe Festkommaarithmetik Ruben: >Den Artikel über Festkommaarithmetik habe ich mir durchgelesen, aber nicht ganz >verstanden. Siehe http://www.mikrocontroller.net/articles/Netiquette
Moin DAC hat einen Bereich von -2,5V bis 2,5V. Mein Sensor liefert aber nur +/- 200mV bei Vollausschlag. Wenn ich den Ausgangswert durch 56 teile, gehen Informationen verloren. Die Nachkommastellen würden schon noch ziemlich stabil bleiben. Mir geht es nicht um absolute Genauigkeit, sondern hauptsächlich um Auflösung. Ich muss den Zeitpunkt und die ungefähre Amplitude von kleinen Drucksprüngen auswerten.
Naja, es ist ganz einfach. Mache ein Beispiel mit 16bit Festkomma-Aritmetik, sollte der Compiler long long beherrschen (multiplication) dann kannst du auch 32.32bit Festkomma-Aritmetik machen. Beispiel dac/adc result = 100 wird dividiert durch 56,1486412316 Hier ist es vereinfacht, man muß auch gegenrechnen, z.B. macht (float)(0xffff)/(unsigned int)(0xffff/56.1486412316) 56.1576692373607540702656389032 und nicht 56.1486412316 hier würde man den Fehler ausbessern, indem man value=value*1167+value>>7 macht, als Beispiel um den Fehler von 0.009028... bei der Division auszubessern. Diese Sachen sind meist Handoptimiert, oder man nimmt einen generelle fixnum lib. Zuerst mal wird die division in eine Multiplication umgewandelt. Hier da 16 bit Fixmath wird 0xffff verwendet. Wegen mycast sowie high/low bin ich mir unsicher ob das so funktioniert, kann mittels union, ... gemacht werden, prinzipiell ist es so aber einfacher zu verstehen. high(value) => (value>>16) -- low(value) ==(value&0xffff) int32_t value; #define mycast(x,type,offset) ((uint[])(unsigned int)&x)[offset] #define high(x) mycast(x,uint16_t,0) #define low(x) mycast(x,uint16_t,1) #define DIV(x) (unsigned int)(0xffff/(x)) value=100; value *= DIV(56.1486412316); printf("%d",high(value)); high(value)=0; if(value) for(printf(",");value;high(value)=0)value*=10,printf("%01d",high(value)) ;
und schon wieder so ein ärgerlicher Fehler, bei mycast(x,type,offset) muss es mycast(x,uint,offset) heissen.
Ruben schrieb: > Moin DAC hat einen Bereich von -2,5V bis 2,5V. Mein Sensor liefert aber > nur +/- 200mV bei Vollausschlag. Wenn ich den Ausgangswert durch 56 > teile, gehen Informationen verloren. Die Nachkommastellen würden schon > noch ziemlich stabil bleiben. Mir geht es nicht um absolute Genauigkeit, > sondern hauptsächlich um Auflösung. Ich muss den Zeitpunkt und die > ungefähre Amplitude von kleinen Drucksprüngen auswerten. Du willst 2 Stellen hinter dem Komma, also (Pseudocode): result = ADCvalue * 100 Da dein ADC-Ergebniss weniger als 20 Bit hat (0,2V von 2,5V), gibts keinen Überlauf. result = result/56 alle anderen digits in deinem Faktor machen weniger aus, als die 2 Stellen hinter dem Komma anzeigen können. dann print result/100 print ',' // oder '.' print result^100 // Modulo MfG Klaus
Klaus schrieb: > result = result/56 Sorry, war zu schnell, ist falsch richtig result = result/*5614*
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.