Berechnung mit ADC-wert mißlingt

Gast #1353584
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
Gast #1353599
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 .
#1353632
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
Gast #1353652
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
#1353667
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.
Gast #1354215
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.
Moderator (Firma: Titel) Persönliche Seite #1354550
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 ;-)
Gast #1354559
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"
#1354703
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren