Hallo, ich bin gerade dabei einen AD-Wandler zu programmieren komme aber noch nicht so ganz mit der Umrechnung klar. IC Atmega8 Ich habe die interne Referenzspannung von 2,56V gewählt Am ADCO 0 habe ich ein einstellbare Spannung von 100 mv bis 400 mv anliegen wo ich auswerten möchte. Habe zwei Schaltstellen eine bei 260 mv und die zweite bei 340 mv. Kann ich die Umrechnung mit der Formel umrechnen ADC = Vin * 1024 /Aref = 0,260 *1024 / 2,5 = 106,4 ADC = Vin * 1024 /Aref = 0,340 *1024 / 2,5 = 139,2 stimmt diese Umrechnung? oder gib es eine andere Formel? kann man auch die zwei werte in einer if frage vergleichen z.b if (ADC > 0,260mv | < 0,340mv) oder geht das nicht? Bin für jede Hilfe und Tipps Dankbar
Torsten schrieb: > ich bin gerade dabei einen AD-Wandler zu programmieren komme aber noch > nicht so ganz mit der Umrechnung klar. > > IC Atmega8 > > Ich habe die interne Referenzspannung von 2,56V gewählt > Am ADCO 0 habe ich ein einstellbare Spannung von 100 mv bis 400 mv > anliegen wo ich auswerten möchte. > > Habe zwei Schaltstellen eine bei 260 mv und die zweite bei 340 mv. > > Kann ich die Umrechnung mit der Formel umrechnen > > ADC = Vin * 1024 /Aref = 0,260 *1024 / 2,5 = 106,4 > > ADC = Vin * 1024 /Aref = 0,340 *1024 / 2,5 = 139,2 > > stimmt diese Umrechnung? oder gib es eine andere Formel? Es gibt eine ganze Menge anderer Formeln. Welche die richtige ist, hängt davon ab, wie genau du den AD-Wandler betreibst. Die von dir verwendete Formel wäre korrekt für den Fall, daß du das Ding im Single-Ended Modus und mit rechts ausgerichteten Ergebnissen betreibst. > kann man auch die zwei werte in einer if frage vergleichen > > z.b if (ADC > 0,260mv | < 0,340mv) ImPrinzip ja, aber so sicher nicht. Was du wahrscheinlich wolltest: Wissen ob die Spannung im vorgegebenen Bereich ist. Dann mußt du schreiben: if (ADC > ADCVALUE(0.26) && ADC < ADCVALUE(0.34)) Dazu müßtest du natürlich auch ein passendes Macro namens ADCVALUE schreiben, was die Anwendung der passenden Formel darstellt. Fazit: Lerne am besten erstmal die Sprache, die du verwendest. Ja, es ist eine Scheißsprache, aber schließlich zwingt dich ja niemand, sie zu verwenden...
ja an sich schon aber wenn Aref gleich 2,56V ist sollte man das auch in die Gleichung einsetzen... > Habe zwei Schaltstellen eine bei 260 mv und die zweite bei 340 mv. > Kann ich die Umrechnung mit der Formel umrechnen > ADC = Vin * 1024 /Aref = 0,260 *1024 / 2,5 = 106,4 ADC = Vin * 1024 / Aref = 0,260 * 1024 / 2,56V = 104
Falk Brunner schrieb: > Siehe Festkommaarithmetik Huch?! Mir scheint, es geht hier eher um Gleitkommarithmetik zur Entwurfszeit...
c-hater schrieb: > Dazu müßtest du natürlich auch ein passendes Macro namens ADCVALUE > schreiben, Makro ist schon richtig. Er will aber "mV" Ich würde so schreiben: #define mV * 1024 / 2560 if ((ADCW > (260 mV)) && (ADCW < (340 mV))) { /* all ok */ } Gruß Anja
Hallo, erst mal vielen Dank für die schnellen Antworten. Ich habe in der zwischen zeit noch ein wenig ausprobiert doch es will einfach nicht. Ober bin ich nur heute Abend nicht mehr in der Lage die Fehler zu finden -; Wenn ich das Programm Startete dann gehen Port B & D kurz an so wie im Programm aber danach reagiert er nicht mehr auf das analoge Signal. Wenn ich die Werte verändre bringt es auch nichts (außer ich komme unter 15 aber das ist aber wahrscheinlich die Ungenauigkeit von AD-Wandler) Habe im Anhang mal den Text. Ihr könnt ja mal drüber schauen und sagen wo noch Fehler sind bzw. wo keine sind.
Torsten schrieb: > wo noch Fehler sind ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion" ADC_result = ADCW; // ADC-Wert in ADC_result schreiben Nach Start der Wandlung solltest Du nicht so ungeduldig sein und solange Warten bis der ADC auch den Wert gewandelt hat. (siehe Datenblatt). Gruß Anja
Guten Morgen, was mir aufgefallen ist: 1) c.txt Datein laufen bei mir nicht durch Compiler 2) mehrfaches Überschreiben des Rigisters ADCSRA, Stichwort Bitmanipulation
1 | ADCSRA = (1<<ADPS1) | (1<<ADPS2); // Frequenzvorteiler 64 |
2 | ADCSRA = (1<<ADIE); |
3 | ADCSRA = (1<<ADEN); // ADEN = ADC aktivieren |
4 | ADCSRA |= (1<<ADSC); |
Mach dir mal den Spaß und spiele mit Papier und Bleistift µC und berechne bei diesen 4 Zeilen die Ergebnisse. Bitte hier auch hinschreiben. Start sei ADCSRA := 0. Dann ist diese Syntax von Zeile 1 falsch, waaaaas macht der Compiler für Ausgaben?
1 | Test_PortB |Test_PortD; // Ausgabeports D & B einschalten |
2 | _delay_ms(200); |
3 | PORTB =~0x00; // Ausgabeprot B auschalten |
4 | PORTD =~0x00; // Ausgabeprot D auschalten |
Uwe S. schrieb: > Mach dir mal den Spaß und spiele mit Papier und Bleistift µC und > berechne bei diesen 4 Zeilen die Ergebnisse. Heutzutage darf man auch den Simulator der IDE (Atmel Studio, AVR Studio oder was auch immer) benutzen, um sich Schritt für Schritt anzusehen, was im Prozessor passieren würde.
Hallo Wolfgang, ja sicherlich, es ist auch für Anfänger eine brauchbares Mittel. Mal in so einen AVR µC hinein sehen zu können. Ich verwende nur kein WinOS und somit keinen Simulator und benötige auch keinen.. Es hat für mich eine andere Klarheit die Dinge (Problemlösungen) auf dem Papier richtig zu machen, als mit einem Simulator nur die Ergebnisse (Ausgaben) zu sehen.
Noch etwas cooler ist ein In-Circiuit Debugger (z.B. AVR Dragon). Damit kannst Du das Programm anhalten, "in den Chip hinein schauen" und sogar Ports und Register ändern. Wegen der Berechnung: Wann immer es geht, vermeide Fließkomma Zahlen. Denn diese werden langam berechnet und erfordern ziemlich viel Programm Speicher. Anstatt 0,260 Volt kann der AVR besser mit 260mV rechnen. Das obige Marko "mV" ist eine geniale Lösung für diese Aufgabe, da einfach anzuwenden, gut nachvollziehbar und ohne Fließkomma Arithmetik. Noch besser wird es, wenn Du bei Divisionen und Multiplikationen möglichst auf "runde" Zahlen im Sinne des Binärsystem setzt, also 2, 4, 8, 16, usw. Denn um eine Zahl durch diese runden Zahlen zu dividieren oder zu multiplizieren, muss er ledigleich Bits nach Links oder rechts verschieben. Eine Division durch 7 ist erheblich komplexer. Ein Blick in den erzeugten Assembler-Code kann diesbezüglich Aufsclussreich sein. 1024/256 = 4 also eine Runde Zahl. Das ist der Idealfall! Un nun kannst DU Dir denken, warum die Referenzspannung gerade 2,56V ist und nicht etwa 2,5 Volt.
Hallo, habe das Programm etwas verändert. Wenn ich die Simulation durchlaufen lasse geht es bis auf die Ausgänge setzten. Kann man in der Simulation auch auf den AD-Wandler irgendein Signal legen? Denn wenn ich es wider auf meinem Board mache funktioniert es immer noch nicht richtig. Wenn ich jetzt auf die zweite Schalter Stellung gehe schaltet er mir die Schalter Stellung 1 durch. Stimmt da was in meiner Umrechnung nicht? Habe jetzt auch die Warte Zeile für den AD-Wandler drin.
Hänge bitte C-Dateien auch als solche an und nicht mit der Endung ".txt". Du sparst Dir die Umbennung und das lässt sich besser anschauen. Danke.
Hallo Torsten, hier mal eine übersichtlichere und angepasste Version. Als Beispiel habe ich mal Macros die wie Funktionen aus sehen angelegt und zum anderen static Funktionen für das LED setzen. Schau mal über das Programm und versuche es zu verstehen. Ich nehme mal an, dass die LED GND geschaltet werden, um "AN" zu sein.. .
Hallo, mit dem Programm von Uwe S. habe ich so weit durch geschaut und auch verstanden. Nur habe ich immer noch das Problem das die Schalter Stellung 3 die Schalter Stellung 2 durchschaltet Kurze Erklärung habe einen 3 Stufen schalter 1 Stufe 142 mv -> soll nichts passieren 2 Stufe 228 mv -> soll die erste if schleife durch schalten 3 Stufe 312 mv -> soll die erste if schleife aus und die zweite if schleife schalten. Berechnung 2 Stufe ADC = Vin * 1024 / Aref = 0,228 * 1024 / 2,56V = 91,2 3 Stufe ADC = Vin * 1024 / Aref = 0,312 * 1024 / 2,56V = 124,8 Wo kann jetzt das Problem noch liegen?
Guten Morgen, grundlegend sind deine Fehler noch vorhanden. Warum verwendest Du nicht mein Bsp.? Ich schreibe dir diese jetzt nicht heraus.
Torsten schrieb: > Kann man in der Simulation auch auf den AD-Wandler irgendein Signal > legen? Ein Analogsignal wird schwierig. Nachdem du das Ergebnis der Wandlung in ADC_result übernommen hast, kannst du es aber manipulieren.
Guten Morgen, @ Uwe S. ich habe dein Bsp. verwendet habe nur aus versehen die Falsche Datei angehängt. Habe bei den if abfragen die Werte auch schon mal Probiert abzuändern es bringt zwar etwas aber dann zucken die Led's wie sie wollen, aber es müsste doch auch mit den Werten gehen wo in den if schleifen sind, habe noch mal nachgemessen die werte am AD-Wanderl stimmen und die Umgerechnete Werte auch. Woran kann es jetzt noch liegen?
Vielleicht stimmen die Spannungen nicht, oder die von Dir programmierten Schwellwerte sind innerhalb der Toleranz des ADC oder der Referenz. Wenn eine Spannung ab 213mV irgedn etwas auslösen soll, dann wäre es schlecht, den Wert "312mV" zu programmieren. Ich würde eher die Mitte zwischen den tatsächlichen Spannungen als Grenzwerte nehmen: > 1 Stufe 142 mv -> soll nichts passieren > 2 Stufe 228 mv -> soll die erste if schleife durch schalten > 3 Stufe 312 mv -> soll die erste if schleife aus und die zweite if Also demnach etwa so abfragen: if (spannung <= 100mV) was dann passieren soll, hast Du vergessen, festzulegen else if (spannung > 100mV) dann soll nichts passieren else if (spannung > 180mV) dann soll die erste if schleife durch schalten else if (spannung > 270mV) dann soll die erste if schleife aus und die zweite if ...
>> if ((ADC_result >96) && (ADC_result <130))
oder sollte es if ((ADC_result > 96) || (ADC_result < 130)) sein ?
Bernd N schrieb: >>> if ((ADC_result >96) && (ADC_result <130)) > > oder sollte es if ((ADC_result > 96) || (ADC_result < 130)) sein ? Nö. Denn ausnahmslos für jede Zahl von -unendlich bis +unendlich gilt, dass sie entweder größer als 96 ODER kleiner als 130 ist. Für manche Zahlen gilt sogar beides. Aber eines von beiden gilt immer. 30 ist zwar nicht größer als 96, aber es ist kleiner als 130. 280 ist zwar nicht kleiner als 130, aber es ist größer als 96.
Stefan Frings schrieb: > Also demnach etwa so abfragen: > > if (spannung <= 100mV) was dann passieren soll, hast Du vergessen, > festzulegen > > else if (spannung > 100mV) dann soll nichts passieren > > else if (spannung > 180mV) dann soll die erste if schleife durch > schalten > > else if (spannung > 270mV) dann soll die erste if schleife aus und die > zweite if ... Aber dann bitte die Reihenfolge der Abfragen umdrehen. Denn 290 ist größer als 100. Und in dem Fall wäre es dann fatal, wenn das erste if zuschlägt und .... nichts tut. Die restlichen else-if kommen dann gar nicht mehr zum Zug. Bei solchen Dingen immer probehalber mit ein paar Zahlen im Kopf die Abfragen durchgehen. Da verhaut man sich leicht und schnell. (Zum Thema if-Schleife sag ich jetzt mal nichts :-)
> Am ADCO 0 habe ich ein einstellbare Spannung von 100 mv bis > 400 mv anliegen wo ich auswerten möchte. Was hast du da verschaltet? Masseverbindung hast du hergestellt? Abgesehen davon würde ich das alles mal radikal abspecken. Anstelle einer Spannung von 100 bis 400mV würde ich da erst mal ein 10k Poti als Spannungsteiler zwischen Vcc und GND vom µC schalten und mit dem Abgriff auf den ADC0 Pin. Dann nehm ich Vcc als Referenzspannung im Programm. ADIE braucht kein Mensch und führt nur zu Fehlern sobald erst mal Interrupts aktiviert sind. Überhaupt würde ich erst mal die Routinen aus dem AVR-GCC-Tutorial so wie sie sind, als Basis für den ADC nehmen. http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Analoge_Ein-_und_Ausgabe Dann fliegt das ganze Gedöhns mit Seitenruder und Blinken und was weiß ich noch was, raus. Zieht den Code nur in die Länge und trägt nichts zum Testen des ADC bei. Dann kommt ganz simpler Code. 1 ADC Eingang - 1 AUsgang an dem von mir aus 1 LED hängt
1 | int main() |
2 | {
|
3 | DDRD |= (1<<PD0); |
4 | |
5 | ADC_Init(); |
6 | |
7 | while( 0 ) { |
8 | if( ADC_Read( 0 ) > 512 ) |
9 | PORTD |= (1<<PD0); |
10 | else
|
11 | PORTD &= ~(1<<PD0); |
12 | }
|
13 | }
|
und erst wenn das beim Drehen am Poti die LED korrekt ein/aus macht, erst DANN arbeite ich weiter in die Richtung, in die ich eigentlich will. Nicht 5 Schritte auf einmal machen, sondern einen nach dem anderen und beim einfachsten anfangen.
Hallo Karl-Heinz, ich bin erschreckt, suche ich nach diesem frei erfundenen Begriff hier im Forum gibt es von Google 5.520 Ergebnisse. So ist klar, dass sich Anfänger derer Bezeichnungen bemächtigen, auch wenn sie nichts aussagen !
Hallo, mein Programm funktioniert nur habe ich nicht die errechnete Analog-Werte genommen. Mit den doppelten Werten funktioniert es.
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.