Hallo,
folgendes Problem habe ich mit einem Programm in welchen ein ADC
abgefragt wird.
Die Referenzspannung des ADC liegt bei 5V. Eingelesen werden Spannungen
von 0-2V.
Das heißt die 1024 "Schritte" werden nicht ausgereizt. Damit das
geschieht habe ich einfach den Wert der vom ADC eingelesen wird mit 3
multipliziert. Nun ist zwar der Bereich größer aber die Werte schwanken.
Ist es nun besser die Referenzspannung abzusenken nahe 2V oder kann es
nicht an der Softwaretechnischen Verstärkung liegen sondern der ADC ist
einfach ungenau?
Oder ist es möglich das eine Verstärkung also Nachberechnung mit
Wandlung von INT in FLOAT und wieder in INT einfach meinen ATmega 168
mit 16MHz etwas ausbremst und daher die Werte so schwanken?
> Das heißt die 1024 "Schritte" werden nicht ausgereizt. Damit das> geschieht habe ich einfach den Wert der vom ADC eingelesen wird mit 3> multipliziert. Nun ist zwar der Bereich größer aber die Werte schwanken.
Dadurch wird doch nix genauer:
0 -> 0
1 -> 3
2 -> 6
3 -> 9
...
Hallo,
wie kommst du denn auf 3?
5/2=2,5 wäre deine "Verstärkung" aber hast du denn das mal
durchgerechnet?
Aref/1024bit = V/bit
5/1024 = 0,00488...mV/bit.
410bit*0,00488mV/bit= 2,0008V *2,5 =5,002V
= 2,0008V *3 =6,0024V
Christian F. schrieb:> Dadurch wird doch nix genauer:> 0 -> 0> 1 -> 3> 2 -> 6> 3 -> 9> ...
Nicht? Von 1 auf 2 ist 1 bit dazwischen von 3 auf 6 sind 3 bit.
chris schrieb:> wie kommst du denn auf 3?>> 5/2=2,5 wäre deine "Verstärkung" aber hast du denn das mal> durchgerechnet?>> Aref/1024bit = V/bit> 5/1024 = 0,00488...mV/bit.>> 410bit*0,00488mV/bit= 2,0008V *2,5 =5,002V> = 2,0008V *3 =6,0024V
Es sind nicht 2 V die anliegen sondern 1.12V. Daher bin ich auf 3. nach
oben wollte ich etwas Reserve lassen.
Piere schrieb:> Christian F. schrieb:>> Dadurch wird doch nix genauer:>> 0 -> 0>> 1 -> 3>> 2 -> 6>> 3 -> 9>> ...>> Nicht? Von 1 auf 2 ist 1 bit dazwischen von 3 auf 6 sind 3 bit.
genial, also lässt sich die Genauigkeit einfach durch multiplizieren
steigern
Piere schrieb:> Christian F. schrieb:>> Dadurch wird doch nix genauer:>> 0 -> 0>> 1 -> 3>> 2 -> 6>> 3 -> 9>> ...>> Nicht? Von 1 auf 2 ist 1 bit dazwischen von 3 auf 6 sind 3 bit.
Das ist aber nicht genauer.
Ob du deine Werte von 0 bis 250 durchnummerierst oder von 0 bis 750 in
3-er Schritten kommt sich letzten Endes aufs selbe raus: Du hast nur 251
Schritte.
Wie du die dann 'nennst', ob 0-250 oder 0-750(3) oder "rot", "rosa",
"rostrot", "leichtgelb", .... ist ja völlig wurscht. 251 unterscheidbare
Werte sind 251 unterscheidbare Werte und nicht mehr.
Piere schrieb:> Nicht? Von 1 auf 2 ist 1 bit dazwischen von 3 auf 6 sind 3 bit.
Nein. Zwar hast du Recht, aber die Bits dazwischen (4,5) werden nie
gesetzt. Demnach wird das ganze so nicht genauer, sondern allenfalls
schwerer auszuwerten.
Piere schrieb:> Ich Versuch eigentlich künstlich den vollen 1024bit BEreich auszunutzen
Grundregel in der Informatik:
Information, die weg ist, ist weg.
Wenn deine Hardware Situation so ist, dass du 251 unterscheidbare
Eingangswerte hast, dann hast du eben nicht mehr. Egal auf welche
anderen Zahlenbereiche du die Dinge umrechnest. Aus 10 Paar Socken
werden nicht mehr, nur weil du auf das erste Paar 1 draufschreibst, auf
das 2.te 4, das 3.te 7, etc. etc.
Christian F. schrieb:> Nein. Zwar hast du Recht, aber die Bits dazwischen (4,5) werden nie> gesetzt. Demnach wird das ganze so nicht genauer, sondern allenfalls> schwerer auszuwerten. Oder irre ich total?
Stimmt, er kann ja nur 1, 2, 3 einlesen, nicht 1.1 oder 1.2 daher wird
da zwischen der Bereich nie gesetzt. Also setzte ich die
Referenzspannung herunter um die Auflösung zu verbessern.
Piere schrieb:> wieso wird es ungenauer
Wer sagt denn das? (Abgesehen davon, dass man es vermeiden sollte auf
AVR künstlich float Variablen zu erzeugen, die man absolute nicht
braucht.)
Piere schrieb:> Oder bremst das erzeugen der floats zu sehr aus?
Das kommt drauf an, wie stark dein Strom wirklich schwankt.
Aber hier weiß ja keiner was du misst (Gleichstrom - Wechselstrom), wie
deine Hardware aussieht, bzw. was du mit den Messwerten sonst noch so
alles anstellst, ehe dann irgendwann mal eine Zahl auf der Ausgabe
landet.
Ich messe den Strom an einer Bohrmaschine.
Aller 10ms wird gemessen.
Wenn der gemessene Wert einen Wert x überschreittet soll die Maschine
ausschalten.
Vor der Berechnung macht sie es immer am gleichen Punkt, nach der
Berechnung oder Verstärkung immer mal früher oder später.
Piere schrieb:> Ich messe den Strom an einer Bohrmaschine.> Aller 10ms wird gemessen.> Wenn der gemessene Wert einen Wert x überschreittet soll die Maschine> ausschalten.> Vor der Berechnung macht sie es immer am gleichen Punkt, nach der> Berechnung oder Verstärkung immer mal früher oder später.
Quellcode und Schaltplan wären sinnvoll, um die Probleme verstehen zu
können.
>Ist es nun besser die Referenzspannung abzusenken nahe 2V oder kann es>nicht an der Softwaretechnischen Verstärkung liegen sondern der ADC ist>einfach ungenau?
Der ADC des Atmega ist recht genau, aber ich vermute deine 5V haben
einen großen Ripple. Außerdem ist eine 5V-Quelle aus einem
Spannungsregler o.ä. immer selbst sehr ungenau und bringt ebenfalls
gerne einen Ripple mit. Daher hat der AVR von Haus aus eine 2,56V
Referenzquelle eingebaut, die nur noch einen externen 100nF-Kerko
braucht. Wenn du es also genau haben willst, besorg dir eine externe
Referenzspannungsquelle oder nimm die interne des Atmega. Sonst funkt
dir dein Ripple immer rein.
Den Vref auf die Versorgung zu hängen macht nur Sinn, wenn du Potis
einlesen willst die auch über GND und VCC hängen. Dann schwankt die
Versorgung der Potis mit Vref und du hast zumindest relativ zur
Poti-Position immer den richtigen Wert. Auf Überabtastung komm ich dann
mal unten....
>Oder ist es möglich das eine Verstärkung also Nachberechnung mit>Wandlung von INT in FLOAT und wieder in INT einfach meinen ATmega 168>mit 16MHz etwas ausbremst und daher die Werte so schwanken?
Dein ADC läuft immer mit der selben Geschwindigkeit PARALLEL, deshalb
nennt sich das Ding ja auch ADC-Peripherie. Du stupst ihn an und er
meldet sich, wenn er fertig ist und legt die den passenden Wert im
ADC-Register ab, im INT-Mode kriegst du einen Interrupt, im Free-Running
Mode holst du aus dem ADC-Register nur den jeweils letzten Wert und im
Polling-Mode ist er schon lange fertig, bist du vorbeiläufst, das Flag
einliest und dann weiterrechnest.
Ja du kannst je nach Reihenfolge deiner Float/Int-Rechenoperationen eine
Menge Infomration verlieren und deine Auflösung noch weiter
verschlechtern. Deshalb macht man das auch optimiert auf
INT/longINT-Anweisungen und nicht mit Floats. Selbst wenn es ein
schnellerer Prozessor mit breiterem Bus wäre, kommt es immer noch auf
die Reihenfolge der INT/Float-Befehle an!
Ich hab das mal zur Basis 10 gemacht, eigentlich macht man das dann für
den µC optimiert zur Basis 2....
Wenn du also mV/µV haben möchtest, dann nimm longINT und mache das hier:
ADCinMicroV=ADC*48876; // 5000/1023=4,887586; longInt bis 2e^9
ADCinMicroV=ADCinMicroV/10; //jetzt ist es in microVolt...
ADCinMilliVolt=ADCinMicroV/1000; //jetzt ist es in MilliVolt, INT reicht
Jetzt machst du zwar nicht wirklich was kaputt durch die Rechnerei, aber
du erhälst deswegen keine Auflösung im µV-Bereich!!!
Jetzt zum Oversampling: Prinzipiell kann man Wechselspannungsmessungen
künstlich aufwerten und tatsächlich ein paar Bits mehr rausholen, wenn
man mehrmals hintereinander misst und die Werte zusammenfasst. Das geht
aber nicht bei Gleichspannungen! Dazu kommt ein passender
AntiAliasing-Filter vor den ADC, ausgelegt auf die Zielfrequent von
100Hz, z.B. ein RC-Glied. Dein ADC tastet jetzt aber mit, sagen wir
800Hz ab. Je Verdoppelung der Abtastrate holst du dir ein halbes Bit.
Bei 800Hz gegenüber 100Hz bist du achtfach drüber, also 2^3. Das macht
zurechtgebogene 3*0,5=1,5Bit mehr.
Wenn du jetzt auf milliVolt rechnen möchtest, akkumulierst du zuerst 8
Werte aus dem ADC-Register, was einen maximal möglichen Wert von
8*1023=8184 ergibt. Also eine Auflösung von ungefähr(!)
5000mV/8184=0,610948mV
Das ganze hat in der Realität noch ein paar Schwierigkeiten, auf die
sich hier die anderen sicherlich sofort besserwisserisch stürzen
werden...
Aber das ganze macht auch bei "Gleichspannungen" Sinn, wenn diese doch
mal zappeln. Das schlägt sich im LSB nieder, dem kannst du durch
zusammenfassen/mitteln mehrerer ADC-Werte entgegen wirken.
- Pass die Reihenfolge deiner Berechnung an und mach es am besten
komplett
in longInt und dann runter auf INT, ohne Floats.
- Nimm eine ordentliche Referenz für den ADC (2,56V intern)
- Fasse ADC-Werte zusammen um Schwankungen im LSB entgegen zu wirken
- Hast du an einen Tiefpassfilter am ADC-Eingang gedacht?
- Zeig mal den Code. Welche Bereiche willst du abbilden? 0-2V auf 0-?A
Du solltest schneller messen und einen Mittelwert über n Werte bilden
und diesen auswerten. Daher, miss alle 1ms, bilde das gleitende mittel
über 8 Werte. Welche Genauigkeit und Auflösung brauchst du wirklich?
Sollte kein Problem sein mit nem OPV den Messbereich an deine Referenz
anzupassen. Hier kleinen Alaising Filter mit fg ~ 1kHz vorsehen.
Ingo
René B. schrieb:> Der ADC des Atmega ist recht genau, aber ich vermute deine 5V haben> einen großen Ripple. Außerdem ist eine 5V-Quelle aus einem> Spannungsregler o.ä. immer selbst sehr ungenau und bringt ebenfalls> gerne einen Ripple mit.
Und wenn sowohl der ADC wie auch das zu messende Ding mit der gleichen
"verseuchten" Spannung versorgt werden, dann ist das Signal aus dem ADC
ziemlich stabil. Schließlich werden nur zwei Spannungen verglichen.
René B. schrieb:> Den Vref auf die Versorgung zu hängen macht nur Sinn, wenn du Potis> einlesen willst die auch über GND und VCC hängen. Dann schwankt die> Versorgung der Potis mit Vref und du hast zumindest relativ zur> Poti-Position immer den richtigen Wert. Auf Überabtastung komm ich dann> mal unten....
Nope. s.o.
René B. schrieb:> im INT-Mode kriegst du einen Interrupt, im Free-Running> Mode holst du aus dem ADC-Register nur den jeweils letzten Wert und im> Polling-Mode ist er schon lange fertig, bist du vorbeiläufst, das Flag> einliest und dann weiterrechnest.
Seit wann gibt es denn einen INT-Mode beim AVR-ADC?
Das IF wird gesetzt, sobald der Wandler mit der Wandlung durch ist -
egal ob Freerunning Mode oder Single Conversion.
Das wird
im Datenblatt des ATTiny26 wird ein LC-Filter von 10µH und 100nF für
AVCC empfohlen, steht bei den neueren Typen nicht mehr drin kann aber
sicherlich nicht schaden. VCC und AREF kann man dadurch auch filtern.
Wenn man vor dem Ripple des Spannungsreglers Angst hat.
René B. schrieb:> Daher hat der AVR von Haus aus eine 2,56V> Referenzquelle eingebaut, die nur noch einen externen 100nF-Kerko> braucht.
Wo kommt der Kerko dazwischen? AREF und GND?
Ingo/STK Erst lesen, dann posten...
>(..)einen Mittelwert über n Werte bilden(..)
Zitat ich selbst:
>- Fasse ADC-Werte zusammen um Schwankungen im LSB entgegen zu wirken>Schließlich werden nur zwei Spannungen verglichen.
Die Einschränkung steht dabei. Poti vs. Shunt, denk mal drüber nach.
Netterweise hast du es ja selbst darunter zitiert.
>Seit wann gibt es denn einen INT-Mode beim AVR-ADC?
Auf eine Jahreszahl will ich mich mal nicht festlegen, aber ein ADC ohne
INT-Mode auf einem Prozessor, der INTs unterstützt macht wenig Sinn.
Schau mal ins DB der Atmegas, bevor du vorschnell was postest.
Auch atmegas sind AVRs mit ADC. z.B. mega8/16/32/644/128 haben nicht
umsonst im ADCSRA-Register ein ADIE-Bit (INT-enable) und die passende
ISR dazu.
Wie will man auch sonst konstante Abtastraten hinkriegen, dann wären die
Prescaler-Einstellungen ja auch sinnlos. Polling/FreeRunning ist für
quick'n'dirty-Implementationen.
> Wo kommt der Kerko dazwischen? AREF und GND?
Genau, AREF und GND mit Kerko und intern die Register auf 2,56V
konfigurieren. Ich meine das wären im ADMUX-Register die REFSx-Bits.
René B. schrieb:> Wie will man auch sonst konstante Abtastraten hinkriegen, dann wären die> Prescaler-Einstellungen ja auch sinnlos. Polling/FreeRunning ist für> quick'n'dirty-Implementationen.René B. schrieb:> Ingo/STK Erst lesen, dann posten...
dito.
Dein INT-Mode ist kein expliziter ADC-Modus. So kam das in deinem Post
leider rüber. Mehr wollte ich nur klarstellen.
Ja, bei den 1,8V-fähigen Reihen findest du eine interne 1,1V-Referenz.
So dummerweise auch der mega168.
Hier wird es jetzt ein wenig kniffliger. Am AREF bleibt nach wie vor ein
100nF-Kerko und die Register für die interne Referenz werden gesetzt.
Allerdings solltest du jetzt dein Signal am ADC-Eingang mit einem
Spannungsteiler herunterteilen, z.B mit zwei 1k-R. Du kannst dann
Spannungen bis 2,2V verarbeiten, das sollte reichen.
Wenn deine Signalquelle nicht mit 2k belastet werden darf, weil sie dann
einbricht, musst du einen Impedanzwandler (OPV) vorschalten. Wenn das
aber sowieso aus einer OPV-Schaltung rauskommt, wird das schon passen.
Piere schrieb:> Ich messe den Strom an einer Bohrmaschine.> Aller 10ms wird gemessen.
Falls die Bohrmaschine mit 50 Hz Wechselspannung läuft, solltest du
bezüglich der Wahl der Abtastrate noch mal Herrn Shannon konsultieren
René B. schrieb:> Ja, bei den 1,8V-fähigen Reihen findest du eine interne 1,1V-Referenz.> So dummerweise auch der mega168.>> Hier wird es jetzt ein wenig kniffliger. Am AREF bleibt nach wie vor ein> 100nF-Kerko und die Register für die interne Referenz werden gesetzt.> Allerdings solltest du jetzt dein Signal am ADC-Eingang mit einem> Spannungsteiler herunterteilen, z.B mit zwei 1k-R. Du kannst dann> Spannungen bis 2,2V verarbeiten, das sollte reichen.> Wenn deine Signalquelle nicht mit 2k belastet werden darf, weil sie dann> einbricht, musst du einen Impedanzwandler (OPV) vorschalten. Wenn das> aber sowieso aus einer OPV-Schaltung rauskommt, wird das schon passen.
Aber ich könnte auch einfach auf AREF über denn Spannungsteiler die 2V
anlegen oder? ich möchte ungern am ADC mit einem Spannungsteiler
arbeiten.
Ok, wenn du aus den 5V per Spannungsteiler 2V machst, hast du aber immer
noch die Schwankungen aus der Versorgung drauf, es sei denn es ist eine
gut stablisierte 5V-Referenzquelle.
Wie sieht denn die Schaltung aus, welche dort angeschlossen wird? Wenn
sie von dir ist, kannst du doch in der Verstärkung dort runter gehen, so
dass die 1,1V wieder passen.