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
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
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
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.
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?
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 ...
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
intmain()
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 !