Zweiekomplement Problem

Gast #4084771
Lesenswert?
• ▲
▼
Hallo zusammen,

ich arbeite mit einem MSP430 und lese damit einen Beschleunigungssensor 
(H3LIS331DL) über I2C aus.
Dieser liefert mir einen 12-Bit Wert im Zweierkomplement jeweils für X,Y 
und Z.

Die Kommunikation über I2C funktioniert. Man kann die Device ID etc. 
auslesen. Die Werte stimmen.

ABER: Wenn ich z.B. den X-Wert auslese, während der Sensor in Ruhe ist 
bekomme ich folgende Werte:
1
x_LOW     = 96       // Untere 8-Bit als unsigned char
2
X_HIGH     = 255     // Obere 8-Bit als unsigned char
3
X_16_bit   = 65376   // x_value = ( (x_high << 8) | x_low); unsigned int
4
X_12_BIT   = 4086    // x_value_12 = (x_value / 16) unsigned int

Es gilt: 98 mg/digit

Ich werde aus den Werte einfach nicht schlau. Weiß Jemand einen Rat?
Herzlichen Dank im Vorraus.

MSPler
Gast #4084791
Lesenswert?
• ▲
▼
MSPler schrieb:
>
> ABER: Wenn ich z.B. den X-Wert auslese, während der Sensor in Ruhe ist
> bekomme ich folgende Werte:
> x_LOW     = 96       // Untere 8-Bit als unsigned char
> X_HIGH     = 255     // Obere 8-Bit als unsigned char
> X_16_bit   = 65376   // x_value = ( (x_high << 8) | x_low); unsigned int
> X_12_BIT   = 4086    // x_value_12 = (x_value / 16) unsigned int
>
> Ich werde aus den Werte einfach nicht schlau. Weiß Jemand einen Rat?
> Herzlichen Dank im Vorraus.

Die Werte stimmen doch alle, bis auf den 12bit-Wert. Dort solltest du 
nicht durch 16 teilen, sondern "(x_value and (2^12-1))" rechnen. Also 
"x_value and 4095". Du willst ja sicherlich die unteren 12 Bit des 
16bit-Wertes haben.
#4084807
Lesenswert?
• ▲
▼
Laut Datenblatt liefert der Sensor seine Daten in 
Zweierkomplementdarstellung - was ja auch Sinn macht für Meßwerte die 
sowohl positiv als auch negativ sein können.

Dann alllerdings macht es keinen Sinn sie vorzeichenlos zu betrachten 
oder zu bearbeiten.

Also: x-value mal als int16_t definieren ...
Gast #4084812
Lesenswert?
• ▲
▼
Hallo,

"Zweierkomplement" und "unsigned int"?! Ich dachte, die Idee hinter 
Zweierkomplement ist es positive UND negative Zahlen darstellen und 
leicht rechnen zu können. Vielleicht möchtest du doch 
vorzeichenbehaftete Variablen verwenden.

Dann ergibt sich nämlich:
x_LOW     = 96       // Untere 8-Bit als unsigned char
X_HIGH     = 255     // Obere 8-Bit als unsigned char
X_16_bit   = -160    // x_value = ( (x_high << 8) | x_low); signed int
X_12_BIT   = -10     // x_value_12 = (x_value / 16); signed int

=> -10 * 98mg = -0.98g ~ -1g könnte passen...
Gast #4084822
Lesenswert?
• ▲
▼
Hallo,

herzlichen Dank für die schnellen Antworten.

@Udo Schmitt:
Ich habe das mal so gemacht und kann die -160 als dezimalwert auch 
nachvollziehen und sehe sie auch im Debug-Modus.

Wie verarbeite ich die -160 nun weiter? Mache ich daraus erst einen 
12-Bit Wert und multipliziere dann mit 0,098 mg/digit, also:
1
X = (-160/16) * 0,098; // = -0,98 => -1g

In Ruhe sollte der Sensor folgende Werte [in g] haben:
1
X = 0; //g
2
Y = 0; //g
3
Z = 1; //g

Gruß,
MSPLer
#4084842
Lesenswert?
• ▲
▼
MSPler schrieb:
> Wie verarbeite ich die -160 nun weiter?

Den Kommentar mit "unsigned int" hatte ich har nicht gelesen.
Du definierst deine Variablen wie die Kollegen oben schon gesagt haben 
als int16_t und rechnest einfach damit.
Du musst nicht durch 16 teilen um auf "12 Bit" zu kommen. Der Wert ist 
schon korrekt ein int16 Wert. Nur kann der Sensor maximal die 12 Bit 
auflösen die oberen 4 Bits sind bei negativen Werten immer F(hex) bzw 
1111 (binär) das ist so beim 2er Komplement, oder bei positiven Werten 
0000.

Warum der X Wert jetzt in Ruhe so hoch ist kann ich dir nicht sagen, 
schau dir die Doku nochmal genau an, ob da nicht irgendwo noch ein 
Teiler /16 ist, und du nicht irgendwo x,y, und z Achse verwechselt hast.
lass dir die Werte ausgeben und drehe das Teil mal und schau welche 
Werte sich dann wie ändern.
Sprich: spiele mal ein bischen, jetzt weisst du ja wie du die Werte 
interpretieren kannst.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.