Guten Abend, ich möchte gerade mein Leben einfacher machen und den Compiler rechnen lassen. Aber leider rechnet der ganz anders als ich. Was mache ich falsch? ich erwarte mir in der Variable test den wert 245 jedoch steht in Wirklichkeit 0,0002337598 drin! #define R1 270000.0f // Wiederstandswert1 #define R2 47500.0f // Wiederstandswert2 #define Utarget 5.0f // Versorgung ADC bzw Atmel #define ADCstep Utarget/1024 // #define Uschw1 8.0f #define Ig1 Uschw1/(R1+R2) #define Uadc1 R2*Ig1 #define _8V ((Uadc1/ADCstep)) double test = _8V if (voltage < _8V) { bla; }
Mach mal um alle Definitionen eine Klammer! #define rechnet nicht, sondern ersetzt. Insbesondere: #define ADCstep (Utarget/1023) Btw: Es sind nur 1023 Steps bei 10 Bit. Gruß
Der Preprozessor macht das daraus:
1 | double test = ((47500.0f*8.0f/(270000.0f +47500.0f)/5.0f/1024)); |
Wo die Klammer fehlt, findest Du bestimmt selbst heraus ;) Wenn man schon defines benutzen muss, immer alles klammern.
pi_user schrieb im Beitrag #4617657:
> #define ADCstep Utarget/1024 //
Mach da mal Klammern drum.
Danke! Wenn man es so stehen sieht dann ist es auch logisch!!!! Danke
> #define rechnet anders als ich es erwarte
Nein, "#define" rechnet überhaupt nichts. "#define" ersetzt nur den
Text, "#define" weiß nicht, was es da ersetzt.
#define ist böse, man sollte nur Konstanten #definen und die Rechnerei ganz normal im Programm hinschreiben. Aber selbst dann gibt es pathologische Fälle, in denen die Klammern nötig sind.
eagle user schrieb: > #define ist böse, Ja, aber für symbolische Konstanten gibt es in C keine Alternative. Egal ob berechnet oder nicht. Stroustrup hatte in C++ eben deshalb skalaren "const" Definitionen abweichend von C die Rolle lexikalischer Konstanten gegeben. Eine Eigenschaft, die C fehlt. > man sollte nur Konstanten #definen und die Rechnerei > ganz normal im Programm hinschreiben. Nein. Symbolische Namen verwendet man, um einen Wert an einer einzigen Stelle zu definieren und an 1000 Stellen verwenden zu können. Es wäre absurd, an den 1000 Stellen jeweils die Rechnung hinzuschreiben und später ändern zu müssen. Es wäre ebenso absurd, statt dessen den Taschenrechner zu bemühen um den Wert an Stelle einer Rechnung direkt hinschreiben zu können. In anderen Sprachen kann man symbolische Konstanten ungefähr so definieren: const integer A = B * C; Das Äquivalent dazu in C ist #define A ((B)*(C)) Dass man aufgrund des Prinzips der Textersetzung mehr Klammern setzen muss als in C sonst nötig ist traurig, gehört aber eben zu den Altlasten von C.
Don schrieb: > Joachim schrieb: > >> Btw: Es sind nur 1023 Steps bei 10 Bit. > > 2^10 sind bei dir 1023? Steps! Es sind zwar 1024 Werte, aber 1023 Steps! Von 0 auf 1 ist 1 Step. Von 0 auf 1023 sind 1023 Steps!
Alex W. schrieb: > Don schrieb: >> Joachim schrieb: >>> Btw: Es sind nur 1023 Steps bei 10 Bit. >> 2^10 sind bei dir 1023? > Steps! Es sind zwar 1024 Werte, aber 1023 Steps! Von 0 auf 1 ist 1 Step. > Von 0 auf 1023 sind 1023 Steps! Genau. Oder einfach Dreisatz: V_Ref entspricht ADC_Maximalwert (hier 1023). Gruß
Es sind trotzdem 1024. Auszug vom ATmega48...ATmega328: "The minimum value represents GND and the maximum value represents the voltage on the AREF pin minus 1 LSB." Und so kenne ich es von anderen Wandlern auch. Das trägt allerdings auch gar nicht zur Lösung seines Problems bei. Gruß Jobst
Jobst M. schrieb: > "The minimum value represents GND and the maximum value represents the > voltage on the AREF pin minus 1 LSB." Jo und was ist das Maximum "minus 1 LSB"? Richtig 1023. Bei 10 Bit sind es 1024 Abstufungen, da du die Stufe 0 mitzählen musst sind es 0 bis 1023. Der Fehler ist mir auch schon paar mal passiert. Merke es häufig wenn ich den ADC Wert umrechne und mich wundere warum da was nicht ganz so passt. :)
mr. mo schrieb: > Bei 10 Bit sind es 1024 Abstufungen, da du die Stufe 0 mitzählen musst > sind es 0 bis 1023. Hauptsache du hast was geschrieben.
mr. mo schrieb: > Jo und was ist das Maximum "minus 1 LSB"? Richtig 1023. Nein. Das Maximum ist 1023. Einen höheren Wert kannst Du mit 10 Bit nicht darstellen. Und es soll ja auch nicht vom Wert 1 LSB abgezogen werden, sondern von Vref. Und der Wert 1023 entspricht einer Spannung von Vref minus 1 LSB. Vref ist also 1024 (was maximum + 1 LSB ist) Du musst also von Vref die Spannung für 1 LSB abziehen und kannst dann durch Deine 1023 teilen oder Vref einfach durch 1024 teilen. mr. mo schrieb: > Der Fehler ist mir auch schon paar mal passiert. Nein, nun machst Du ihn. Vielleicht solltest Du mal einen ADC diskret aufbauen, dann weißt Du auch woher das kommt. 512 ist genau Vref/2, 256 Vref/4, 128 Vref/8, ... Eingangsspannung darf also nie Vref werden, sondern nur 1023/1024 davon - oder Vref - 1 LSB. Ach ja: Auch aus dem Datenblatt: V IN ⋅ 1024 ADC = ------------- V REF Gruß Jobst
Diese alte Diskussion mal wieder... Der Fehler, der hier immer gemacht wird, ist, dass es hier nicht um Stufen, sondern um Spannungsbereiche geht. Jeder ADC-Wert entspricht nicht genau einer Spannung, sondern einem Spannungsbereich. Mal auf 2 Bit reduziert, bei Uref = 1 V: 0 entspricht dem Bereich 0V <= U < 0,25V 1 ensptricht dem Bereich 0,25V <= U < 0,5V 2 ensptricht dem Bereich 0,5V <= U < 0,75V 3 ensptricht dem Bereich 0,75V <= U < 1V Die aus dem Wert ermittelte gerundete Spannung wäre also U = (Wert + 0,5) / 4 Das gilt für einen ADC, der nicht selbst schon rundet. Aber auch wenn der ADC das tut, muss man durch 4 teilen und nicht etwa durch 3 - bei 10 Bit enstprechend durch 1024.
Hier bspw. wird auch auf die 1023/1024-Problematik eingegangen: http://www.st.com/content/ccc/resource/technical/document/application_note/9d/56/66/74/4e/97/48/93/CD00004444.pdf/files/CD00004444.pdf/jcr:content/translations/en.CD00004444.pdf Seite 12-13 Jobst M. schrieb: > 512 ist genau Vref/2, 256 Vref/4, 128 Vref/8, ... Zitat Seite 4: The SAR starts by forcing the MSB (Most Significant bit) high (for example in an 8 bit ADC it becomes 1000 0000), the DAC converts it to V AREF/2. The analog comparator compares the input voltage with VAREF/2. If the input voltage is greater than the voltage corresponding to the MSB, the bit is left set, otherwise it is reset. Das heißt doch, wenn exakt Vref/2 anliegt, dann wird das MSB auf 0 gesetzt, weil nicht größer. Gruß
Jobst M. schrieb: > Nein. Das Maximum ist 1023. LOL, soviele Worte um nichts. Werte insgesammt = 2^n Maximaler Wert = 2^n - 1 Und das wars dann.
Mit wenigen Worten nichts zu sagen, ist auch nicht wirklich besser, als mit vielen Worten nichts zu sagen.
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.