Forum: Mikrocontroller und Digitale Elektronik ADC - schwanken unterbinden


von Fragr (Gast)


Lesenswert?

Guten Abend,

ich suche gerade nach einer Möglichkeit den ADC softwareseitig zu 
optimieren.
Ein Potentiometer wird ratiometrisch ausgelesen und oversampled (256 
mal) und schließlich dezimal ausgegeben. Dabei habe ich das Problem, 
dass, sobald sich der Messwert einem anderen annähert ziemlich schwankt. 
Wenn ich mich also aktuell auf 33 befinde und Richtung 34 drehe, 
fluktuiert der Wert mehrmals pro Sekunde zwischen 33 und 34.
Diese Unruhe ist irgendwie störend und ich würde das gerne entfernen.

An der Schaltung lässt sich nicht viel ändern, aber trotzdem eine kurze 
Beschreibung: AVCC liegt über einem Kondensator an GND und über eine 
Spule an VCC. VCC kommt über einem Step-Down. Schwankungen dort sollten 
aber relativ unwichtig sein, oder? (ratiometrische Messung). Einen 
Schaltplan und SourceCode kann ich nachliefern, wobei ich aktuell keine 
Notwendigkeit drin sehen.

Ich habe keine Ansatz wie ich das lösen könnte und freue mich über eure 
Tipps.

Beste Grüße.

von Mein grosses V. (vorbild)


Lesenswert?

Fragr schrieb:
> Einen
> Schaltplan und SourceCode kann ich nachliefern, wobei ich aktuell keine
> Notwendigkeit drin sehen.

Ich schon. Und wenn es nur darum geht, dem Schaltplan zu entnehmen, um 
welchen Controller und ADC es sich handelt.

von tescht (Gast)


Lesenswert?

Softwarehysterese:
Wenn aktueller gemessener Wert um x Einheiten vom vorherigen 
akzeptierten Wert abweicht, dann akzeptiere gemessenen Wert und mache 
ihn zum gültigen Wert.

von Fragr (Gast)


Lesenswert?

> Wenn aktueller gemessener Wert um x Einheiten vom vorherigen
> akzeptierten Wert abweicht, dann akzeptiere gemessenen Wert und mache
> ihn zum gültigen Wert.

Check. Ich danke dir!

von Falk B. (falk)


Lesenswert?

@Fragr (Gast)

>An der Schaltung lässt sich nicht viel ändern, aber trotzdem eine kurze
>Beschreibung: AVCC liegt über einem Kondensator an GND und über eine
>Spule an VCC. VCC kommt über einem Step-Down. Schwankungen dort sollten
>aber relativ unwichtig sein, oder?

Oder. Schaltregler sind nur allzuoft böse Störquellen. Ersetz den mal 
probehalber durch ein Labornetzteil oder einen Linearregler.

>(ratiometrische Messung).

Ist egal, hier geht es um HF-Störungen.

>Ich habe keine Ansatz wie ich das lösen könnte und freue mich über eure
>Tipps.

Man könnte eine Hysterese einbauen, die erst bei einer Änderung >=2 
einen neuen Wert anzeigt. Aber vorher sollte man alle anderen Mittel 
ausschöpfen.

von Thomas (kosmos)


Lesenswert?

stell mal den ADC Takt langsamer ein obs dann stabiler wird?

von Fragr (Gast)


Lesenswert?

> Oder. Schaltregler sind nur allzuoft böse Störquellen. Ersetz den mal
> probehalber durch ein Labornetzteil oder einen Linearregler.

Oh ja, daran kann es natürlich liegen, da ich folgendes nicht wusste:

>> (ratiometrische Messung).

> Ist egal, hier geht es um HF-Störungen.

Vermutlich sind die Störungen schneller als der ADC seine Referenz 
übernimmt oder woran liegt das?

> Aber vorher sollte man alle anderen Mittel ausschöpfen.

Alles klar. Was kann ich neben Linearregler noch tuen? Wäre ein 
Kondensator (~10nF) zwischen Mittelabgriff und ADC sinnvoll?

Beste Grüße.

von Joe F. (easylife)


Lesenswert?

Falk B. schrieb:
> Man könnte eine Hysterese einbauen, die erst bei einer Änderung >=2
> einen neuen Wert anzeigt. Aber vorher sollte man alle anderen Mittel
> ausschöpfen.

Die Hysterese ist die einzige Möglichkeit das Problem zu beseitigen.
Egal wie minimal das Rauschen ist, selbst bei gut gemittelten Messwerten 
kommt es schon durch minimalstes Rauschen zum hin- und herspringen:

33.99999999 -> 33
34.00000000 -> 34

Da du ja 256 Werte interpolierst, kann die Hysterese unter 0.5 liegen, 
so dass keine Schritte verloren gehen.

: Bearbeitet durch User
von Fragr (Gast)


Angehängte Dateien:

Lesenswert?

> stell mal den ADC Takt langsamer ein obs dann stabiler wird?

Hey. Der Takt liegt bei etwa 125kHz, was auch (meines Wissens nach) 
absolut im Rahmen ist. Immerhin darf die Messung weder zu schnell noch 
zu langsam erfolgen (zwischen 50kHz und 200kHz sollte es sein glaube ich 
- ausm Kopf).

Übrigens habe ich den Schaltplan vergessen, was ich jetzt nachhole. An 
den Pins, wo nur ein Stück Wire anliegt, sind die Anzeigen 
angeschlossen. Ich habe den Schaltplan leider nicht vorliegen und habe 
das eben schnell nachgezeichnet. Verzeiht mir daher, dass es nicht alles 
ist.

von Falk B. (falk)


Lesenswert?

@ Fragr (Gast)


>Alles klar. Was kann ich neben Linearregler noch tuen? Wäre ein
>Kondensator (~10nF) zwischen Mittelabgriff und ADC sinnvoll?

Ja.

von W.A. (Gast)


Lesenswert?

Fragr schrieb:
> Ein Potentiometer wird ratiometrisch ausgelesen und oversampled (256
> mal) und schließlich dezimal ausgegeben.

Fragr schrieb:
> Übrigens habe ich den Schaltplan vergessen, was ich jetzt nachhole.

Das Poti darf natürlich nicht an den verdreckten 5V hängen, sondern muss 
mit der Referenz laufen. Was ist da dran sonst ratiometrisch?

von Falk B. (falk)


Lesenswert?

@ Joe F. (easylife)

>> Man könnte eine Hysterese einbauen, die erst bei einer Änderung >=2
>> einen neuen Wert anzeigt. Aber vorher sollte man alle anderen Mittel
>> ausschöpfen.

>Die Hysterese ist die einzige Möglichkeit das Problem zu beseitigen.

Jain.

>Egal wie minimal das Rauschen ist, selbst bei gut gemittelten Messwerten
>kommt es schon durch minimalstes Rauschen zum hin- und herspringen:

Aber nur, wenn die Eingangsspannung ziemlich genau zuwischen 2 
AD-Quantisierungsbereichen liegt. Normale Digitalanzeigen auf 
Multimetern flackern auch nicht immer wild rum.

>Da du ja 256 Werte interpolierst,

Er interpoliert gar nichts, er bildet einen Mittelwert. Das ist was 
anderes.

von Joe F. (easylife)


Lesenswert?

Falk B. schrieb:
>>Egal wie minimal das Rauschen ist, selbst bei gut gemittelten Messwerten
>>kommt es schon durch minimalstes Rauschen zum hin- und herspringen:
>
> Aber nur, wenn die Eingangsspannung ziemlich genau zuwischen 2
> AD-Quantisierungsbereichen liegt.

was eben passieren kann.

> Normale Digitalanzeigen auf
> Multimetern flackern auch nicht immer wild rum.

da dort sinnvollerweise auch unterhalb der Anzeigegrenze eine Hysterese 
implementiert ist.

>
>>Da du ja 256 Werte interpolierst,
>
> Er interpoliert gar nichts, er bildet einen Mittelwert. Das ist was
> anderes.

Das stimmt. Suldijung.
Ändert aber am Problem nichts.

von Fragr (Gast)


Lesenswert?

Alles klar. Danke dann soweit.
Ich versuche es also mit dem Linearregler, dem Kondensator und 
vielleicht dann auch mit der Hysterese :)

Bislang sieht das nur so aus:
1
void getdigit(uint32_t value)
2
{
3
 uint32_t grad = (value *3291) / 10000;
4
d[0] = (grad /100);
5
d[1] = grad % 100) / 100;
6
d[2] = grad %10
7
}

Ich bekomme einen 10 bit Wert. Soll ich das letzte Bit einfach verwerfen 
für die "Hystereseprüfung"? Wenn der Wert mehr abweicht, dann nehme ich 
den neuen?


> Das Poti darf natürlich nicht an den verdreckten 5V hängen, sondern
> muss mit der Referenz laufen. Was ist da dran sonst ratiometrisch?

Wenn ich das richtig verstanden hat, so bezeichnet die ratiometrische 
Messung eine "Verhältnis"messung. Deswegen dachte ich, es kann direkt an 
5V, da ich ja nicht den Strom bzw. anliegende Spannung messe, sondern 
der Verhältnis.
Ich hoffe, ich kann das noch mit dem Linearregler richten.

von W.A. (Gast)


Lesenswert?

Joe F. schrieb:
> Ändert aber am Problem nichts.

Am Problem wird man sowieso nichts ändern können. Das gibt es bei jeder 
verrauschten Messung. Und wenn keine Hysterese bei der Anzeige 
implementiert ist, sieht man das Rauschen eben auch in der Anzeige.

von Falk B. (falk)


Lesenswert?

@ Fragr (Gast)

Besser so.
1
void getdigit(uint32_t adc_val)
2
{
3
  uint32_t grad = (adc_val * 3291) / 10000;
4
5
  d[2] = grad % 10; grad /= 10;
6
  d[1] = grad % 10; grad /= 10;
7
  d[0] = grad %10;
8
}

>Ich bekomme einen 10 bit Wert. Soll ich das letzte Bit einfach verwerfen
>für die "Hystereseprüfung"?

Nein.

> Wenn der Wert mehr abweicht, dann nehme ich den neuen?

Das Problem bei der Hysterese ist, dass du einen blinden Bereich hast. 
Wenn sich nämlich dein Meßwert langsam ändert, bekommst du das nur 
versüätet bis gar nicht mit, eben weil nur große Änderungen angezeugt 
werden. So eine Hysteres ist meistens ein Würg-Around.

>>> Das Poti darf natürlich nicht an den verdreckten 5V hängen, sondern
>>> muss mit der Referenz laufen. Was ist da dran sonst ratiometrisch?

>Ich hoffe, ich kann das noch mit dem Linearregler richten.

Gehe schrittweise vor, mach eine Änderung nach der anderen und prüfe das 
Ergebnis.

: Bearbeitet durch User
von tescht (Gast)


Lesenswert?

messen
10 Bit Wert zum Vergleich bei nächster Messung sichern.
 9 Bit anzeigen, also letztes (LSB) verwerfen (right shift)

Label:
messsen
Mit gesichertem 10 Bit Wert vergleichen. Abweichung größer zB eins?
Ja, dann gerade gemessenen 10 Bit Wert sichern. Letztes Bit verwerfen 
(right shift) und 9 Bit Wert anzeigen.
weiter bei Label

(Unterschied größer zB 3? -> 2 mal shift right)

AVCC ist Versorgung von ADC (irgendwo in Datenblatt zu finden). Poti 
statt an Vcc besser an AVCC

von Falk B. (falk)


Lesenswert?

@ tescht (Gast)

>10 Bit Wert zum Vergleich bei nächster Messung sichern.
> 9 Bit anzeigen, also letztes (LSB) verwerfen (right shift)

Nürtz dir wenig bis nichts, wenn die Spannung auf der Kippe steht. Nur 
dass die Bereiche dazwischen größer sind.

von Hermann (Gast)


Lesenswert?

Joe F. schrieb:
> Die Hysterese ist die einzige Möglichkeit das Problem zu beseitigen.

Das habe ich noch nie gehört. Rundung sollte man als erstes machen. Dann 
sind die Probleme mit:
> 33.99999999 -> 33
> 34.00000000 -> 34
weg.
Und außerdem: Rauschen ist bei Überabtastung sogar unbedingt 
erforderlich!
Wers nicht glaubt, bitte mal hier in Kap.3.2 nachlesen:
http://www.atmel.com/Images/doc8003.pdf

Ich habe ähnliche schwankende Messungen, wenn ich auf meinem 
Programmierboard messe, das über USB-5V versorgt wird. Also unbedingt 
Vcc gut filtern und sauberen Sternpunkt für Masse. Dann darf so etwas 
nicht passieren.

von Fragr (Gast)


Lesenswert?

> Das habe ich noch nie gehört. Rundung sollte man als erstes machen.
> Dann sind die Probleme mit:
>> 33.99999999 -> 33
>> 34.00000000 -> 34
> weg.

Naja, dann hat man das Problem bei 33.4999999 statt bei 33.9999999.

Ich werde erst einmal versuchen einen Linearregler und die 10nF zwischen 
ADC-Kanal und Messpunkt zu packen. Vielleicht ist dadurch bereits mein 
Problem gelöst.

von Falk B. (falk)


Lesenswert?

@ Hermann (Gast)

>Das habe ich noch nie gehört. Rundung sollte man als erstes machen. Dann
>sind die Probleme mit:
>> 33.99999999 -> 33
>> 34.00000000 -> 34
>weg.

Nö, sie verschieben sich nur um 0,5 ;-)
Das Wackeln eines ADC auf Kante ist prinzipbedingt! Das geht nicht 
anders, nur mit Tricks.

>Und außerdem: Rauschen ist bei Überabtastung sogar unbedingt
>erforderlich!

Stimmt. Aber ein Mangel an Rauschen bzw. überlagerten Störungen ist hier 
selten der Fall ;-)

von Walter S. (avatar)


Lesenswert?

Fragr schrieb:
> und die 10nF zwischen
> ADC-Kanal und Messpunkt zu packen

wie meinst du das?
Ich würde zwischen ADC-Eingang und GND empfehlen

von Hermann (Gast)


Lesenswert?

Falk B. schrieb:
> Nö, sie verschieben sich nur um 0,5 ;-)

Stimmt! Trotzdem macht Rundung Sinn.

von Thomas (kosmos)


Lesenswert?

welchen Widerstandswert hat eigentlich dein Poti? Wenn dieser zu hoch 
ist wirkt sich die Kapazität der S&H Stufe auf das Signal aus, der Kerko 
soll dann das ganze stützen. Durch den niedrigeren Takt, gibt man dem 
Umladevorgang etwas mehr Zeit.

von N.Oise (Gast)


Lesenswert?

Solange die Hysterese größer ist, als die Rauschamplitude, wird alles 
gut.

von Fragr (Gast)


Lesenswert?

> welchen Widerstandswert hat eigentlich dein Poti?

10k Ohm. Je nach Wetter werden andere Werte als 'optimal' bezeichnet.
Bei 10k Ohm habe ich aber weniger bedenken. Im Datenblatt steht, meine 
ich, der Wert sollte 100k nicht übersteigen.

> Ich würde zwischen ADC-Eingang und GND empfehlen

ähm, ja genau :)

von eProfi (Gast)


Lesenswert?

Besser so:
 uint32_t grad = (value *2696) / 8192;
das /8192 wird mit 13 mal nach rechts schieben erledigt.

Noch besser: wenn Du eh 32 bit nimmst, geht es so noch schneller:
 uint32_t grad = value * 21568L; //337*64
 uint16_t disp = grad / 65536L; //der schlaue Compiler macht das mit 
einem movw  bzw. er rechnet nur mit dem High-Word weiter
//für die folgende Rechnung reichen 16 Bits
  d[2] = disp % 10; uint8_t dis2 = disp / 10;
//für die folgende Rechnung reichen 8 Bits
  d[1] = dis2 % 10; dis2 /= 10;
  d[0] = dis2 % 10;

hier mal ein ganz anderer Ansatz mit 2 Tabellen von 2008:
Beitrag "ADC-Wert z.B. in Spannung umrechnen und dezimal ausgeben mittels Tabellen, auch Linearisieren"

von tescht (Gast)


Lesenswert?

Falk B. schrieb:
> @ tescht (Gast)
>
>>10 Bit Wert zum Vergleich bei nächster Messung sichern.
>> 9 Bit anzeigen, also letztes (LSB) verwerfen (right shift)
>
> Nürtz dir wenig bis nichts, wenn die Spannung auf der Kippe steht. Nur
> dass die Bereiche dazwischen größer sind.


Bitte auch mit folgenden Zeilen gemeinsam betrachten wie in originaler 
message:

tescht schrieb:
1
> messen
2
> 10 Bit Wert zum Vergleich bei naechster Messung sichern.
3
>  9 Bit anzeigen, also letztes (LSB) verwerfen (right shift)
4
> 
5
> Label:
6
> messsen
7
> Mit gesichertem 10 Bit Wert vergleichen. Abweichung groesser zB eins?
8
> Ja, dann gerade gemessenen 10 Bit Wert sichern. Letztes Bit verwerfen
9
> (right shift) und 9 Bit Wert anzeigen.
10
> weiter bei Label

Es gab hier im Forum gute Diskussion um Hysterese in SW. Kann gerade 
nicht wiederfinden.


Fragr schrieb:
> Wenn ich das richtig verstanden hat, so bezeichnet die ratiometrische
> Messung eine "Verhältnis"messung. Deswegen dachte ich, es kann direkt an
> 5V, da ich ja nicht den Strom bzw. anliegende Spannung messe, sondern
> der Verhältnis.

tescht schrieb:
> AVCC ist Versorgung von ADC (irgendwo in Datenblatt zu finden). Poti
> statt an Vcc besser an AVCC

Also oberen Anschluß von Poti nicht an +5V sondern an den mit 
Induktivität und Kondensator entstörten AVCC Anschluß von µC versuchen.

von Sebastian L. (der_mechatroniker)


Lesenswert?

Ich hätte jetzt nach jeder Messung so etwas gemacht:
1
// ggf. mit diesem Wert rumspielen
2
#define HYSTERESE 1 
3
4
if (inputValue > internalValue + HYSTERESE)
5
    internalValue = inputValue - HYSTERESE;
6
if (inputValue < internalValue)
7
    internalValue = inputValue;

Und das vor (!) der Dezimierung von der vollen ADC-Bitbreite auf den 
Anzeigebereich.

von pcrom (Gast)


Lesenswert?

Ich weisz nicht was genau die Applikation ist und wie die Meszwert 
gezeigt wird, aber auf jeden fall kannst du die Anzeige und weiter 
benutzing dieser Wert auseinander ziehen.

Wenn die wert zB 100x pro sekunde neu gemessen und benutzt wird, reicht 
es oft nur 1 oder 2x pro sekunde Anzuzeigen. Dann hat man ein weniger 
nervoeses signal auf dem Anzeiger.

von M. K. (sylaina)


Lesenswert?

Fragr schrieb:
> Immerhin darf die Messung weder zu schnell noch
> zu langsam erfolgen (zwischen 50kHz und 200kHz sollte es sein glaube ich
> - ausm Kopf).

Das gilt nur für full resolution. Du kannst den ADC auch mit 1 MHz 
takten, dann ists nur nicht mehr auf 10 bit genau sondern eher so um die 
8-9 bit. (Wandlerrauschen nimmt zu)

von Thomas (kosmos)


Lesenswert?

oder du mittelst es für die Anzeige noch länger als für das restliche 
Prog nach 256 mal wird eben der Wert in Register 16 geschrieben und 
Register 17 erst nach 1024 mal.

Um welche Spannungsbereiche handelt es sich eigentlich, vielleicht 
kannst du durch Anpassung der Referenzsspannung an das Messsignal eine 
genauere Messung erhalten?

Sind überhaupt 8,9 oder 10 Bits Auflösung nötig nicht das dann 
vielleicht eine Motor PWM auch mit 16 oder 32 Stellungen auskommt?

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
Noch kein Account? Hier anmelden.