www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Berechnung mit ADC-wert mißlingt


Autor: Mathias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich hoffe jemand kann mir helfen.
Ich verwende den ADC eines Atmega32 um eine Stromstärke (4-20mA) über 
einen Widerstand zumessen. (Imax = 20mA, mit R=250 Ohm --> Vmax=5V; ARef 
= AVCC)
Die ADC-Messung klappt schon, auch die Ausgabe auf einer 
7-Segmentanzeige.

nun möcht ich den eingelesen ADC-Wert noch umrechnen. 4mA ensprechen 
0kg; 20mA entsprechen 1000kg. Der Bereich dazwischen ist linear.
Daher habe ich folgende Formel entwickelt, um das Offset auszugleichen:

u32 ADU; //Mittelwert von 4 ADC-Wandlungen
u32 kg;
kg = ((1000/8184)*(ADU*10-2046)); //Faktor 10, damit ich nicht mit 818,4 
und 204,6 rechnen muss

Wenn ich nun das Programm durch den AVR Simulator jage, stimmt der Wert 
in ADU, aber "kg" bleibt immer 0 ...

Woran kann das liegen?

Vielen Dank schonmal für eure Hilfe

Mathias

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mathias schrieb:

> Woran kann das liegen?

Daran, dass 1000/8184 null ist.

Autor: Urgs (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das glaube ich nicht. Dann wäre ja die ganze Herleitung Formel, 
einschliess der AD-Werte für 0 und 20kg bzw. 4mA und 20mA falsch?

Uuups. Da gab es ja garkeine Herleitung.

Aber abgesehen davon ist 1000/8184 doch 
0,12218963831867057673509286412512 .

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Urgs schrieb:

> Aber abgesehen davon ist 1000/8184 doch
> 0,12218963831867057673509286412512 .

Es ist eine Integer-Berechnung, und damit ist 1000/8184 = 0.
Oder war das jetzt irgendwie ironisch von dir gemeint?

Autor: Urgs (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Oder war das jetzt irgendwie ironisch von dir gemeint?

War die Frage jetzt irgendwie ironisch von dir gemeint?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> 0,12218963831867057673509286412512 .
> Oder war das jetzt irgendwie ironisch von dir gemeint?
bis 0,12218963831867 wäre es noch als normale, durchaus übliche Antwort 
durchgegangen.
Ab 057673509286412512 wirds dann ironisch  ;-)

> kg = ((1000/8184)*(ADU*10-2046));
Besser so:
kg = ((1000*ADU*10-2046000)/8184);

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

Bewertung
0 lesenswert
nicht lesenswert
Urgs schrieb:
> Das glaube ich nicht.

Solltest du aber

> Dann wäre ja die ganze Herleitung Formel,

Herleitung und Formel sind Mathematik.
Es ist ein Fehler zu glauben, dass Arithmetik in einem Computer exakt 
gleich funktioniert wie in der Mathematik. In Mathe gibt es keine 
Datentypen, in C aber schon. Und der Compiler benutzt die Datentypen der 
beteiligten Operanden um zu entscheiden, wie eine Operation durchgeführt 
wird.

Bei dir ist alles int. Daher wird auch int gerechnet.
So wie in der Grundschule:  17 Äpfel durch 3 Kinder macht 5 Äpfel pro 
Kind und 2 bleiben Rest

1000 durch 8184 macht 0 mal und 1000 bleiben Rest

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey,

hast du deine Variable in deinem Programm richtig initalisiert?
Mit int oder uint_8 ....

Vielleicht liegt es daran

Autor: chridre (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
int kennt nur ganze Zahlen und keine fließkomma ;)
also wenn du eine Rechnung hast bei der irgend was raus kommt wie
0,9018239083
so wird alles hinter dem Komma abgeschnitten.

Deklariere deine Variable als float oder double. Dann klappt es auch mit 
Kommazahlen.

mfg
chridre

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Deklariere deine Variable als float oder double.
Ja, klar. Und dann wundere dich, warum das Flash voll ist und das 
Berechnen solange dauert...

Autor: Urgs (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Karl heinz Buchegger

Noch mehr Ironie?
Dafür wäre es ein bischen lang.

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

Bewertung
0 lesenswert
nicht lesenswert
Urgs schrieb:
> @ Karl heinz Buchegger
>
> Noch mehr Ironie?

Die Ironie besteht darin, dass du von C keine Ahnung hast, dich hier 
aber als der große Macker aufspielst.

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

Bewertung
0 lesenswert
nicht lesenswert
chridre schrieb:

> Deklariere deine Variable als float oder double. Dann klappt es auch mit
> Kommazahlen.

Mann kann aber auch Gehirnschmalz anstelle von Testosteron einsetzen :-)

Gleichungen kann man umstellen.
Oft kann man sie so umstellen, dass die potentiell gefährlichen 
Operationen wie Division, bei denen etwas verlorengeht (nämlich die 
Nachkommastellen), erst ganz zum Schluss ausgeführt werden. Bin ich 
sowieso nur am ganzzahligen Ergebnis interessiert, so habe ich gegenüber 
der float/double Variante meistens keinen Nachteil, habe aber den 
Vorteil dass die Berechnung 30 mal so schnell durchrechnet und 40 mal 
weniger Flash belegt.

Autor: Urgs (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Karl Heinz

Nun mal langsam mit den jungen Pferden.

Ich glaube Du hast mich falsch verstanden.

Du wirst mir in letzter Zeit unsympathisch.

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

Bewertung
0 lesenswert
nicht lesenswert
Urgs schrieb:
> @ Karl Heinz
> Ich glaube Du hast mich falsch verstanden.

Dann drück dich normal aus, dann gibt es auch keine Missverständnisse.

> Du wirst mir in letzter Zeit unsympathisch.
Auch recht.

Autor: Urgs (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auch recht.

Autor: Mathias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, an alle, dir mir die Augen geöffnet haben, besonders an Lothar. 
Funktioniert nun (zumindest im Simulator), wie gewollt...

P.S.. Ich wollte hier keinen Streit auslösen ;(

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: eProfi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> u32 ADU; //Mittelwert von 4 ADC-Wandlungen
u32 ist überflüssig (wenn der ADC-Wert rechtsbündig ausgegeben wird).

u16 ADCsum;  /Summe von 4 Wandlungen  (können auch mehr (8..64) sein)
u16 kg;

Wenn Du statt des Mittelwertes  die Summe  von 4 Wandlungen verwendest 
und das in der nachfolgenden Berechnung berücksichtigst, hast Du weniger 
zu rechnen und mehr Genauigkeit.

Ich würde auch nicht dividieren, sondern mit dem Kehrwert 
multiplizieren, geht viel schneller.

Eigentlich müsste man auch noch aufrunden:

//bei Summe von 4 Wandlungen
#define ADCsummeVon4mA (4*1024/5) //819,2
#define Aufrunden (32768/20024) //1
kg = (ADCsumme + Aufrunden - ADCsummeVon4mA) * 20024UL / 65536UL;
Probe:
4*1023 muss 1000 ergeben:
(4*1023 +1 -819)*20024/65536=1000,3445


//bei Summe von 16 Wandlungen
#define ADCsummeVon4mA (1+16*1024/5) //3276,8 --> 3277
#define Aufrunden (32768/5005) //6
kg = (ADCsumme + Aufrunden - ADCsummeVon4mA) * 5005UL / 65536UL;
Probe:
(16*1023+ 6-3277)*5005/65536=1000,2210



Genaugenommen müsste man so rechnen:
65536*1000/4/1024/0,8=20000
(4096-819)*20000/65536=1000,06103515625
Da aber der ADC nicht 1024 ausgeben kann, hilft man dem Wert etwas auf 
die Sprünge, indem man mit 20024 multipliziert.


Merke:
Der Rechner rechnet viel lieber mit Vielfachen von 2 als mit Vielfachen 
von 10.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Merke: Der Rechner rechnet viel lieber mit Vielfachen von 2 als mit
> Vielfachen von 10.
Jedes Vielfache von 10 ist zugleich ein Vielfaches von 2   :-o
2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22....

Korrekt hieße das
Merke: Der Rechner rechnet viel schneller mit Potenzen von 2 als mit
Potenzen von 10.


BTW:
> ... Der Rechner rechnet viel lieber ...
"Lieb" ist dem Rechner gar nichts,
dem ist vollkommen egal, womit oder was er rechnet ;-)

Autor: RetterDerMathematik (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
eheheh nicht die mathematik verteufeln, sehr wohl hat auch die 
Mathematik für das Problem einen logischen Weg! Wenn er nämlich mit Int 
rechnet ist er nicht im Raum von |R sondern im Raum von Z! und somit 
gibt es dort keine Zahl 0,.... und das Problem ist auch in der 
Mathematik gelöst! In der Natur kommt es nur sehr oft vor das Gerechnet 
wird ohne zu wissen was man tut (z.B. in welchen Raum man sich bewegt 
...) und schwup die wup hat man shcon das falsche ergebnis... (schönste 
beispiele sind komplizierteste gleichungen wie durch x dividiert wird 
und nicht ausgeschlossen wird das x null werden kann somit die 
umstellung nicht exakt ist, räume verlassen werden (imaginäre zahlen) 
etc. etc. und die Leute wundern sich warum es nicht klappt (bsp. 
(-1)^1/3 bzw. die dritte wurzel aus -1. die die nicht nachdenken sagen 
es gibt nur eine lösung nämlich -1, das ist aber falsch es gibt exakt 3 
lösungen! (-1, 0.5(-1+i*sqrt(3)), 0.5(-1-i*sqrt(3)))  zugegeben ich habs 
auch in der schule nicht besser gelernt aber in studium sind mir dann 
die augen aufgegangen und ich überleg nun des öftern mal wenn ich einen 
mist raus bekomme aus formel ob ich mir nicht hilfe bei der mathematik 
holen kann ;) )

so nun: "hoch die mathematik"

Autor: :::: (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein Tiefpass ist resourcenschonender wie eine Mittelung und gibt jedes 
Mal ein Resultat. Man kann auch mach exponentiellem Mittel suchen 
lassen.

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...resourcenschonender als eine Mittelung...

Autor: Dieter S. (accutron)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Anfangsgleichung kann vereinfacht werden zu:

Y = (X * 1250)/1023 - 250

Die Multiplikation und Division erfordern aber immer noch 32 Bit (bzw. 
24 Bit).

Wichtig ist dabei zu beachten, dass es für kleine X auch zu Unterläufen 
kommen kann (die abzufangen sind).

Gruß

Dieter

Autor: Reinhard R. (reirawb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Y = (X * 1250)/1023 - 250

Bei moderater Verschlechterung der Genauigkeit kann ich 
(programmtechnisch gesehen) noch weiter vereinfachen:

Y = (X * 1251)/1024 - 250
10 Bit Schieben^^^^

aber bei einem Wertebereich von 0...1000 und dem auswertbaren
ADC-Bereich von 204 (4mA) bis 1023 = 820 Schritte wird das
ganze sowieso nur ein Schätzeisen :-)
                      ^^^^^^^^^^^
Das soll jetzt keine Abwertung des Projetes sein. Wahrscheinlich reicht 
dem OP die Auflösung.

Reinhard

Autor: Richard U. (ronw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
:::: schrieb:
> Ein Tiefpass ist resourcenschonender wie eine Mittelung und ...

Eine Mittelwertbildung über mehrere Werte ist nichts anderes als ein 
Tiefpass.

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.