Accelometer zeigt keine Werte

Hallo zusammen:)

Ich habe ein Problem mit meinem Programm welches ich für mein Accelometer geschrieben habe. Zurzeit verwende ich eine art Shield (so würde ich das beschreiben) von AVR auf dem man über I2C drei verschiedene Sensoren ansteuern kann. Bis jetzt konnte ich Werte für mein Gyrosensor und des magnetometer ohne Probleme herausbekommen. Jedoch beim Accelometer stehe ich wirklich auf dem Schlauch. Im Datenblatt finde ich ach nichts wirklich nützliches welche register ich benutzen kann. Hier der Link-> http://www.atmel.com/Images/doc8369.pdf

Im Datenblatt stehen nur die Startadressen um die Sensoren anzusprechen. Ich denke mal ich schicke falsche Adressen am dem Sensor was vermuten lässt warum ich immer am Monitor 0 sehe egal wie oft ich es hin und her bewege.

Leider weiss ich nicht was ich noch an mein Programm ändern sollte. Hoffe Ihr könnt mir helfen danke im Voraus:)

PS: den Code befindet sich im Anhang

accel1.txt (2.14 KB)

AdrianG90:
Leider weiss ich nicht was ich noch an mein Programm ändern sollte.

Das ist für eine systematische Fehlersuche die völlig falsche Frage.

Und dann hast Du auch noch (ebenso völlig falsch) gleich DREI NEUE THREADS zum selben Thema aufgemacht!

Für eine systematische Fehlersuche würdest Du zuerst einmal prüfen müssen, ob Du Deine I2C-Sensoren funktionstüchtig angeschlossen hast. Offenbar hast Du ein Kombi-Modul angeschlossen, auf dem sich mehrere Sensoren befinden.

Ob diese Sensoren alle funktionieren und mit welcher I2C-Adresse sie ansprechbar sind, testest Du am besten zunächst mal mit einem Sketch vom Typ "I2C Scanner", z.B. diesem:

#include <Wire.h>


void setup()
{
  Wire.begin();

  Serial.begin(9600);
  Serial.println("\nI2C Scanner");
}


void loop()
{
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for(address = 1; address < 127; address++ ) 
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");

      nDevices++;
    }
    else if (error==4) 
    {
      Serial.print("Unknow error at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");

  delay(5000);           // wait 5 seconds for next scan
}

Werden Deine Sensoren mit diesem Sketch gefunden?
Wenn ja: Was wird an welchen I2C-Adressen gefunden?

das habe ich schon längst gemacht
gefunden wurde einmal die Adresse
0x0F für das accelometer
0x1E für das magnetometer
und 0x68 für den gyrosensor

mehr adressen wurden nicht gefunden.

Und noch mal entschuldigung für die Threads wollte natürlich eins Posten und nicht direkt drei weiss leider nicht wie man die löschen kann.

Diesen Ansatz der Fehlersuche bin ich auch drauf gekommen.

In der Setup weiss ich leider nicht welche Adresse ich dem Sensor nun schicken soll. Ich weiss leider nur die Startadresse.
ich hab mal einige stellen meines Codes kommentiert wo mein Problem ist!

#include <Wire.h>

#define ACCEL 0x0F // Accel I2c Address // das ist klar

#define TO_Read (6)// num of bytes we are going to read each time // hier soll ein Wert gelesen werden Welchen aber??

byte buff [TO_Read];// 6 bytes buffer for saving data read from the device
int regAddress = 0x01;

float AcX;
float AcY;
float AcZ;

void setup() {
// put your setup code here, to run once:
Serial.begin(9600); // Baund 9600
Wire.begin();

// Was schicke ich dem Senor nun eigentlich? 1. Die Adresse klar 2.? welche Speicheradresse und welchen Wert?
writeTo(ACCEL,0x1B,0);
writeTo(ACCEL,0x1B,8);
writeTo(ACCEL,0x1B,16);

}

void readFrom(int device,int adress, int nbytes, byte buff[])
{
Wire.beginTransmission(device); //start transmission to device
Wire.write(adress); // sends address to read from
Wire.endTransmission(); // end transmission

Wire.beginTransmission(device);
Wire.requestFrom(device, nbytes); //request 6 bytes from devices
for(int i= 0; i<nbytes;i++)
buff*=Wire.read();*

  • Wire.endTransmission(); //end Transmission*
    }
    void writeTo(int device, byte address, byte val) {
  • Wire.beginTransmission(device); //start transmission to device*
  • Wire.write(address); // send register address*
  • Wire.write(val); // send value to write*
  • Wire.endTransmission(); //end transmission*
    }
    void loop() {
  • // put your main code here, to run repeatedly:*
  • readFrom(ACCEL, regAddress, TO_Read, buff);*
    _ /*_
  • AcX = Wire.read() << 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)*
  • AcY = Wire.read() << 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)*
  • AcZ = Wire.read() << 8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)*
  • Tmp = Wire.read() << 8 | Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)*
    _ */_
  • AcX = (((int)buff[1]) << 8 ) | buff[0];*
  • AcY = (((int)buff[3]) << 8 ) | buff[2];*
  • AcZ = (((int)buff[5]) << 8 ) | buff[4];*
    Ausgabe: 0 0 0

AdrianG90:
das habe ich schon längst gemacht
gefunden wurde einmal die Adresse
0x0F für das accelometer
0x1E für das magnetometer
und 0x68 für den gyrosensor

OK, dann hast Du die Hardware funktionstüchtig angeschlossen, wenn das funktioniert.

Das nächste wäre, den PullUp-Widerständen nach der Aktivierung des I2C-Busses eine kleine Zeitspanne zur Stabilisierung der Spannung zu geben:

  Wire.begin();
  delay(100);

Und wenn das nichts bringt, müßtest Du anfangen, Deinen Code zu debuggen und herauszufinden, wo Du Fehler gemacht hast.

Damit Deine Lesefunktion funktioniert, würde ich diese auch dringend mal entsprechend der gängigen I2C-Kommunikation korrigieren. Du hast da zwei falsche Programmzeilen drin, die weg müssen. Also eher so:

void readFrom(int device,int adress, int nbytes, byte buff[])
{
  Wire.beginTransmission(device); //start transmission to device
  Wire.write(adress); // sends address to read from
  Wire.endTransmission(); // end transmission

  Wire.requestFrom(device, nbytes); //request 6 bytes from devices
  for(int i= 0; i<nbytes;i++)
  buff[i]=Wire.read();
}

jurs:
Damit Deine Lesefunktion funktioniert, würde ich diese auch dringend mal entsprechend der gängigen I2C-Kommunikation korrigieren. Du hast da zwei falsche Programmzeilen drin, die weg müssen. Also eher so:

void readFrom(int device,int adress, int nbytes, byte buff[])

{
 Wire.beginTransmission(device); //start transmission to device
 Wire.write(adress); // sends address to read from
 Wire.endTransmission(); // end transmission

Wire.requestFrom(device, nbytes); //request 6 bytes from devices
 for(int i= 0; i<nbytes;i++)
 buff[i]=Wire.read();
}

Kannst Du außerdem mal erklären, was das in der Initialisierung werden soll:

// Was schicke ich dem Senor nun eigentlich? 1. Die Adresse klar 2.? welche Speicheradresse und welchen Wert?
  writeTo(ACCEL,0x1B,0);
  writeTo(ACCEL,0x1B,8);
  writeTo(ACCEL,0x1B,16);

Den Code kannst Du entweder weglassen, weil er sowieso nicht funktioniert (entspricht auch nicht den Standards bei der I2C-Kommunikation) oder Du mußt den Code umschreiben, dass eine I2C-Kommunikation stattfindet.

Die Befehle schicke ich ja zu der Funktion writeTo. Und diese schickt es an dem Sensor. Wenn du mein kommentar gelesen hättest dann steht meine frage schon im Kommentar drinne. Ich weiss nicht ausser die Startadresse welche welchen an welcher adresse ich noch senden soll.

auch das hier
int regAddress = 0x32;
// put your main code here, to run repeatedly:
readFrom(ACCEL, regAddress, TO_Read, buff);

hab ich einfach ein Speicherwert gegeben.

Nun meine Frage kann ich einfach irgendwelche Speicheradresse dem Sensor zuteilen und der muss nur diesen Auswerten oder gibs dazu ne liste ?

AdrianG90:
Die Befehle schicke ich ja zu der Funktion writeTo. Und diese schickt es an dem Sensor.

Dann passt es ja.

AdrianG90:
Nun meine Frage kann ich einfach irgendwelche Speicheradresse dem Sensor zuteilen und der muss nur diesen Auswerten oder gibs dazu ne liste ?

Die Bedeutung aller auslesbaren und beschreibbaren Register eines Sensors stehen stets im dazugehörigen "Datenblatt", auf Neudeutsch "datasheet".

Dein Sensor ist offenbar ein KXTF9 von der Firma Kionix, und in dem Fall müßte das zutrffende Datenblatt laut Google dieses hier sein:

Das sind 41 Seiten technische Erklärungen zum Sensor, und die Register sind ab Seite 13 ff. erläutert.

Und ja: In einer Liste!

Ich habe mir das Datenblatt angesehen und sehr viele Register adressen gefunden. Aber die brache nicht nicht alle. Hab mir nur die nötigen Register rausgesucht die ich zum ansprechen brauche. Nun werden mir die Werte angezeigt vom Beschleunigungssensor. Jedoch bezweifele ich das diese richtig sind. Egal es gerade stehen bleibt oder sich bewegt(da soll sein) ändern sich meine Werte ziemlich sehr auseinander.

Den Beschleunigungssensor direkt auszlesen hat irgendwie nicht geklappt. Aber über dem Gyroskop geht es. Was kann daran nicht stimmen?

#include <Wire.h>
#define GYRO 0x68 // gyro I2C address
#define REG_GYRO_X 0x1D // IMU-3000 Register address for GYRO_XOUT_H
#define AUX_DMP_CONTROLL 0x3D // IMU-3000 Register address for controling digital motion processor and the aux device

#define ACCEL 0x0F // Accel I2C Address
#define KXTF9_FILT_REG 0x21 // Data control reg addr
//#define KXTF9_HPFHZ_50 0x00 // HPF roll off at 100 Hz
//#define KXTF9_LPFHZ_400 0x06 // LPF roll off at 25 hz

#define KXTF9_POWER_CTL 0x1B // Power control reg addr
#define KXTF9_PC0 0x80 // Operating mode bit
#define KXTF9_RES 0x40 // Resolution bit
#define KXTF9_GS2G 0x00 // bits for 2G mode
#define KXTF9_GS4G 0x08 // bits for 4G mode
#define KXTF9_GS8G 0x10 // bits for 8G mode

byte buffer[12]; //Array to store ADC values
int accel_x;
int accel_y;
int accel_z;
int i;
// Write a value to address register on device
void writeTo(int device, byte address, byte val) {
Wire.beginTransmission(device); // start transmission to device
Wire.write(address); // send register address
Wire.write(val); // send value to write
Wire.endTransmission(); // end transmission
}

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Wire.begin();
delay(100);
//set accel register data address
writeTo(GYRO, 0x18, 0x06);
// set accel i2c slave address
writeTo(GYRO, 0x14, ACCEL);

writeTo(ACCEL, KXTF9_POWER_CTL, KXTF9_PC0 ); // set accel power control to 'measure'
writeTo(GYRO, AUX_DMP_CONTROLL, 0xEE); //cancel pass through to accel, gyro will now read accel for us

}

void loop() {
// put your main code here, to run repeatedly:

// First set the register start address for X on Gyro
Wire.beginTransmission(GYRO);
Wire.write(REG_GYRO_X); //Register Address GYRO_XOUT_H
Wire.endTransmission();

// New read the 12 data bytes
Wire.beginTransmission(GYRO);
Wire.requestFrom(GYRO, 12); // Read 12 bytes
i = 0;
while (Wire.available())
{
buffer = Wire.read();

  • i++;*

  • }*

  • Wire.endTransmission();*

  • // Accel is LSB first. Also because of orientation of chips*

  • // accel y output is in same orientation as gyro x*

  • // and accel x is gyro -y*

  • accel_y = buffer[7] | buffer[6];*

  • accel_x = buffer[9] | buffer[8];*

  • accel_z = buffer[11] | buffer[10];*

  • Serial.print(accel_x);*

  • Serial.print("\t");*

  • Serial.print(accel_y);*

  • Serial.print("\t");*

  • Serial.print(accel_z);*

  • Serial.println("");*

  • delay(1000);*
    }

Ne Menge Sachen.
Es ist ganz normal, dass die Werte schwanken. die Dinger sind dermassen empfindlich, dass es nahezu schon Ausschläge gibt, wenn ne Fliege auf der anderen Schreibtischseite landet.
Und: wenn der Sensor alle drei Achsen erfasst, dann auch die Erdbeschleunigung- wenn also alles auf "0" steht (oder in der Gegend) läuft definitiv was schief.
Den Rest macht man dann mit vernünftigen Filtern.