Forum: Mikrocontroller und Digitale Elektronik Differential channels eines ATmega32 auslesen


von Dennis M (Gast)


Lesenswert?

Hallo, hätte da eine Frage,

möchte die "differential channels" meines ATmega 32 nutzen um Spannungen 
messen zu können, entweder positive oder negative.
Jetzt ist es so, dass ich zwei Spannungsquellen habe. Beide liegen am 
selben Ground. Die eine pos. Spannung liegt am ADC0, dei spannung die 
gemessen werden soll liegt an ADC1.
1
  ADMUX = 0x10;
2
        ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
3
4
        while (ADCSRA & (1<<ADSC) )     // auf Abschluss der 
5
        ;
6
7
  voltage = ADCL;       // mit uint16_t x
8
  voltage += (ADCH<<8); // in zwei Zeilen (LSB/MSB-Reihenfolge und
9
10
  sprintf(hallo_string,"V: %d\t%X ",voltage,voltage);
11
  uart_puts(hallo_string);

Der Wert den ich angezeigt bekomme, sollte sich folgendermaßen berechnen 
lassen,

ADC=((Vpos-Vneg)*GAIN*512)/Vref

wobei, Vpos==ADC0 und Vneg==ADC1

nun erhalte ich anstatt eines Wertes zwischen -511 un 512 einen Wert 
zwischen 0 und 1024. Bin momentan ratlos, warum!

z.B. kriege ich als Ausgabe des ADC 780,


wenn ich aber das ganze per Hand berechnen tu,
ADC=((3V-0,7V)*1*512)/5V=235, aber 1024-235=788 also gleicht dem Wert 
des ADC.

Bewege ich mich da momentan in die flasche Richtung?

von Avr N. (balze)


Lesenswert?

Dennis M schrieb:
> möchte die "differential channels" meines ATmega 32 nutzen um Spannungen
> messen zu können, entweder positive oder negative.

Negative Spannungen geht nicht ohne weiteres. (Datenblatt Seite 208)

22. Analog to Digital Converter
 22.1 Features
   0 - VCC ADC Input Voltage Range

Soll heissen, es sind nur positive Spannungen an den Eingaengen 
zulaessig.

Die Differenz zwischen zwei (bezogen auf den GND des µC positiven) 
Spannungen kann aber natuerlich auch negative werden.
AIP = 1V ; AIN = 3V => Ergebnis -2V

Willst Du wirklich negative Spannungen messen geht das nur mit etwas 
Aufwand.
Du musst dann Deine Spannungen in einen (bezogen auf den µC) positiven 
Bereich bringen und einen "virtuelle" Masse fuer AIN bereitstellen.
z.B.
AIN = 2,5V (feste virtuelle Masse)
AIP = 4V => gemessen +1,5V
oder
AIP = 0,8V => gemessen -1,7V

MfG,

Balze aka AVR Noob

P.S.: Habe den selben Fehler auch gerade hinter mir ;-)

von Avr N. (balze)


Lesenswert?

Dennis M schrieb:
>   voltage = ADCL;       // mit uint16_t x
>   voltage += (ADCH<<8); // in zwei Zeilen (LSB/MSB-Reihenfolge und

Ist voltage ein uint16_t ?
Das Ergebnis Deiner differentiellen Messung ist aber vorzeichenbehaftet!

Versuche mal einen int16_t.
Im Zweierkomplement wuerde das dann naemlich passen.

MfG,

Balze aka AVR Noob

von Dennis M (Gast)


Lesenswert?

Hallo,
also die voltage Variable ist bei mir als signed int definiert.
Was meinst du mit "virtuelle Masse", h.d. dass ich z.B. einen Pin des uC 
mit Spannung versorgen tu z.B. 2.5V, und diesen als Masse definiere?
Kann dir nicht ganz folgen.

Gruß

Dennis

von Avr N. (balze)


Lesenswert?

Dein differentieller ADC akzeptiert nur positve Spannungen an beiden 
Eingaengen.
Die Differenz aus beiden Spannungen kann also negativ werden.
Legst Du jetzt (z.B.) 2,5V auf Deinen AIN, und hebst Deine zu messenden 
Spannugen um diese 2,5V an, kannst Du auch Deine negative Spannung 
messen und bekommst auch Dein negative Ergebnis.

Damit sind diese 2,5 Volt Deine "virtuelle" Masse fuer die zu messenden 
Spannungen (natuerlich nicht die Masse Deiner Schaltung)

Aber so wie Du es in die Formel eingesetzt hast, sind ja beide Deiner 
Spannungen positiv (bezogen auf die µC Masse). Du hast also ein Problem 
mit der Zahlendarstellung.

(Datenblatt Seite 225)
When an ADC conversion is complete, the result is found in these two 
registers. If differential
channels are used, the result is presented in two’s complement form.

Das heisst, dass im hoechstwertigen Bit das Vorzeichen steht. Du 
solltest also Deinen ADC das Ergebnis mal links-bündig ausgeben lassen 
und anschliessend das Ergebnis durch 64 dividieren. (schieben um 6 nach 
rechts geht nicht, weil Dir dann das Vorzeichen verloren geht!)

MfG,

Balze aka AVR Noob

von Avr N. (balze)


Lesenswert?

0d780 = 0b1100001100

0b1100001100 im zweierkomplement = (minus)0b11110011

(minus)0b11110011 = -243

von Dennis M (Gast)


Lesenswert?

Also habe jetzt das Ergebnis linksbündig ausgegeben,

mit Vpos=0,69=ADC0
und Vneg=2,99=ADC1

mit der Formel kriege ich -153 raus und Ausgegeben bekomme ich -15400.
-15400*5V=-77000/512=-150(ADC)=-150/64=-2,3V was auch stimmt 
(0,69V-2.99V)
auch mit Vpos=0V stimmen die berechneten Werte mit den gemessenen 
überein. Das ist schon mal gut :)
Ich muss jetzt nur noch das mit der positiven Masse realisieren.

Vielen dank für die Hilfestellung Avr Noob.

Gruß

Dennis

von ADC (Gast)


Lesenswert?

Avr Noob schrieb:
> schieben um 6 nach
> rechts geht nicht, weil Dir dann das Vorzeichen verloren geht!

Wenn die Variable signed ist, wird nach "vorn" mit 1en aufgefüllt, so 
dass das Vorzeichen erhalten bleibt. Lediglich bei unsigned Variablen 
wird mit 0en aufgefüllt.

von Avr N. (balze)


Lesenswert?

Gerne!

Guck mal hier:
Beitrag "Re: Atmel Xmega synchrone ADCs / Quantisierungs + Schwingungs Problem"

So ist das auf meiner letzten Platine realisiert.

IC5 ist die Refernzspannungsquelle fuer die ADCs und fuer Dich eher 
uninteressant.

IC4a (OP AD820) stellt die halbe Betriebsspannung (3,3V/2) als virtuelle 
Masse zur Verfuegung. (XGND genannt) (Vielleicht nicht sooo guenstig 
weil Vcc keine tolle Referenz ist, aber fuer meinen Zweck ausreichend.)

Auf diese virtuelle Masse beziehen sich jetzt auch die beiden 
differentiellen Kanaele, die an IC2a und IC3a ankommen.

Die Beschaltung an IC2a (und IC3a) bringt mir ein Eingangssignal von +/- 
10V auf +/- 1V (bezogen auf XGND).

Bezogen auf mein SystemGND liegen die Signale zwischen 0,65V und 2,65V
3,3V/2-1V = 0,65V ; 3,3V/2+1V = 2,65V

Damit sind alle Signale positiv bezogen zu GND, differentiell kann ich 
aber +/- 1V messen.

MfG,

Balze aka AVR Noob

von Avr N. (balze)


Lesenswert?

ADC schrieb:
> Wenn die Variable signed ist, wird nach "vorn" mit 1en aufgefüllt, so
> dass das Vorzeichen erhalten bleibt. Lediglich bei unsigned Variablen
> wird mit 0en aufgefüllt.

STAUN, echt? Das ist mir neu und sehr cool.
Allerdings muesste dann mit dem MSB aufgefuellt werden, weil ja sonst 
auch positive Zahlen negativ wuerden. RICHTIG?

MfG,

Balze

von ADC (Gast)


Lesenswert?

Avr Noob schrieb:
> STAUN, echt? Das ist mir neu und sehr cool.
>
> Allerdings muesste dann mit dem MSB aufgefuellt werden, weil ja sonst
>
> auch positive Zahlen negativ wuerden. RICHTIG?

Hast recht, es wird bei signed natürlich mit dem MSB aufgefüllt.
Ich hatte das mal beim simulieren mitbekommen.

von Dennis M (Gast)


Lesenswert?

@ Avr Noob

Hi, wo hast du denn den OP AD820 her. Gibts sowas ähnliches bei Conrad 
oder Reichelt, was ich mit einer Spannung von 3,3 Volt versorgen kann 
und für den Zweck einer virtuellen Masse einsetzen könnte.

Gruß

Dennis

von Avr N. (balze)


Lesenswert?

Moin Dennis,

Dennis M schrieb:
> Hi, wo hast du denn den OP AD820 her.
Gibts z.B. bei Farnell

Dennis M schrieb:
> Gibts sowas ähnliches bei Conrad
> oder Reichelt, was ich mit einer Spannung von 3,3 Volt versorgen kann
> und für den Zweck einer virtuellen Masse einsetzen könnte.

Gibt es, ich bin aber eher ein OPAmp Leihe. Deshalb solltest Du hier mal 
recherchieren oder ggf. einen neuen Beitrag zur richtigen Auswahl des 
OPAmps einstellen.

Ein OPAmp mit Single Supply 2,7V - 5,5V ist beispielsweise dieser: 
AD8651
Ob dieser hierfuer geeignet ist, kann ich Dir allerdings nicht sagen. 
(Ist aber ein 16bit ADC Beispiel im Datenblatt.

MfG,

Balze aka AVR Noob

von Avr N. (balze)


Lesenswert?

Oh man,

Leihe = Laie

Vielleicht sollte ich vor dem Absenden mal lesen :)

von Dennis M (Gast)


Lesenswert?

Danke nochmals,

hier eine andere Frage. Könnte ich eventuell einfach einen 
Spannungsteiler anstatt eines OPs nehmen? Z.B. Zwei Widerstände gleicher 
Größe, der eine geht an Plus der andere an Ground, und die Massen meiner 
beiden Spannungsquellen, die ich mit dem uC messen möchte einfach 
zwischen diese zwei Wiederstände schalten. Habe das mal ausprobiert und 
ich kriege sogar richtige Spannungswerte raus, positive sowie negative. 
Kann man sowas machen oder bringt es Nachteile mit sich??

Gruß

Dennis

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.