Forum: Mikrocontroller und Digitale Elektronik Frage zur Bildung des Umrechnungsequivalents für einen AD-Wandler


von Anfangender Anfänger (Gast)


Lesenswert?

Hallo,

ich möchte gerne einen AD-Wandler auslesen. Mein Signal bekomme ich und 
muss es nun noch in eine Zahl umwandeln. Das ist sehr kompliziert. Der 
AD-Wandler hat eine Referenzspannung von 4,094 Volt und eine Bitbreite 
von 12bit.

12bit entspricht 2^12 = 4096 step

4,096 V/4096 steps = 0,001 V/step

Ich bekomme meine Antwort in Form von zwei 8bit-Integers hintereinander 
geliefert. Diese muss ich erst zu einem 12-bit-Integer ummodeln, um dies 
mit dem Umrechnungsequivalent zu multiplizieren, um auf den 
Spannungswert zu kommen.

Ich habe dazu einfach eine Shift- und Oder-Operation ausgeführt:

byte1 = 0b11110000
byte2 = 0b11110000

12bit = (byte2<<4) | (byte2>>4) (=111100001111)

dies kann ich mir auch einfach als Zahlenwert anzeigen lassen: 3855
Die Shift-Oder-Kombination zeigt, dass sie funktioniert.

Leider ist der gemessene Spannungswert um den Faktor 2 zu klein. Ich hab 
nen Spannungsteiler mit zwei gleichen Widerständen gebastelt und die 
Spannung sollte etwa 50 Prozent von vref betragen. Leider ist die 
Spannung, die ich aus den 12 bit lese, um den Faktor 2 zu klein. Der ADC 
zeigt 1,02 Volt an, obwohl 2,04 Volt am ADC anliegen. Ich habe mal 
probiert:

12bit = (byte2<<5), um nochmal ein Bit weiter nach oben zu gehen. Das 
ergibt aber für mich keinen Sinn, weil das ja eine 13-bit breite Antwort 
wäre, der ADC aber ja nur 12bit breit misst.

Was könnte mein Fehler sein?

von Achim S. (Gast)


Lesenswert?

Anfangender Anfänger schrieb:
> 12bit = (byte2<<4) | (byte2>>4) (=111100001111)

da wolltest du eigentlich etwas anders schreiben, oder? Byte 1 kommt zum 
Beispiel gerade gar nicht mehr vor.



Anfangender Anfänger schrieb:
> Was könnte mein Fehler sein?

Vielleicht dass der ADC bipolar misst? Dann werden die 12 Bit auf den 
Bereich von -Vref bis +Vref aufgeteilt, für den Bereich von 0 bis +Vref 
bleiben nur 11 Bit übrig. Macht genau einen Faktor 2

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Anfangender Anfänger schrieb:
> Anfangender Anfänger

passt schon mal - bitte sag uns mal, um welchen AD Wandler es da geht.

Anfangender Anfänger schrieb:
> 12bit = (byte2<<4) | (byte2>>4) (=111100001111)

Nö, so nicht. Du müsstest wenigstens byte1 irgendwo behandeln. Es ist 
immer vorteilhaft, den wahren Code zu schicken, und nicht irgendwas 
schnell (und hier bestimmt auch noch falsches) aus dem Code abzutippen.

von Anfangender Anfänger (Gast)


Lesenswert?

Achim S. schrieb:
> Vielleicht dass der ADC bipolar misst?

Nö, der ist so eingestellt, dass er monopolar misst.

Ich habe den Fehler gefunden - ich habe mir die Bits anzeigen lassen:

Beispiele

Byte1:
0b1011100
Byte2:
0b10000

Die Bytes werden irgendwie nicht mit 8bit-Breite angezeigt. Shifte ich 
jetzt Byte1 um vier nach rechts:

Result_Byte = Byte1<<4, dann ist es "nur" 11 Stellen breit. Aus 
irgendeinem Grund werden die vorangestellten Bits abgeschnitten, wenn 
sie Nullen sind :-( Ich müsste also erst vorher eine Testung vornehmen, 
wie die Bitbreite eines Bytes ist, um dann zu wissen, wie groß die 
Verschiebung sein muss :-(

Ich bekomme meine Daten wie folgt:

Import spidev
Import time

spi.open(0,0)

sendebyte = []
sendebyte.append(0b10001110)

spi.writebyte(sendebyte)
time.sleep(0.0001)
mybytes = spi.readbytes(2)

result=(mybytes[0]<<4)|(mybytes[1]>>4)
print (result)

der ADC ist ein Max186

von Anfangender Anfänger (Gast)


Lesenswert?

Matthias Sch. schrieb:
> Anfangender Anfänger schrieb:
>> 12bit = (byte2<<4) | (byte2>>4)

war ein Schreibfehler.

>> 12bit = (byte1<<4) | (byte2>>4)
dazu das Pythonequivalent:
result=(mybytes[0]<<4)|(mybytes[1]>>4)

von Thomas E. (thomase)


Lesenswert?

Anfangender Anfänger schrieb:
> Byte1:
> 0b1011100
> Byte2:
> 0b10000
>
> Die Bytes werden irgendwie nicht mit 8bit-Breite angezeigt. Shifte ich
> jetzt Byte1 um vier nach rechts:
>
> Result_Byte = Byte1<<4, dann ist es "nur" 11 Stellen breit.

Ja sicher. Die Zahl würde auch in 11 Bit passen. Weil sie nicht grösser 
ist!

Wenn du ein Thermometer hast, das bis 200° misst, also dreistellig und 
dieses dir die Raumtemperatur von 22° anzeigt, ist das jetzt kaputt, 
weil es nur 2-stellig anzeigt? Oder hat man die führende 0 von 022 
einfach weggelassen?

mfg.

von Anfangender Anfänger (Gast)


Lesenswert?

Thomas Eckmann schrieb:
> Wenn du ein Thermometer hast, das bis 200° misst, also dreistellig und
> dieses dir die Raumtemperatur von 22° anzeigt, ist das jetzt kaputt,
> weil es nur 2-stellig anzeigt? Oder hat man die führende 0 von 022
> einfach weggelassen?
>
> mfg.

Das muss man aber erstmal wissen - ich bin davon ausgegangen, dass der 
Datentyp immer 8bit breit ist. Darum bin ich ja auch noch anfangender 
Anfänger und kein Experte so wie Du oder so, der schon viele Jahre sich 
mit der Materie auskennt.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Anfangender Anfänger schrieb:
>>> 12bit = (byte2<<4) | (byte2>>4)
>
> war ein Schreibfehler.

Das meine ich damit, lieber den wirklichen Code zu posten und nicht 
falsch sich selbst zu zitieren.
Im Datenblatt zum MAX 186 steht, das das Ergebnis im ersten Byte mit 
einer führenden Null gesendet wird, direkt anschliessend kommt das 
zweite Byte mit 3 Nullen als LSB padding. Also:

uint16_t result = (byte1 << 5) | (byte2 >> 3);

von Anfangender Anfänger (Gast)


Lesenswert?

Matthias Sch. schrieb:
> Im Datenblatt zum MAX 186 steht, das das Ergebnis im ersten Byte mit
> einer führenden Null gesendet wird

Hey, danke für die Antwort. Dass hab ich wohl in dem Text nicht richtig 
gelesen. Kannst Du mir das mal kurz schreiben, auf welcher Seite das in 
dem Datenblatt steht? Ich habe in dem Datenblatt das Bild Figure6 auf 
Seite 12 angeschaut. Dort sieht man nicht, dass die Bits irgendwie mit 
einer Null/Eins anfangen. Auch bleibt das Problem bestehen, dass Bit1 
und Bit0 manchmal nicht genau 8bit Länge haben. Wenn Byte1 den Wert 1 
hat, dann interpreteiert das Python das irgendwie als 0b1 und nicht als 
0b00000001, shifte ich 5 Bits nach links, ist es immer noch zu kurz - so 
klappt es also nicht :-(

von Yalu X. (yalu) (Moderator)


Lesenswert?

Anfangender Anfänger schrieb:
> Kannst Du mir das mal kurz schreiben, auf welcher Seite das in
> dem Datenblatt steht?

Text auf Seite 11 und Abbildung 6 auf Seite 12.

Anfangender Anfänger schrieb:
> Wenn Byte1 den Wert 1 hat, dann interpreteiert das Python das
> irgendwie als 0b1 und nicht als 0b00000001,

Weil 0b1 und 0b00000001 exakt dasselbe sind, nämlich 1.

> shifte ich 5 Bits nach links, ist es immer noch zu kurz - so klappt es
> also nicht :-(

Doch. Hast du's probiert?

Beispiel: Die am ADC anliegende Spannung wird in den Wert 1234
umgesetzt.
1
             1234          Dezimal
2
               |
3
         010011010010      Binär mit 12 Stellen
4
            /     \
5
        0100110  10010     Aufteilen in einen 7- und einen 5-Bit-Teil
6
           |       |
7
       00100110  10010000  Hinzufügen der Pad-Bits
8
           |       |
9
          38      144      Dezimal
10
           |       |
11
         byte1   byte2     Zuweisung an Variablen

Python-Session:
1
>>> byte1 = 38
2
>>> byte2 = 144
3
>>> result = byte1<<5 | byte2>>3
4
>>> result
5
1234

Voilà :)

: Bearbeitet durch Moderator
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.