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
Mathias schrieb:
> Woran kann das liegen?
Daran, dass 1000/8184 null ist.
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 .
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?
>Oder war das jetzt irgendwie ironisch von dir gemeint?
War die Frage jetzt irgendwie ironisch von dir gemeint?
>> 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);
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
Hey, hast du deine Variable in deinem Programm richtig initalisiert? Mit int oder uint_8 .... Vielleicht liegt es daran
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
> Deklariere deine Variable als float oder double.
Ja, klar. Und dann wundere dich, warum das Flash voll ist und das
Berechnen solange dauert...
@ Karl heinz Buchegger Noch mehr Ironie? Dafür wäre es ein bischen lang.
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.
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.
@ Karl Heinz Nun mal langsam mit den jungen Pferden. Ich glaube Du hast mich falsch verstanden. Du wirst mir in letzter Zeit unsympathisch.
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.
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 ;(
> 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.
> 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 ;-)
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"
Ein Tiefpass ist resourcenschonender wie eine Mittelung und gibt jedes Mal ein Resultat. Man kann auch mach exponentiellem Mittel suchen lassen.
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
> 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
:::: schrieb:
> Ein Tiefpass ist resourcenschonender wie eine Mittelung und ...
Eine Mittelwertbildung über mehrere Werte ist nichts anderes als ein
Tiefpass.
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.