Hallo,
ich habe eine Frage und hoffe auf eure Hilfe.
Ich möchte eine Spannung (0-12V) an Hand eines Mikrocontrollers messen.
Dazu würde ich einen ADC-Channel benutzen, die Referenzspannung beträgt
5V.
Der ADC hat eine Auflösung von 12b.
Die 0-12V würde ich über einen Spannungsteiler messen wollen.
Ist das so in Ordnung? Was müsste ich jetzt tun und in welcher
Reihenfolge?
Skalieren, berechnen ...?
LG, Ani
Ani schrieb:> Damit meine ich 12 bit, also 4096 Schritte.> So habe ich es zumindest laut dem Datenblatt verstanden. :-)
Welches Datenblatt zu welchem ATMega? Link?
Karl M. schrieb:> Hallo,>> was meinst Du damit ?> /Der ADC hat eine Auflösung von 12b./
Na wohl 12 Bit. Was denn sonst?
Ob es einen ATMega gibt der einen 12 Bit ADC weiß ich aber auch nicht.
> Ist das so in Ordnung?
Ja
> Was müsste ich jetzt tun und in welcher> Reihenfolge?
Rechne den Spannungsteiler und deine gewünschte Spannungsauflösung des
Ergebnisses (z.B. 1/10V) aus und passe die Rohdaten vom ADC entsprechend
an.
Ich lasse das immer Wolfram Alpha ausrechnen. Gib dort einfach die
Formel für den ADC (steht im Datenblatt) ein. Den Spannungswert ersetzt
du durch die Formel für den Spannungsteiler und dividierst diesen noch
um deine Auflösung zu bekommen, also z.B. durch 10.
Dort bekommt man dann einen Bruch, nach dem Schema (ADC * x) / y, das
kannst du im Code dann direkt so rechnen lassen, und hast dann direkt
die Spannung in z.B. 1/10V vorliegen und kannst direkt als Festkomma
weiterverarbeiten. Lass die Finger von float usw.
Wenn Du wirklich eine externe Referenzspannung mit 5V ist immer eine
Berechnung der Fehlerkette sinnvoll.
Bei vielen ADC kann man mit einem 2-Punktabgleich den/ einen Offset- und
einen liearisierungs Fehler ausgleichen.
Es ergibt sich dann eine Funktion f1 der Form:
f1(x) = m *(x-x0) +y0
m = (y1-y0) / (x1-x0) ; konstant
Je nach Vorgeschaltetem Spannungsteiler, incl. Puffer
Opperationsverstärker ist dann die Berechnung der Eingangsspannung
einfach.
f2(x) = f1(x) * k
Karl M. schrieb:> Wenn Du wirklich eine externe Referenzspannung mit 5V ist immer eine> Berechnung der Fehlerkette sinnvoll.>> Bei vielen ADC kann man mit einem 2-Punktabgleich den/ einen Offset- und> einen liearisierungs Fehler ausgleichen.>> Es ergibt sich dann eine Funktion f1 der Form:> f1(x) = m *(x-x0) +y0> m = (y1-y0) / (x1-x0) ; konstant>> Je nach Vorgeschaltetem Spannungsteiler, incl. Puffer> Opperationsverstärker ist dann die Berechnung der Eingangsspannung> einfach.>> f2(x) = f1(x) * k
Wo geht's denn hier jetzt bitte um die Genauigkeit und Abgleich. Das
braucht man doch erst mal alles gar nicht. Zur gewünschten Genauigkeit
schreibt Ani doch nichts.
What ?!
Cyblord -. schrieb:>> was meinst Du damit ?>> /Der ADC hat eine Auflösung von 12b./>> Na wohl 12 Bit. Was denn sonst?
Ich definiere b := Birnen, denn Bier trinke ich nicht.
Also die "Einheit" Bit sollte man schon korrekt angeben.
Spaß beiseite, eine vollständige und korrekte Schreibweise lässt keinen
Raum für Interpretationen.
Karl M. schrieb:> What ?!>> Cyblord -. schrieb:>>> was meinst Du damit ?>>> /Der ADC hat eine Auflösung von 12b./>>>> Na wohl 12 Bit. Was denn sonst?>> Ich definiere b := Birnen, denn Bier trinke ich nicht.>> Also die "Einheit" Bit sollte man schon korrekt angeben.>> Spaß beiseite, eine vollständige und korrekte Schreibweise lässt keinen> Raum für Interpretationen.
War aus dem Kontext aber einfach zu 100% klar.
Cyblord -. schrieb:> Wo geht's denn hier jetzt bitte um die Genauigkeit und Abgleich. Das> braucht man doch erst mal alles gar nicht. Zur gewünschten Genauigkeit> schreibt Ani doch nichts.
Es ist halt der für mich sinnvollste Weg und ich mache es so.
Nur die Rohdaten ohne Korrellation ausgeben nützt doch gar nichts!
Vielen Dank für eure Hilfe, ich werde versuchen mich in Zukunft
deutlicher auszudrücken. :-)
Ich werde die Tipps nun ausprobieren und mich dann wieder melden.
LG, Ani
Karl M. schrieb:> Cyblord -. schrieb:>> Wo geht's denn hier jetzt bitte um die Genauigkeit und Abgleich. Das>> braucht man doch erst mal alles gar nicht. Zur gewünschten Genauigkeit>> schreibt Ani doch nichts.>> Es ist halt der für mich sinnvollste Weg und ich mache es so.>> Nur die Rohdaten ohne Korrellation ausgeben nützt doch gar nichts!
Wer spricht von Rohdaten ausgeben? Rohdaten in einen Spannungswert
umrechnen nützt was. Wie GENAU das ganze dann ist, hängt erst mal von
den verwendeten Widerständen im Spannungsteiler und dann von der ADC
Genauigkeit selbst ab. Dazu steht im Datenblatt auch einiges. Aber bevor
man nicht mal den Spannungswert selbst hat, ist die Genauigkeit
zweitrangig.
Denn selbst ohne irgendeinen Abgleich, mit 1% Metallwiderständen und ne
Standard 5V LDO kann man 0-12 V auf 1/10V genau messen. Mehr wollen die
meisten gar nicht.
Ani schrieb:> Der ADC hat eine Auflösung von 12b.
Bei einem Atmega eher nicht, da braucht man schon ATxmega.
> Spannungsmessung ATmega> die Referenzspannung beträgt 5V.
Die Versorgungsspannung. Die Versorgungsspanngun auch als
Referenzspannung zu verwenden ist in Anwendungen bei denen man MESSEN
will ud nicht blos SCHÄTZEN will aber eher unsinnig. Alle Atmega haben
eine interne stabile Referenzspannung. Die ist allerdings ungenau, so
daß man die Schaltung vor der ersten Anwendung mit diesem Chip
kalibrieren muss.
Ani schrieb:> Die 0-12V würde ich über einen Spannungsteiler messen wollen.
Kann man machen. Der Netzwerkwiderstand am A/D-Eingang sollte nicht über
10k liegen (bei 10 bit A/D-Wandlern von ATmegas, bei ATxmega noch mal
ins Datenblatt gucken).
Der "obere" Widerstand des Spannungsteilers muss ausreichend gross sein
damit auch bei Überspannung am Eingang nicht mehr als der zulässige
Strom über die Eingangsschutzdidoen des A/D-Wandlers fliessen kann. 10k
sind also auch als Mindestwert ok.
> Was müsste ich jetzt tun
Masse der 12V Schaltung mit Masse (0V) des 5V der Versorgung des AVR
verbinden und gucken ob es nicht knallt.
> Rechne den Spannungsteiler und deine gewünschte Spannungsauflösung des> Ergebnisses (z.B. 1/10V) aus und passe die Rohdaten vom ADC entsprechend> an.
@Cyblord:
Ich habe als R1 33k und R2 3,3k.
Die Uges kann zwischen 0 und 12 V liegen.
Zwischen den beiden Widerständen gehe ich auf meinen ADC-Eingang.
Müsste ich nun über die Spannungsteilerformel die beiden Teilspannungen
ausrechnen, um dann damit die Gesamtspannung zu brechnen?
Was meinst du genau mit Rohdaten des ADC anpassen?
LG, Ani
Ani schrieb:>> Rechne den Spannungsteiler und deine gewünschte Spannungsauflösung des>> Ergebnisses (z.B. 1/10V) aus und passe die Rohdaten vom ADC entsprechend>> an.>> @Cyblord:>> Ich habe als R1 33k und R2 3,3k.
Zu hoch. Nimm max. 10k für R1 und passe R2 an.
> Die Uges kann zwischen 0 und 12 V liegen.> Zwischen den beiden Widerständen gehe ich auf meinen ADC-Eingang.>> Müsste ich nun über die Spannungsteilerformel die beiden Teilspannungen> ausrechnen, um dann damit die Gesamtspannung zu brechnen?
Dich interessiert nur U2. Du musst die Formel nehmen die U2 berechnet.
Also U2=(Uges/(R1+R2))*R2
> Was meinst du genau mit Rohdaten des ADC anpassen?
Einfach das umrechnen deines direkten ADC Ergebnisses ist eine reale
Spannung.
>> LG, Ani
Ani schrieb:> Der ADC hat eine Auflösung von 12b.
Dann meinst du bestimmt einen ATXMega und keinen ATMega, die ATMegas
haben alle nur 10 Bit AD-Wandler drin. Oder willst du an den ATMega
einen 12 Bit AD-Wandler anschließen?
Ani schrieb:> Ist das so in Ordnung? Was müsste ich jetzt tun und in welcher> Reihenfolge?> Skalieren, berechnen ...?
Du skalierst dir deinen Spannungsteiler, z.B. eine Reihenschaltung von
10 kOhm und 2,2 kOhm. Die 2,2 kOhm gehen an Masse, an die 10 kOhm kommt
dein Signal. Zwischen den 10 kOhm und den 2,2 kOhm gehst du an deinen
AD-Wandler-Eingang.
Wie das Signal gewandelt wird hängt vom AD-Wandler ab.
Das Wandlerergebnis ergibt sich dann zu AnliegendeSpannung = 12 V / 4095
* ADValue. Es kommt dann drauf an was du genau brauchts. Man kann mit
Floats rechnen, das braucht aber idR etwas Leistung oder du benutzt
Festkomma-Arithmetik und rechnest z.B. alles in Millivolt und setzt das
Komma dann erst bei der Ausgabe, das bleibt halt ganz dir überlassen.
Es ist ein ATXMega, stimmt! :-)
Ich habe leider noch ein Verständnisproblem bei der Umrechnung.
Ich möchte meine Werte in Millivolt halten.
Nun rechne ich bei U2=(Uges/(R1+R2))*R2:
R1=10k, R2=2,2k
Ani schrieb:> Bei dieser Rechnung bekomme ich nach der Division eine Kommazahl heraus.
nein bekommst du nicht. Zumindest nicht der Compiler sondern nur du wenn
du sie im Taschenrechner eingibst.
Wenn ich mir die Variable U2 nach dieser Rechnung anzeigen lasse,
erhalte ich 0.
Ich denke mir das so, dass ich 12000 durch 12200 teile, damit 0,98
erhalte.
Es wird aberundet auf 0. Mit dieser 0 multipliziere ich die 2200.
Wie kann ich das verhindern?
LG, Ani
Ani schrieb:> Bei dieser Rechnung bekomme ich nach der Division eine Kommazahl heraus.> Wie kann ein int-Datentyp damit rechnen?
Im Taschenrechner ja, dein AVR bekommt da aber 2200 raus. Warum? Ganz
einfach: Der Compiler rechnet zunächst 12000 / 10000. Ohne weitere
Information kommt da bei einer Integer-Rechnung 1 raus. Und dann wird
das Ganze mit 2200 multipliziert.
Mal ganz nebenbei, was erhoffst du dir durch diese Rechnung, die stimmt
ja vorne und hinten nicht (Tipp: Rges).
Also, rechne wie folgt:
1
...
2
MeasureVoltage=12000/4095*ADCValue;
3
...
Da aber 12000 / 4095 = 2,93... gibt und man ne Integerrechnung macht
gibt das nen ziemlich großen Fehler, also entweder in Float rechnen oder
12000 / 4095 durch 3 ersetzen oder in Mikrovolt rechnen. Kommt natürlich
auch drauf an wie genau du es brauchst.
M. Köhler schrieb:
>Es kommt dann drauf an was du genau brauchts. Man kann mit>Floats rechnen, das braucht aber idR etwas Leistung oder du benutzt>Festkomma-Arithmetik und rechnest z.B. alles in Millivolt und setzt das>Komma dann erst bei der Ausgabe, das bleibt halt ganz dir überlassen.
Mit float habe ich es nun geschafft, die Spannung zu messen.
1
Umeasure=12.0/4095*adc_value;
Ich würde aber auch gerne probieren, wie das ganze mit Millivolt
funktioniert.
Kannst du mir das genauer zeigen, wie das dann funktioniert, außer den
Datentyp auf int zu ändern.
LG, Ani
Ani schrieb:> Bei dieser Rechnung bekomme ich nach der Division eine Kommazahl heraus.> Wie kann ein int-Datentyp damit rechnen?
Na in dem du nicht auf 12 Volt, sondern 12000 Millivolt umrechnest...
Ok, es funktioniert.
Leider ist das Messergebnis noch ziemlich ungenau, bei beiden Varianten.
Bringt es etwas, die Messung mehrmals durchzuführen und einen Mittelwert
zu bilden und dann erst das Ergebnis auszugeben?
Kann ich an Hand meines Spannungteilers genauer werden?
LG, Ani
Ani schrieb:> Bringt es etwas, die Messung mehrmals durchzuführen und einen Mittelwert> zu bilden und dann erst das Ergebnis auszugeben?
Es kommt drauf an wie stabil deine Referenzspannung und wie stabil deine
zu messende Spannung ist. Eine Mittelwertbildung kann hier viel helfen,
da kommt dann aber zwangsläufig die Frage auf: Kannst du es dir leisten
zu mitteln (das setzt die Abtastfrequenz runter)?
Ani schrieb:> Leider ist das Messergebnis noch ziemlich ungenau,
Was hast du an:
MaWin schrieb:> Die Versorgungsspannung auch als> Referenzspannung zu verwenden ist in Anwendungen bei denen man MESSEN> will und nicht bloss SCHÄTZEN will aber eher unsinnig.
nicht verstanden ?
Wie oft muss man es dir wiederholen bis du es begreifst ?
(daß es dann noch dutzend weitere Gründe geben kann warum die Messung
ungenauer als nötig wird, vom Aufbau auf Steckbrett, Versorgung durch
lange Leitung aus Labornetzteil, nebenbei angeschlossenem TFT mit CCFL
Hintergrundbeleuchtung, 2 langen Kabeln zur Spannungsquelle die gemessen
werden soll und diese einstellbare Spannungsquelle als 50k Poti
ausgeführt, von denen wir nichts wissen weil du es NATÜRLICH
verschwiegen hast, kommt hinzu).
MaWin schrieb:> (daß es dann noch dutzend weitere Gründe geben kann warum die Messung> ungenauer als nötig wird,
Grundsätzlich sollte man nicht so genau wie möglich, sondern so genau
wie nötig messen. Welche Genauigkeit der TE wirklich benötigt, hat er
allerdings bislang nicht gesagt.
Ani schrieb:> Die Abweichung ist sogar noch größer, wenn ich in Millivolt rechne.
Dann ist wohl dein Programm falsch, denn die Messabweichung ist immer
gleich gross, egal ob man in Volt oder Millivolt rechnet.
MaWin schrieb:> Ani schrieb:>> Die Abweichung ist sogar noch größer, wenn ich in Millivolt rechne.>> Dann ist wohl dein Programm falsch, denn die Messabweichung ist immer> gleich gross, egal ob man in Volt oder Millivolt rechnet.
Das tippe ich auch. Es muss bzgl. des Zahlenwertes eagal sein ob Ani mit
12,0 rechnet oder mit 12000 (also ob man mit Gleitkommaarithmetik
rechnet oder mit Festkommaarithmetik), es sollte in beiden Fällen
annähernd das gleiche heraus kommen und sich nicht ein Unterschied in
der beschriebenen Größenordnung auftreten, das klingt sehr nach
Code-Fehler vom Programmierer.
Guten Mittag,
genau dieses rumirren des TE Ani hatte ich erwartet.
Und schon am Anfang auf einen Puffer-Operationsverstärker hingewiesen.
Jeder ADC benötigt einen Eingangsstrom und bildet da durch mit dem
vorgesehenen Eingangs-Spannungsteiler einen belasteten Spannungsteiler,
der dann einen ganz anderes Teilungsverhältnis hat (i.A. fällt die
Messspannung kleiner aus).
Gab es schon mal einen Schaltplan, Programm und einige Bilder hier im
Forum?
Andere Fehlerquellen wurden ja schon genannt.
Hi
>Ich habe eine Abweichung von ca, 0,5V im unteren Bereich, im oberen>Bereich über 1V. Es ist eine Platine mit kurzen Leiterbahnen.
Die Berechnung
Umeasure = 12.0 / 4095 * adc_value;
ist eh unrichtig:
In unsigned mode the conversion result from the ADC is:
RES = (VINP + ΔV)/VREF * TOP
VINP is the single ended input and ΔV = VREF x 0.05. TOP is the top
value given by the configured resolution. For 12-bit
mode TOP is 4096 ...
MfG Spess
Karl M. schrieb:> Jeder ADC benötigt einen Eingangsstrom und bildet da durch mit dem> vorgesehenen Eingangs-Spannungsteiler einen belasteten Spannungsteiler,> der dann einen ganz anderes Teilungsverhältnis hat (i.A. fällt die> Messspannung kleiner aus).
Hast Du mal nachgesehen, wie hoch der Eingangswiderstand des
ADC-Einganges vom Kontroller im Verhältnis zu den Widerständen des
Spannungsteilers im einstelligen Kilo-Ohm-Bereich ist?
Die Änderung des Teilerverhältnisses dadurch kannst Du in den Skat
drücken.
MfG Paul
spess53 schrieb:> Hi>>>Ich habe eine Abweichung von ca, 0,5V im unteren Bereich, im oberen>>Bereich über 1V. Es ist eine Platine mit kurzen Leiterbahnen.>> Die Berechnung>> Umeasure = 12.0 / 4095 * adc_value;>> ist eh unrichtig:> ...
Hm, interessant. Woher weist du in welchem Modus der TE misst?
Hi
>Hm, interessant. Woher weist du in welchem Modus der TE misst?
Daher:
Autor: Ani (Gast) schrieb
>Die Uges kann zwischen 0 und 12 V liegen.>Zwischen den beiden Widerständen gehe ich auf meinen ADC-Eingang.
MfG Spess
spess53 schrieb:> Hi>>>Hm, interessant. Woher weist du in welchem Modus der TE misst?>> Daher:>> Autor: Ani (Gast) schrieb>>>Die Uges kann zwischen 0 und 12 V liegen.>>Zwischen den beiden Widerständen gehe ich auf meinen ADC-Eingang.>> MfG Spess
Ja, er kann unsigned, wie du vermutest, benutzen aber auch signed. Und
dann haste den Offset nicht. Sein Spannungspegel lässt eigentlich eher
vermuten, dass er signed benutzt denn Vref/2+dV als Bezugspotential zu
benutzen erscheint mir dabei nicht sehr sinnvoll was beim unsigned Mode
der Fall wäre.
Abend,
bevor wir noch lange weiter raten, sollte Ani erst einmal etwas mehr zur
Hardware und vermutlich auch zum Code preisgeben.
Das es kein Mega sondern ein Xmega ist wissen wir ja inzwischen, damit
fallen auch die 5V Referenz Spannung weg, mit genau welcher UB der Xmega
läuft wissen wir aber immer noch nicht.... das die interne Referenz um
weiten sinnvoller ist, wurde schon mehrfach erwähnt, wie der Xmega
tatsächlich initialisiert wurde, wissen wir aber auch nicht, ADC
kalibriert? wissen wir auch nicht....
Ist immer wieder das selbe und macht noch nicht einmal auf dem Clo Spaß
das zu lesen ;-)
Ich habe jetzt einige Informationen und Erkenntnisse.
Bauteil: ATXmega 64
ADC Auflösung: 12 bit
Zu messende Spannung: zwischen 0V und 12V
Schaltung am ADC-Eingang: Spannungsteiler bestehend aus R1 10k und R2
2,2k.
Parallel zu R2 habe ich einen 10nF Kondensator.
Wenn ich nun rechne:
void berechne_vin(void)
{
ergebnis = 12000 / 4095 * adc_wert);
}
erhalte ich eine ziemliche Abweichung vom wirklichen Spannungswert. (
bis 1-2V)
Das der ADC-Wandler auch einen minimalen Widerstand hat und damit einen
belasteten Spannungsteiler bildet ist weiß ich nun durch eure Beiträge.
Ich habe im Internet gelesen, dass man den Wert evtl. noch skalieren
muss, bzw. die Spannungsteilerformel anwenden muss. Kann mir nun jemand
die weitere Vorgehensweise erklären?
LG, Ani
Ani schrieb:> Ich habe im Internet gelesen, dass man den Wert evtl. noch skalieren> muss, bzw. die Spannungsteilerformel anwenden muss.
Dann mach's doch: Spannungsteiler in die Berechnung mit einbeziehen.
[OT]
'Spannungsteilerformel'
:-)
[/OT]
Wozu hast du den Spannungsteiler eingebaut? ...
Was ergibt sich daraus für ein messbarer Spannungsbereich? ...
Der Rest ist Mathematik 6. Klasse.
Wir wissen ja nicht wie alt Ani ist,
und ob sie alle Beiträge im Nachhinein versteht.
Ich verweise mal auf meinen Beitrag.
Beitrag "Re: Spannungsmessung ATmega"
Ich bin schon 17, also berechnen könnte ich das ganze schon, ich versteh
nur noch nicht ganz wie das alles zusammenhängt.
Ich habe den Spannungsteiler benutzt, damit ich meinen ADC-Kanal nicht
zerstöre.
Da dürfen ja nur 0-5V anliegen und keine 0-12V.
Ich kann jetzt mit meinem Spannungsteiler ausrechnen, dass ich am
ACD-Kanal eine Spannung zwischen 0 und 2,16V anliegen habe. Das könnte
ich noch ein bisschen verbessern.
Also weiß ich jetzt, dass ich am ADC-Eingang zwischen 0 und 2,16V habe
und am Ausgang 0 und 12V habe. Und meinen aktuellen ADC-Wert weiß ich.
Jetzt könnte ich das ganze ja skalieren, z.B. 0V -> 0V und 2,16V -> 12V.
Aber welche Information fehlt mir da noch dazu?? :-(
LG, Ani