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
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.
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ß
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.
> Der Datentyp des Ergebnisses interessiert niemanden.
Sollte besser lauten:
Der Datentyp der Variable, in der du das Ergebnis speicherst,
interessiert niemanden.
Vergiss nicht, dass du bei der Ausgabe des Nachkommaanteils entsprechend viele führende Nullen ausgeben musst. Sonst kommt wieder Unsinn raus.
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.
@Throsten: Hast du mal nachgesehen, was der GNU-Compiler aus "x*5/1024" macht? ;-)
@ A.K.: Stimmt, hast Recht. Hab in meiner Überlegung nicht an den Compiler gedacht, sondern bin nur von der Programmierung ausgegangen.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.