3-Achsen Beschleunigungssensor ADXL355 programmieren

Ein herzliches Hallo an Alle,

ich bin neu hier bei euch und benötige etwas (mehr oder weniger :wink: ) Hilfe. Ich bin ein kompletter Neuling was Arduino angeht.

Und zwar geht es um den Beschleunigunssensor ADXL355 aus dem Hause AnalogDevices.

Ich möchte gerne den Sensor über ein Arduino Due Board auslesen können und benötige Hilfe bei der Programmierung. Da ich programmiertechnisch auch nicht die hellste Kerze auf dem Kuchen bin, suchte ich Lösungen im Internet, und siehe da...nix... Ich finde nichts brauchbares zu diesem Sensor ( jede Menge Infos über andere bzw. ähnliche Sensoren). Nach etwas recherchieren im Netz und im Datenblatt des Sensors entschied ich mich für I2C als serielle Schnitstelle und machte meine ersten Gehversuche damit. Leider ohne großen Erfolg. Außerdem fehlt mir auch ein Programmaufbau, welches meine 3-Achsen "ausliest". Unten zeige ich euch mein "Programm".
Ich weiß, dass das kein Thema ist, was in 5-10min erledigt ist, aber ich nimm trotzdem meinen Mut zusammen und versuche den Schritt mit diesem Forum. Wenn ich eure Probleme mit meinen Problemem in dem Forum vergleiche, ist es schon fast peinlich für mich.

Ich hoffe auf ein paar nette Menschen die mir vielleicht unter die Arme greifen wollen und können.

Meine ersten Versuche waren eben die Kommunikation herzustellen und nur mal die Auslenkung in X Achse auszulesen.

#include “Wire.h”
#define ADXL355 0x53 // Adresse Sensor
int dt =100; // warten (10ms)
byte XDATA3 = 0x08 // senden vom Befehl (nur X Werte)

Void setup() {
Wire.begin();
Serial.begin(9600);
}

Void Loop() {
Wire.beginTransmission(ADXL355); // Anfang von Übertragung

Wire.write(XDATA3); // erste 8 Bit vom Signal
Wire.endTransmission();

Serial.print („Acceleration in X - “);
Serial.print (XDATA3);

Delay (dt);
}

Ich bedanke mich im Voraus schon herzlichst bei euch für eure Hilfe.

Such mal nach einem I2Scanner Sketch im Internet (und nimm möglichst ein Suchergebnis von arduino.cc)
Dann lass das mal laufen und berichte, ob der deinen Sensor findet.

Dann sehen wir weiter.

Ansonsten:

  1. Sketche bitte in code tags.

  2. Hast du keine Fehlermeldungen beim Verifizieren bekommen ?

'Void' does not name a type

int dt =100; // warten (10ms)

  1. Kommentare sind gut, wenn sie stimmen :wink:

  2. Willkommen im Forum

Hallo,

deine I2C Kontaktaufnahme stimmt nicht. Es fehlt noch die Mitteilung ab welchen Register gelesen werden soll und wie wieviele weitere ab da. Ich gebe dir mal ein Bsp. nur Adresse ggf. anpassen. Es kompiliert aber ungetestet. Mach was sinnvolles daraus.

/*
 *  IDE 1.6.13
 *  Arduino Mega2560
 *  11.01.2017
 */

#include <Wire.h>
#define ADXL355_adress  0x53   // Adresse ggf. ändern

unsigned int intervall = 1000;
unsigned long last_millis;
  
void setup()
{
  Wire.begin();
  Serial.begin(9600);
  
}

void loop()
{
  if ( millis() - last_millis > intervall )  {      // aller x [ms] frische Daten
    last_millis = millis(); 
    if (read_ADXL355 (ADXL355_adress) == true)  {   // wenn Fehlerstatus "wahr", dann
     Serial.println("ADXL355 I2C Busfehler");
    }
    else  {                                         // wenn kein Busfehler, dann           
      Serial.println("fertig");
    }
  }  
 
}
 
 
bool read_ADXL355 (int i2c_adresse)
{
  bool error = false;                      // Fehlerstatus setzen
  Wire.beginTransmission(i2c_adresse);     // Connect
  Wire.write(0x08);                        // Anfrage ab/der Register Nummer
  if (Wire.endTransmission() > 0 )         // war Connect fehlerfrei?
   { 
    error = true;                          // I2C Busfehler
    return error;                          // Abruch
   } 
   
  Wire.requestFrom(i2c_adresse, 9);        // 9 Bytes (Register) in Folge anfordern/lesen

  if (Wire.available() > 0 )  {            // sind Daten vorhanden?
    for (int i=0x08; i<0x11; i++)  {       // Register von ... bis
      Serial.print( Wire.read() );  
      Serial.print("  "); 
    }
  }      
  return error;  
}

Hallo zusammen,
erstmal vielen vielen Dank für eure schnelle Hilfe.

michael_x:
Such mal nach einem I2Scanner Sketch im Internet (und nimm möglichst ein Suchergebnis von arduino.cc)
Dann lass das mal laufen und berichte, ob der deinen Sensor findet.

Ja das habe ich getan und hat auch super funktioniert. Er findet den Sensor unter 0x1D anstatt 0x53. (steht auch so im Datenblatt).

michael_x:
2. Hast du keine Fehlermeldungen beim Verifizieren bekommen ?3. Kommentare sind gut, wenn sie stimmen :wink:

Doch, ich hatte einen Fehler beim kompilieren, aber habe es behoben.
Mein Code schaut wie folgt aus:

#include "Wire.h"
#define ADXL355 0x1D  //Device Address Sensor...I2C-Scanner
int dt = 500;         //delay time
byte XDATA3 = 0x08;   //First Register X Data

void setup(){
  Wire.begin();        //join I2C bus
  Serial.begin(9600);  //serial communication
}

void loop(){
  Wire.beginTransmission(ADXL355);
  Wire.write(XDATA3);
  Wire.endTransmission();
  delay(dt);
  
}

michael_x:
4. Willkommen im Forum

Vielen Dank :slight_smile:

Doc_Arduino:
Hallo,

deine I2C Kontaktaufnahme stimmt nicht. Es fehlt noch die Mitteilung ab welchen Register gelesen werden soll und wie wieviele weitere ab da. Ich gebe dir mal ein Bsp. nur Adresse ggf. anpassen. Es kompiliert aber ungetestet. Mach was sinnvolles daraus.

/*

*  IDE 1.6.13
*  Arduino Mega2560
*  11.01.2017
*/

#include <Wire.h>
#define ADXL355_adress  0x53  // Adresse ggf. ändern

unsigned int intervall = 1000;
unsigned long last_millis;
 
void setup()
{
  Wire.begin();
  Serial.begin(9600);
 
}

void loop()
{
  if ( millis() - last_millis > intervall )  {      // aller x [ms] frische Daten
    last_millis = millis();
    if (read_ADXL355 (ADXL355_adress) == true)  {  // wenn Fehlerstatus "wahr", dann
    Serial.println("ADXL355 I2C Busfehler");
    }
    else  {                                        // wenn kein Busfehler, dann         
      Serial.println("fertig");
    }
  }

}

bool read_ADXL355 (int i2c_adresse)
{
  bool error = false;                      // Fehlerstatus setzen
  Wire.beginTransmission(i2c_adresse);    // Connect
  Wire.write(0x08);                        // Anfrage ab/der Register Nummer
  if (Wire.endTransmission() > 0 )        // war Connect fehlerfrei?
  {
    error = true;                          // I2C Busfehler
    return error;                          // Abruch
  }
 
  Wire.requestFrom(i2c_adresse, 9);        // 9 Bytes (Register) in Folge anfordern/lesen

if (Wire.available() > 0 )  {            // sind Daten vorhanden?
    for (int i=0x08; i<0x11; i++)  {      // Register von ... bis
      Serial.print( Wire.read() ); 
      Serial.print("  ");
    }
  }     
  return error; 
}

Vielen Dank Doc_arduino für deine Bemühungen.

Ich habe deinen Code angepasst und die device Adress auf 0x1D geändert. Ich nehme an, dass der Sensor nun auch richtig angeschlossen ist.
Die Ausgabe deines Codes ist:

0 0 0 0 0 0 0 0 0 fertig

Jedoch ändert sich bei Bewegung des Sensors nichts.

bool read_ADXL355 (int i2c_adresse)
{
  bool error = false;                      // Fehlerstatus setzen
  Wire.beginTransmission(i2c_adresse);     // Connect
  Wire.write(0x08);                        // Anfrage ab/der Register Nummer
  if (Wire.endTransmission() > 0 )         // war Connect fehlerfrei?
   { 
    error = true;                          // I2C Busfehler
    return error;                          // Abruch
   } 
   
  Wire.requestFrom(i2c_adresse, 9);        // 9 Bytes (Register) in Folge anfordern/lesen

Den Befehl „bool read_ADXL355 (int i2c_adresse)“ verstehe ich nicht.
Muss „i2c_adresse“ nicht erst noch deklariert werden? Oder was ist hiermit gemeint.

Ich weiss, dass er später dann die 9 Register meiner Achsen abfragen will. Aber woher weiss mein Arduino wo er es abfragen soll? (i2c_adresse)?

Vielen Dank nochmal an alle!!

Hallo,

das ist eine Funktionsdefinition
bool read_ADXL355 (int i2c_adresse) {
...
}

Rückgabewert Datentyp bool, also true/false
Übergabewert an die Funktion ist ein int Wert.

In loop lautet der Funktionsaufruf (ohne if )
read_ADXL355 (ADXL355_adress)

Das heißt, der Wert von ADXL355_adress wird an die Funktion übergeben beim Aufruf. Funktions intern ist das dann die lokale Variable i2c_adresse. Zusätzlich frage ich eine bool Statusvariable ab um etwas Sicherheit zu haben ob die Kommunikation glatt lief. Kabelbruch oder sonstwas bekommt man sonst nicht mit. Sinn der Übung ist das die loop übersichtlich wird und die Funktion mehrfach verwendet werden kann. Man übergibt nur verschiedene Adressen. Oder noch weitere Werte wie Registernummern, was auch immer.

Warum du jetzt nur Nullen bekommst weiß ich im Moment auch nicht. Hast du den nackten IC oder ein Modul mit Spannungsregler? Denn der IC verträgt nur 3,3V Versorgungsspannung. Und du hast auch wirklich den ADXL355?

Ich habe den Code von meinem ADXL345 übernommen und abgeändert. Nur deswegen konnte ich dir etwas fertiges liefern was eigentlich funktionieren müßte.

Edit:
was noch sein könnte wäre, das der Pin 2 nicht auf Masse liegt für I2C. ???
Seite 10 - http://www.analog.com/media/en/technical-documentation/data-sheets/ADXL354_355.pdf
Andererseits dürfte dann aber der I2C Scanner keine Adresse finden. Seltsam. :astonished:
Ist 0x1D auch wirklich die Adresse von dem Sensor?

Hallo,

Ja ich habe wirklich den ADXL355 :slight_smile: und zwar nicht als nackten IC sondern als Modul (User Guide), und 3,3V vom Arduino.
Zu den Anschlüssen vom Chip:

Pin 1 ist ja meine Clock und geht an den Arduino Due (SCL 21).

Pin 2 ist in meinem Fall egal ob er auf Masse geschaltet wird oder frei gelassen wird, ändert sich nichts an der Ausgabe.

Pin 3 Serial Data geht an den Arduino Due (SDA 20).

Pin 4 (ASEL) ist optional für mich, wenn ich ihn high setz ist meine device adress= 0x53 und wenn ich ihn low setze bzw dann auch nicht anschließe ist meine device adress= 0x1D.

Datenblatt User Guide hier sieht man die Anschlüsse vom Evaluatuion Board (Seite 4).
Versorgung ganz normal über VDD und VDDIO, und Masse noch.

Doc_Arduino:
Andererseits dürfte dann aber der I2C Scanner keine Adresse finden. Seltsam. :astonished:
Ist 0x1D auch wirklich die Adresse von dem Sensor?

Wie schon gesagt ich kann zwischen beiden Adressen wählen, jedoch ändert sich nichts an der Ausgabe. (Datenblatt S.26)

Was möglicherweise das Problem ist, ist dass du den ADXL345 verwendest, welcher ja ein analoger Sensor ist und bei mir handelt es sich um den digitalten. Muss im Code nicht noch dem Sensor gesagt werden, dass er messen darf (Datenblatt S.38 Power Control Register 0x2D). Ich versuche das mal in den Code mit einzubringen.

Nochmals vielen Dank für deine Hilfe und ich melde mich auf jeden Fall wieder :slight_smile:

Hallo,

mein ADXL345 ist auch digital, sonst hätte ich dir meinen Code nicht geben können.

Du hast glaube ich den richtiger Riecher, mein gefundener Bsp. Code war unvollständig, hatte mehrere Versionen gespeichert.
In dem anderen womit ich ein Servo in Lage halte setze ich ein "Measure Bit" im "Power Control" Register. Sonst bleibt er im Standby. Ggf. noch den Range in einem anderen Register einstellen. Das war damals eine kurze Spielerei.

Aufruf Bsp.

if (write_Register_ADXL345(ADXL345_adress, 0x2D, 0x08) == true)  {  // Measure Bit setzen
    Serial.println(F("ADXL write error"));
  }

Funktion:

boolean write_Register_ADXL345 (int i2c_adresse, byte Register, byte data)
{
  boolean error = false;
  Wire.beginTransmission(i2c_adresse);       // Connect
  Wire.write(Register);                      // Anfrage ab/der Register Nummer
  Wire.write(data);
  if (Wire.endTransmission() > 0 )  {        // war Connect fehlerfrei?
    error = true;                            // I2C Busfehler
  } 
  delay(1);
  return error;                              // return mit Fehlerstatus 
}

Musste abändern. Und denke an den einen Pin auf Masse legen bei deinem "nackten Board".

Hallo,

upps...ich habe den ADXL345 mit dem ADXL354 verwechselt, sorry mein Fehler.

Dein Code hat super funktioniert, jetzt bekomme ich nicht nur Nullen :slight_smile:

Könntest du mir vielleicht noch bei der Auswertung etwas helfen? Ich würde mir gerne die Winkel der 3 Achsen anzeigen lassen. Das wird doch über die Sensitivity aus dem Datenblatt umgerechnet?!
Bzw was wäre sinnvoller? Die jetztigen Ergebnisse über ein anderes Programm (Excel z.B.) umzurechnen oder gleich über das Arduino ausgeben?

Vielen Dank du bist eine sehr große Hilfe für mich :slight_smile:

Hallo,

hab da nochwas gefunden. Der Sensor liegt momentan irgendwo in einer Kiste. :o
Hatte damals was im Internet gesucht und eingebaut.
roll und pitch sind globale float Variablen bei mir und sollten dann laut Erinnerung dem Winkel entsprechen.
Die Formel für den 3. Winkel habe ich nicht zur Hand
Im nachhinein merkt man das man seinen Code besser kommentieren sollte. :wink:
Die Winkel mappe ich für ein Servo um und dann war das so wie bei einer Panzerkanone.
Servo und Sensor waren zusammen montiert, ich konnte den Sensor samt Servoantrieb bewegen aber der Servoarm blieb immer in gleicher Höhe/Lage. Das war damals die Motivation.
Du darfst gern sinnvollere Variablennamen für x,y,z verwenden. :slight_smile:

...
...
if (Wire.available() > 0 )  {         // sind Daten vorhanden?
    int DataX0 = Wire.read();  // LSB Byte einlesen, Bit  7 ... 0
    int DataX1 = Wire.read();  // MSB Byte einlesen, Bit 15 ... 8
    int DataY0 = Wire.read();  // LSB Byte einlesen, Bit  7 ... 0
    int DataY1 = Wire.read();  // MSB Byte einlesen, Bit 15 ... 8
    int DataZ0 = Wire.read();  // LSB Byte einlesen, Bit  7 ... 0
    int DataZ1 = Wire.read();  // MSB Byte einlesen, Bit 15 ... 8
    xAxis = (DataX1<<8) | DataX0;  // Rohwert X-Achse
    yAxis = (DataY1<<8) | DataY0;  // Rohwert Y-Achse 
    zAxis = (DataZ1<<8) | DataZ0;  // Rohwert Z-Achse 
    //Serial.print(xAxis); Serial.print('\t');   // Rohwert 
    //Serial.print(yAxis); Serial.print('\t');   // Rohwert 
    //Serial.print(zAxis); Serial.print('\t');   // Rohwert

    //Roll & Pitch Equations
    float xxAxis = (float)xAxis*16.0/1024;  //  [g]
    float yyAxis = (float)yAxis*16.0/1024;  //  [g]
    float zzAxis = (float)zAxis*16.0/1024;  //  [g]
    roll  = (atan2(-yyAxis,zzAxis)*180.0)/3.14;
    pitch = (atan2(xxAxis,sqrt(yyAxis*yyAxis+zzAxis*zzAxis))*180.0)/3.14;
  }   
...
...

Hallo,

ja das glaube ich dir mit dem kommentieren, ich möchte dir mal meinen momentanen Stand mit dem Code zeigen:

#include <Wire.h>				// Bibliothek
#define ADXL355_adress  0x1D   		// Adresse Sensor
unsigned int intervall = 1000;		// Zeitintervall
unsigned long last_millis;			//in Millisekunden
void setup()					// Start setup
{					
  Wire.begin();				// Beginn
  Serial.begin(9600);			// Baude Rate
if (write_Register_ADXL355(ADXL355_adress, 0x2D, 0) == true)  {  // Measure Bit setzen
    Serial.println(F("ADXL write error"));
  }					

}					
void loop()					//Start Loop
{					
  if ( millis() - last_millis > intervall )  {     // aktualisierungsrate der Datenausgabe
    last_millis = millis();		 
    if (read_ADXL355 (ADXL355_adress) == true)  {   // wenn Fehlerstatus "wahr", dann
     Serial.println("ADXL355 I2C Busfehler");
    }					
    else  {                                          // wenn kein Busfehler, dann           
      Serial.println("fertig");	
    }					
  }  					
}					
					
bool read_ADXL355 (int i2c_adresse)	
{					
  bool error = false;                      // Fehlerstatus setzen
  Wire.beginTransmission(i2c_adresse);     // Connect
  Wire.write(0x08);                        // Anfrage ab/der Register-Nummer
  if (Wire.endTransmission() > 0 )         // war Connect fehlerfrei?
   {					 
    error = true;                          // I2C Busfehler
      return error;                          // return mit Fehlerstatus
   }					 
  
  double pitch, roll, xAxis, yAxis, zAxis;
  
  
  Wire.requestFrom(i2c_adresse, 9);        // 9 Bytes (Register) in Folge anfordern/lesen
  if (Wire.available() > 0 )  {         // sind Daten vorhanden?
    int DataX3 = Wire.read();  // LSB Byte einlesen, Bit  19...12
    int DataX2 = Wire.read();  // MSB Byte einlesen, Bit  11... 4
    int DataX1 = Wire.read();  // MSB Byte einlesen, Bit  3...0
    int DataY3 = Wire.read();  // LSB Byte einlesen, Bit  19...12
    int DataY2 = Wire.read();  // MSB Byte einlesen, Bit  11... 4
    int DataY1 = Wire.read();  // LSB Byte einlesen, Bit  3 ... 0
    int DataZ3 = Wire.read();  // LSB Byte einlesen, Bit  19...12
    int DataZ2 = Wire.read();  // MSB Byte einlesen, Bit  11... 4
    int DataZ1 = Wire.read();  // MSB Byte einlesen, Bit  3...0
    
    xAxis = (DataX3<<16) |(DataX2<<8) | DataX1;  // Rohwert X-Achse
    yAxis = (DataY3<<16) |(DataY2<<8) | DataY1;  // Rohwert Y-Achse 
    zAxis = (DataZ3<<16) |(DataZ2<<8) | DataZ1;  // Rohwert Z-Achse 
    //Serial.print(xAxis); Serial.print('\t');   // Rohwert 
    //Serial.print(yAxis); Serial.print('\t');   // Rohwert 
    //Serial.print(zAxis); Serial.print('\t');   // Rohwert

    //Roll & Pitch Equations
    float xxAxis = (float)xAxis/(16*256000);  //  [g]
    float yyAxis = (float)yAxis/(16*256000);  //  [g]
    float zzAxis = (float)zAxis/(16*256000);  //  [g]
    roll  = (atan2(-yyAxis,zzAxis)*180.0)/M_PI;
    pitch = (atan2(xxAxis,sqrt(yyAxis*yyAxis+zzAxis*zzAxis))*180.0)/M_PI;
    
    Serial.print(xxAxis);
    Serial.print(":     ");
    Serial.print(yyAxis);
    Serial.print(":     ");
    Serial.print(zzAxis);
    
    
    //Serial.print(pitch);
    //Serial.print(":");
    //Serial.print(roll);
  }	 
    					
       				
  return error;  			
}					
bool write_Register_ADXL355 (int i2c_adresse, int Register, int Zahl_fuer_Register)
{					
  bool error = false;			// Fehlerstatus setzen
  Wire.beginTransmission(i2c_adresse); 	// Connect  
  Wire.write(Register);                   	// Anfrage ab/der Register-Nummer
  Wire.write(Zahl_fuer_Register);		// Anfrage ab/der Daten
  if (Wire.endTransmission() > 0 )  {  	// war Connect fehlerfrei?
    error = true;                     	// I2C Busfehler
  } 					
  delay(1);				
  return error;                       	// return mit Fehlerstatus 
  
}

Soweit bin ich sehr zufrieden wie es funktioniert. Von 0 ab bis zum jetzigen Stand mit Deiner Hilfe!!!!

Was jetzt noch nicht ganz stimmt, ist dass meine ausgegeben Werte noch nicht 100%ig korrekt sind. Der Sensor gibt mir alle nötigen Werte, aber der negative Berreich ist nicht korrekt. Momentan bin ich dran über das 2er-Komplement eine Lösung zu finden. Oder wie hast du es bei Dir damals gemacht?

Hallo,

das wird mit dem zu kleinen Wertebereich und verschieben innerhalb dessen zusammenhängen. Mein 345 hat nur 16Bit Daten. Deiner hat 19Bit und diese kann man auch nicht 1:1 auslesen und übernehmen, weil die Bit Positionen nicht stimmen.
Vorm ver-ODERn musste die leider noch zurecht schieben.

Bsp. du liest X3 als erstes aus, dann liegt das eigentliche Bit 12 noch an Position von Bit 0 in der long Auslesevariable. Demzufolge musst du dass 12 Positionen nach links schieben. Ähnlich mit X2. Damit das beim schieben nicht hinten rausrutscht musst du long statt int verwenden. Bei X1 liegt das eigentliche Bit0 aber an Position von Bit 4. Also muss dass nach rechts geschoben werden. Wenn dann die Positionen passen wird alles verodert. Probier mal ... ggf. korrigieren

Wire.requestFrom(i2c_adresse, 9);        // 9 Bytes (Register) in Folge anfordern/lesen
  if (Wire.available() > 0 )  {         // sind Daten vorhanden?
    long DataX3 = Wire.read();  // LSB Byte einlesen, Bit  19...12
    long DataX2 = Wire.read();  // MSB Byte einlesen, Bit  11... 4
    long DataX1 = Wire.read();  // MSB Byte einlesen, Bit  3...0
    ...
    ...
   
    long xAxis = (DataX3<<12) | (DataX2<<4) | (DataX1>>4);  // Rohwerte schieben und verODERn
    ...
    ...

lokale Variablen muss man immer initialisieren, auch wenn es nur mit Null ist. Meistens geht das ohne auch gut, weil der Variablen sofort ein Wert zugewiesen wird vor deren weiteren Benutzung. Vergisst man das rechnet man mit Datenmüll weiter. Deswegen habe ich das noch korrigiert. Oder du initilasiert alle lokalen am Anfang der Funktion mit 0.

Für Testausgaben in formatierter Binärform kannste sowas verwenden. Alles übereinander ausgeben, kannste schön die Richtigkeit beim verschieben und verodern überprüfen.

void formatiere_LONG (long data)
{
  Serial.print(F("data: "));
  for (int i=31;i>=24;i--) Serial.print(bitRead(data,i)); 
  Serial.print(".");
  for (int i=23;i>=16;i--) Serial.print(bitRead(data,i)); 
  Serial.print(".");
  for (int i=15;i>=8;i--) Serial.print(bitRead(data,i)); 
  Serial.print(".");
  for (int i=7;i>=0;i--) Serial.print(bitRead(data,i)); 
  Serial.println();
}

Hallo,
ja genau ich hatte zuerst probleme mit dem verschieben der Bits. Wegen dem Wertebereich habe ich festgestellt, dass der int Wertebereich beim Due 32 Bit groß ist und auch ausreichen würde, habe aber trotzdem auf long umgestellt. Jetzt funktioniert mein Code soweit.

 if (Wire.available() > 0 )  {         // sind Daten vorhanden?
    long DataX3 = Wire.read();  // LSB Byte einlesen, Bit  19...12
    long DataX2 = Wire.read();  // MSB Byte einlesen, Bit  11... 4
    long DataX1 = Wire.read();  // MSB Byte einlesen, Bit  3...0
    long DataY3 = Wire.read();  // LSB Byte einlesen, Bit  19...12
    long DataY2 = Wire.read();  // MSB Byte einlesen, Bit  11... 4
    long DataY1 = Wire.read();  // MSB Byte einlesen, Bit  3 ... 0
    long DataZ3 = Wire.read();  // LSB Byte einlesen, Bit  19...12
    long DataZ2 = Wire.read();  // MSB Byte einlesen, Bit  11... 4
    long DataZ1 = Wire.read();  // MSB Byte einlesen, Bit  3...0
    
    xAxis = (DataX3<<24) |(DataX2<<16) | (DataX1<<8);  // Rohwert X-Achse
    yAxis = (DataY3<<24) |(DataY2<<16) | (DataY1<<8);  // Rohwert Y-Achse 
    zAxis = (DataZ3<<24) |(DataZ2<<16) | (DataZ1<<8);  // Rohwert Z-Achse

hier sieht man genau wie ich verschiebe...

float xxAxis = (float)xAxis/(4096*256000);  
    float yyAxis = (float)yAxis/(4096*256000);  
    float zzAxis = (float)zAxis/(4096*256000);  
    roll  = (atan2(-yyAxis,zzAxis)*180.0)/M_PI;
    pitch = (atan2(xxAxis,sqrt(yyAxis*yyAxis+zzAxis*zzAxis))*180.0)/M_PI;

und hier findet die Umrechnung statt.
4096=12 bits wieder nach "links" verschieben und die 256k ist meine sensitivity.
Das werde ich noch etwas schöner schreiben :slight_smile:
Hauptsache war, ob es funktioniert :wink:
Jetzt kann ich mal ein paar Messungen mit dem Sensor durchführen.

Also nochmals vielen dank Doc für deine Hilfe und Zeit die Du dir genommen hast. Du warst mir eine sehr große Hilfe...

Hallo,

ein nettes Danke ist Belohnung genug. :slight_smile:

Noch ein Hinweis wegen float Rechnung. Schreibe bei einer Zahl eine Kommastelle dazu, Bsp. 4096.0 dann wird ganz sicher nicht mit Ganzzahl gerechnet. Das ist eine Eigenart vom Compiler. Sonst rechnet er erst in Ganzzahl und das Ganzzahlergebnis wird dann erst in float gewandelt, hat also Rundungsfehler und immer .0. Wenn möglich auch immer erst multiplizieren und danach dividieren. Was "abgeschnitten" wird ist verloren für nächste Rechnung.

float xxAxis = (float)xAxis/(4096.0*256000);

Du erhöhst die Empfindlichkeit haste geschrieben. Darf ich fragen was du damit machst? Bin nur neugierig. :wink:

Falls noch andere mitlesen nochmal im Überblick.
a) in der Anordnung landen die Bits in den 3 Bytes als Zwischenspeicher beim auslesen
b) das hat Alexino nach schieben dann in seinem long
c) ohne bestimmte Gründe müßte das rote eigentlich am Ende in long liegen

Hallo,
sorry für die verspätete Antwort.
Danke für dein Tip habe den Code dementsprechend abgeändert.
Ich wollte mal einen Einblick in die Thematik Senorik und habe vom Geschäft aus die Möglichkeit solche Sensoren mal auszuprobieren :slight_smile:
Jetzt schau ich mal was für Einsatzmöglichkeiten mir der Sensor bringt, evtl mal ein paar Winkelmessungen im Raum.

Hallo,

kein Thema. Genau, probieren kommt vor studieren. Hauptsache Spass macht es. Manches scheint "sinnlos", ist es aber nicht, man lernt dennoch immer was dabei. :slight_smile: