Forum: Mikrocontroller und Digitale Elektronik ADC Umrechnug


von Marcus (Gast)


Lesenswert?

Hallo alle zusammen,

ich habe eigentlich ein sehr einfaches Problem.
Ich möchte den Spannungswert, der am AD-Eingang liegt, auf nem Display
anzeigen.

Dazu multipliziere ich den Digitalwert mit meiner Referenzspannung und
dividiere durch die Auflösung des AD-Wandlers.

Hier ein Beispiel:

unsigned long int i;
unsigned int k;

Messergebnis = readADC(4, 64) // Einlesen am Kanal 4 und Mittelwert aus
64 Messungen

k = Messergebnis*5/1024; //Vorkommastelle berechnen
i = (Messergebnis*5000/1024)%1000; //Nachkommastelle


Diese beiden Größen will ich auf dem Display ausgeben.
Bei der Vorkommastelle kei Problem, bei der Nachkommastelle kommt nur
Unsinn.
Hat jemand einen Tip für mich? Den Datentyp habe ich ja schon extra bei
i auf long int gesetzt??

Danke vorab

von Detlev (Gast)


Lesenswert?

Ist das Messergebnis auch long int? Wenn nicht, wird die Rechnung
wahrscheinlich nur mit 16 Bit ausgeführt, was um Überlauf führt.
Abhilfe: Eine der Konstanten als long kennzeichnen, z.B 5000UL.

von Marcus (Gast)


Lesenswert?

Das Messergebnis ist nur unsigned int.
Warum kommt es zum Überlauf? Ich speichere doch das Ergebnis in ner
unsigned long int Variable? Die ist doch ausreichend Groß

von Karl H. (kbuchegg)


Lesenswert?

Der Datentyp des Ergebnisses interessiert niemanden.
Entscheiden ist welche Datentypen an der Operation beteiligt
sind. Und das sind nun mal in allen Fällen int (oder unsigned int).
Daher wird die Rechnung selbst auch nur im Zahlenbereich int
(oder unsigned int) durchgeführt. Erst nachdem das Ergebnis
der Berechnung feststeht, wird das Ergebnis (der das was von
ihm übrig ist) nach long konvertiert.

von Karl H. (kbuchegg)


Lesenswert?

> Der Datentyp des Ergebnisses interessiert niemanden.

Sollte besser lauten:
Der Datentyp der Variable, in der du das Ergebnis speicherst,
interessiert niemanden.

von Marcus (Gast)


Lesenswert?

Alles klar, werde das dann gleich mal probieren,

danke vorab.

von Karl H. (kbuchegg)


Lesenswert?

Vergiss nicht, dass du bei der Ausgabe des Nachkommaanteils
entsprechend viele führende Nullen ausgeben musst.
Sonst kommt wieder Unsinn raus.

von Thorsten (Gast)


Lesenswert?

Hallo zusammen,

ich bin jetzt nicht der Experte, aber ließe sich die Geschwindigkeit
der Berechnung nicht folgendermaßen erhöhen?

k = Messergebnis * 5 / 1024

Dieses lässt sich ja umformen zu:

k = (Messergebnis * 4 / 1024) + (Messergebnis / 1024)

Durch kürzen ergibt sich dann doch:

k = (Messergebnis / 256) + (Messergebnis / 1024)

Sowas lässt sich doch in C folgendermaßen realisieren:

k = (Messergebnis >> 8) + (Messergebnis >> 10)

Eine Addition und zwei Shift-Befehle sind doch in der Ausführung
deutlich schneller als eine Multiplikation und eine Division oder ist
in meiner Überlegung ein Denkfehler drin.

von A.K. (Gast)


Lesenswert?

@Throsten: Hast du mal nachgesehen, was der GNU-Compiler aus
"x*5/1024" macht? ;-)

von Thorsten (Gast)


Lesenswert?

@ A.K.:
Stimmt, hast Recht. Hab in meiner Überlegung nicht an den Compiler
gedacht, sondern bin nur von der Programmierung ausgegangen.

von Detlev (Gast)


Lesenswert?

i muss übrgens nicht long int sein, da der Wert nicht größer als 999
sein kann.

Und mein Vorschlag für eine schnellere Berechnung:


unsigned int i;
unsigned int k;

Messergebnis = readADC(4, 64) * 5;

k = Messergebnis /1024; //Vorkommastelle berechnen
Messergebnis -= k * 1024;
i = (Messergebnis*250UL) / 256; //Nachkommastelle


Eine andere Frage ist, ob du die Trennung in Vor- und Nachkommastelle
überhaupt brauchst, wenn du sie danach ohnehin noch (getrennt) in einen
String o.ä. wandeln musst.

i = (readADC(4, 64) * 1250UL) / 256;

würde einen Wert zwischen 0 und 4999 ergeben. Den wandelt man in einem
Aufwasch und 'merkt' sich, dass die erste Stelle die Vorkomma, die
anderen die Nachkommastellen sind. Nur so als Idee.

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.