Hallo,
ich hab mal wieder ein kleines Problem.
Ich lese eine Spannung ein und will sie auf einen LCD-Display anzeigen
lassen. Die Spannung wird erst durch einen Spannungsteiler geteilt, mit
einem invertierenden Verstärker verstärkt und dann mit einem
Mikrocontroller eingelesn. Das klappt auch alles, bis auf folgendes
Problem: Die Anzeige ist nicht linear. Im Programm teile ich die
Spannung nochmal so das sie der eingelesenen Spannung entspricht. Wenn
ich z.b. so teile das 10V genau angezeigt werden, weicht die Anzeige bei
größeren oder kleineren Spannungen immer mehr ab. Eigentlich müsste der
Wert bei änderungen linear bleiben. Ich hab keine Ahnung woher das
kommen kann.
mfg Peter
>Die Spannung wird erst durch einen Spannungsteiler geteilt, mit>einem invertierenden Verstärker verstärkt und dann mit einem>Mikrocontroller eingelesn.
Zeig mal die Schaltung.
Vielleicht ist noch ein Offsetfehler drauf, der mittels Korrektur durch
eine Geradengleichung y=mx+c zu beseitigen ist.
Also hintereinander ;) zwei bekannte Spannungen anlegen, angezeigten
Wert ablesen und m und c bestimmen.
Hier mal der Programmteil zum anzeigen der Spannung:
adcval = ReadChannel(0);
u = ADC;
u = (u>>6);
ut = 197;
u = u * 100;
u = u / ut;
itoa( u, Spannungswert, 10 );
sprintf (Spannungswert, "%u,%u", u/10 , u%10);
sprintf (Spannungswert, "%u,%02u", u/100 , u%100);
set_cursor(0,1);
lcd_string("Spannung: ");
lcd_string(Spannungswert);
lcd_string("V");
lcd_string(" ");
Schaltplan habe leider nur eínen selbst gezeichneten, ist aber
eigentlich genau so wie ich es beschrieben habe.
mfg Peter
Peter schrieb:> Schaltplan habe leider nur eínen selbst gezeichneten, ist aber> eigentlich genau so wie ich es beschrieben habe.
Es geht darum eine Nichtlinearität zu finden, die du selber nicht
siehst. Denkst du nicht, dass ein Schaltplan mit Bauteilwerten dazu
besser geeignet wäre, als so eine windige Beschreibung?
Hast du eigentlich schon mal die Spannung direkt am ADC-Pin gemessen und
mit deiner Anzeige verglichen?
adcval = ReadChannel(0);
In adcval hast du jetzt deinen ADC-Wert ...
u = ADC;
... warum dann noch einmal einlesen?
u = (u>>6);
Sehr sinnig. Von 10 Bit Messergebnis werden gleich mal 6 weggeworfen.
>Hier mal der Programmteil zum anzeigen der Spannung:
Dankeschön, unvollständig wie immer bei Deppen.
> adcval = ReadChannel(0);> u = ADC;
Was soll der Quatsch? Nimm adcval statt ADC.
> u = (u>>6);
Ähem. Schon mal was von Right adjusted gehört?
Du rechnest da so viel hin und her das es kein
Wunder ist das da nur noch Müll raus kommt.
tut mir echt leid, ich versteh die ganzen Penner nicht die nur
irgendeinen Scheiß schreiben (Deppen). Wenn es dir zu unverständlich ist
halte dich doch einfach aus dem Thema raus.
adcval ist genau das gleich wie adc.
ADC ist ein 16 Bit Register, wo der Wert linksbündig steht. Ich schiebe
ihn nur nach rechts, das ich nicht so viel teilen muss. Denn Wert habe
ich mal 100 genommen weil ich schlecht durch 1,97 teilen kann, oder?
@ alle anderen, ich werde noch einen schaltplan mit Splan anfertigen und
ihn dann Posten.
@ Karl:
>adcval = ReadChannel(0);>In adcval hast du jetzt deinen ADC-Wert ...> u = ADC;
tut mir leid, das habe ich nun mal so in einem tuturial gelesen, das der
Wert immer gleich in eine Variable geschrieben werden sool.
>... warum dann noch einmal einlesen?> u = (u>>6);>Sehr sinnig. Von 10 Bit Messergebnis werden gleich mal 6 >weggeworfen.
1111111111000000
so sieht nun mal das Ergebnis aus dan kann man doch wohl erstmal um 6
nach rechtsschieben.
mfg Peter
Peter schrieb:> @ Lukas: kannst du das genauer erklären?
x ist deine angelegte Spannung y=f(x) die angezeigte
nun 2 Beispielwerte:
2V angelegt, 1,3V abgelesen
3V angelegt, 2V abgelsen
daraus folgt
@ Karl:
>tut mir echt leid, ich versteh die ganzen Penner nicht die nur>irgendeinen Scheiß schreiben (Deppen). Wenn es dir zu unverständlich ist>halte dich doch einfach aus dem Thema raus.
tut mir leid, du warst damit nicht gemeint.
> Wenn ich z.b. so teile das 10V genau angezeigt werden, weicht die Anzeige > bei
größeren oder kleineren Spannungen immer mehr ab. Eigentlich müsste
> der Wert bei änderungen linear bleiben.
Kann an der Software und/oder der Hardware liegen.
Software mag ich aus dem Codeschnippsel nicht beurteilen.
Aber zu Hardware...
Hast du die Spannung am ADC Eingang (!) schon mit einer unabhängigen
Methode (Multimeter) gemessen. Ich meine, wenn dort schon keine
Linearität herrschen würde, könntest du dich in der Software totsuchen.
Zur Sicherheit bzw. aus Forscherdrang würde ich diese Messung auch vor
dem Spannungsteiler und vor dem invertierenden Verstärker durchführen.
Wenn die gewünschte Linearität an allen drei Punkten vorhanden ist,
lohnt es sich ab dem ADC Eingang zu suchen. Zwei Dinge aus dem
Datenblatt sind IMHO relevant: Abtastrate und Eingangsimpedanz. Bei
einem zu schnellen Abtasten kann ich mir vorstellen, dass es
Verschluckerlis gbt. Bei einer nicht passenden Eingangsimpedanz könnte
es Probleme geben den ADC fristgerecht zu füllen. Im Zusammenhang mit
dem invertierenden Verstärker sicher untersuchungswert.
@ Helfer:
Das werde ich Morgen mal machen.
Sorry:
adcval = ReadChannel(0);
u = ADC;
u = (u>>6);
ut = 197;
u = u * 100;
u = u / ut;
itoa( u, Spannungswert, 10 );
sprintf (Spannungswert, "%u,%u", u/10 , u%10);
> sprintf (Spannungswert, "%u,%02u", u/100 , u%100);
Das gehört eigentlich nicht rein, das steht bei mir nur im Programm als
Kommentar, falls ich eine oder zwei Stellen hinterm Komma anzeigen will.
set_cursor(0,1);
lcd_string("Spannung: ");
lcd_string(Spannungswert);
lcd_string("V");
lcd_string(" ");
mfg Peter
Helfer schrieb:> Bei einer nicht passenden Eingangsimpedanz könnte> es Probleme geben den ADC fristgerecht zu füllen.
Gilt natürlich nicht nur für den ADC-Eingang sondern auch die
Spannungsreferenz des ADCs. (Fehlender Kondensator).
Gruß Anja
> Hier mal der Programmteil
Interessiert keinen.
> Schaltplan habe leider nur eínen selbst gezeichneten, ist aber> eigentlich genau so wie ich es beschrieben habe.
Damit hätte man jedoch vielleicht helfen können, weil man dann
hätte können, ob dein Ausgang wegen Begrenzungen an der
Versorgungsspannung gar nicht linear sein könnte, oder so.
>> x ist deine angelegte Spannung y=f(x) die angezeigte>> nun 2 Beispielwerte:>> 2V angelegt, 1,3V abgelesen>> 3V angelegt, 2V abgelsen
Also 2 Wertepaare, Delta U / Delta ADC
und so wird es in Software umgesetzt:
Beitrag "ADC und Fixed-Point Arithmetik"
Linearisierung inklusive herausrechnen aller Fehlerquellen. Das
beschriebene Oversampling kannst du ja weglassen.
So ein "Problem" hatte ich auch mal. Das war aber bei mir kein
Linearitätsproblem, sondern ein Verstärkungsproblem. Wenn du deine
Faktoren so anpasst, daß da bei angelegten 10V auch wirklich 10V stehen,
dann kann deine Verstärkung auch totaler Mumpitz sein, was du dann aber
erst bei Wertänderungen merkst.
Konkret meine ich: dein Verstärkungsfaktor setzt sich ja aus z.B. dem
Spannungsteilerverhältnis, deiner Auflösung und deiner Referenzspannung
zusammen. Da gibt es die "Idealwerte" (z.B. Referenzspannung = 5V) und
die Wirklichen. Messe deinen Spannungsteiler vielleicht nochmal durch
und vor allem deine Referenzspannung. Für einen Punkt (deine 10V) kann
man sich dir werte zurecht lügen (was bei dir glaube ich) passiert. Mit
zwei Referenzpunkten kriegst du das aber weg. Dann ist es aber immer
noch kein Linearitätsproblem, sondern eine Verstärkungsproblem :) . Ich
hab das Problem bei mir bei der Referenzspannung gefunden...
Gruß