mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ADC Umrechnug


Autor: Marcus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Detlev (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Marcus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Der Datentyp des Ergebnisses interessiert niemanden.

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

Autor: Marcus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alles klar, werde das dann gleich mal probieren,

danke vorab.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

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

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: A.K. (Gast)
Datum:

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

Autor: Thorsten (Gast)
Datum:

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

Autor: Detlev (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.