Beschleunigungsmesser Bosch BMI055 gibt 8 Bit übergelaufene Werte zurück?

Ich versuche, einen BMI055-Beschleunigungsmesser zu verwenden, und die Ausgabe macht mich verrückt.

Ich habe es auf 2G-Empfindlichkeit bei 1000 Hz eingestellt, das heißt, ich habe eine Ausgabe zwischen 0 und 4096 (12 Bit).
Die Ausgabe soll zweikomplementiert sein, also erwarte ich, dass 2048 0G ist

Der Sensor wird mit Hilfe von Lehren möglichst flach aufgebaut.

Jetzt frage ich es in einer Schleife nach seinen FIFO-Daten (1-Frame-Bypass-FIFO), die mir 6 Bytes zurückgeben.
Laut Datenblatt: LSB X MSB X LSB Y MSB Y LSB Z MSB Z

LSB X muss viermal nach rechts verschoben werden und ORd mit MSB X, das viermal nach links verschoben wird.
Ich erhalte also eine 12-Bit-Zahl.

Allein die Analyse der X-Werte zeigt, dass MSB X zwischen 0 und 255 springt!

Code:

temp[0]=(result[1]<<4) | ((result[0])>>4);

Dies zeigt LSB MSB 12BIT-unsigned

Data X:  1       0       0 
Data X:  85      255     4085 
Data X:  201     255     4092 
Data X:  201     255     4092 
Data X:  221     255     4093 
Data X:  157     0       9 
Data X:  49      0       3 
Data X:  181     255     4091 
Data X:  229     255     4094 
Data X:  17      0       1 
Data X:  161     255     4090 
Data X:  117     255     4087 
Data X:  221     255     4093 
Data X:  5       0       0 
Data X:  209     255     4093 

Es sollte mir 2048 zurückgeben, da X bei 0G ist.
4096 wäre 2G-Kraft.
0 wäre -2G Kraft.

Wenn Sie X auf -1G und +1G setzen, scheinen die Werte korrekt zu sein (1000 und 3000).
Nur das mittlere 0G liegt bei 0/4000, abhängig von geringfügigen Vibrationen, anstelle der erwarteten 2046-2049

Es ist 4 Uhr morgens, ich schätze, ich überwache etwas sehr Kritisches. Bitte um Aufklärung

Ich habe mir das Datenblatt nicht angesehen, aber wenn diese Werte signiert sind, liegen alle Messwerte ziemlich nahe bei Null und Ihr Messwert von 3000 würde bei etwa -1000 liegen.
Hmm, also scheint es, dass die 8-Bit-Nummern tatsächlich einzeln signiert sind ?? Obwohl sie nur eine Teilmenge einer größeren Zahl (12 Bit) sind? Ich hätte erwartet, dass die 12-Bit-Zahl im vorzeichenbehafteten Zustand in 8 Bit + 4 Bit gespeichert wird. Ich versuche nur, aus der Mathematik einen Sinn zu machen, die vorher so einfach gewesen wäre.
Nicht sicher, aber wenn es signiert ist, könnten Sie Ihre unsignierte Nummer und so etwas wie verwenden if (x >= 2048) x = x - 4096.
hmm vielleicht, ich bin mir immer noch unsicher, wie ich mit den Registern umgehen soll, die ich erhalte. Datenblatt sagt, dass MSB zwei Komplement ist. LSB ist nicht zweiergänzt (glaube ich?) Bedeutet das, dass Beispielwerte wie lsb 10 msb 255 = -10 sind? 10 1 wäre dann 26 ?
Richtig, das LSB sollte nicht alleine als Zweierkomplementwert interpretiert werden. Ihr erstes Beispiel hat tatsächlich einen Wert von -6 (Ihr zweites ist richtig); Wenn Sie nicht verstehen, warum, würde ich vorschlagen, die Funktionsweise des Zweierkomplements aufzufrischen.
Upvote für euch alle, danke für die Vorschläge. Ich war gestern einfach zu müde, um „durchzuschauen“.

Antworten (2)

Ich denke, Sie werden durch die Notwendigkeit verwirrt, dass das Vorzeichen der Nummer nach links verlängert wird. Meine Lektüre des Datenblatts ist, dass die MSB- und LSB-Register Ihnen einen Satz von 12 Bits geben, die als 12-Bit-Zahl im Zweierkomplementformat zu betrachten sind.

Sie sollten also zuerst die Werte kombinieren und dann bei Bedarf eine Korrektur durchführen, um sicherzustellen, dass es sich angesichts der Größe des Datentyps, in den Sie ihn eingefügt haben, um eine legitime Zweierkomplementzahl handelt. Skalieren Sie ihn dann bei Bedarf.

Ich würde vorschlagen: Wählen Sie zuerst eine Zieldatengröße, die groß genug ist, um das Ergebnis aufzunehmen. Nehmen wir an, Sie verwenden C auf einer MCU, und Sie können signiert kurz wählen, und es sind 16 Bit. (Keines davon ist selbstverständlich, BTW).

Nehmen wir außerdem an, dass MSB und LSB 8-Bit-Zahlen sind. Jetzt:

vorzeichenbehaftetes kurzes Ergebnis = (MSB << 8) | (LSB & 0xF0)

Dies sollte Ihnen eine Zahl geben, die bereits im Zweierkomplementformat vorliegt, wie es von signed short erwartet wird. Dadurch erhalten Sie einen Zahlenbereich, der das 16-fache der rohen 12-Bit-Zahl beträgt, aber richtig um Null herum reicht.

Möglicherweise möchten Sie es dann skalieren, indem Sie durch 16 dividieren. Sie könnten daran denken, diese Division mit scaledresult = (Ergebnis >> 4) durchzuführen, aber wenn dies der Fall ist, müssen Sie prüfen, ob die Rechtsverschiebung eine Vorzeichenerweiterung durchführt. Das heißt, dass scaledresult[15..12] auf 1 gesetzt wird, wenn result[15] 1 war.

Ich hatte das eigentlich schon gemacht, war aber besessen davon, meine Nummer 12 Bit und so effizienten Code wie möglich zu halten. Ich dachte auch, LSB ist eigentlich nicht in zwei Komplementen. Es war gestern vielleicht nur ein bisschen spät für mich :) Ich habe es jetzt genau so implementiert, wie Sie es vorgeschlagen haben, und werde wahrscheinlich sogar die 16-Bit-Version beibehalten, da mein Gyro auch 16-Bit-Ergebnisse liefert.
Es ist einer dieser Fälle, in denen das Format der Daten, die Ihnen von den Registern übergeben werden, das Format ist, das am wenigsten Aufwand erfordert, um in Ihrem Programm nützlich zu werden ... solange Sie wissen, was die Absicht war - in diesem Fall der Zieldatentyp .

Es gibt gebrauchsfertige APIs für den Beschleunigungsmesserteil im BMI055. Bitte beziehen Sie sich auf:

Bosch Sensortec BMA2x2 Sensortreiber