INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 1 Bewertungen - 5 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
portabler Beschleunigungs-/Neigungsmesser
01.05.2015, 17:28
Beitrag #9
RE: portabler Beschleunigungs-/Neigungsmesser
Hallo,

es funktioniert im Großen und Ganzen nur wenn der Arduino vom Strom getrennt wird setzt sich der Messbereich von +- 8g auf den Normalwert +- 2g zurück!
Weiß jemand warum?

Hat außerdem jemand eine Idee wie man die zeitliche Synchrosation noch genauer machen würde? (Ich hab ein Timer der die Zeit zwischen zwei READ/WRITE Vorgängen berechnet und auzeichnet, wenn ich diese Zwischenwerte in MATLAB verrechne ist die berechnete Zeit anders als die tatsächlich vergangene Zeit!)

Code:
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
const int buttonPin = 3;
int LEDPin = 9;
int accX, accY, accZ;
int gyroX, gyroY, gyroZ;
int16_t tempRaw;
int buttonState = 0;
uint32_t timer;
uint8_t i2cData[14];
File myFile;


void setup()
{
  pinMode(LEDPin, OUTPUT);
  pinMode(buttonPin, INPUT);
  pinMode(10, OUTPUT);
  Serial.begin(9600);
  Wire.begin();
  TWBR = ((F_CPU / 400000L) - 16) / 2;
  i2cData[0] = (29 / 3);
  i2cData[1] = 0x00;
  i2cData[2] = 0x01;
  i2cData[3] = 0x10; //Set to +- 8g
  while (i2cWrite(0x19, i2cData, 4, false));
  while (i2cWrite(0x6B, 0x01, true));


  while (i2cRead(0x75, i2cData, 1));
  if (i2cData[0] != 0x68) {
    Serial.print(F("Error reading sensor"));
    while (1);
  }

  delay(100);

  
  while (i2cRead(0x3B, i2cData, 6));
  accX = (i2cData[0] << 8) | i2cData[1];
  accY = (i2cData[2] << 8) | i2cData[3];
  accZ = (i2cData[4] << 8) | i2cData[5];
  tempRaw = (i2cData[6] << 8) | i2cData[7];
  gyroX = (i2cData[8] << 8) | i2cData[9];
  gyroY = (i2cData[10] << 8) | i2cData[11];
  gyroZ = (i2cData[12] << 8) | i2cData[13];


  timer = micros();



}
void read1() {
  digitalWrite(LEDPin, HIGH);


  while (i2cRead(0x3B, i2cData, 14));
  accX = (i2cData[0] << 8) | i2cData[1];
  accY = (i2cData[2] << 8) | i2cData[3];
  accZ = (i2cData[4] << 8) | i2cData[5];

  gyroX = (i2cData[8] << 8) | i2cData[9];
  gyroY = (i2cData[10] << 8) | i2cData[11];
  gyroZ = (i2cData[12] << 8) | i2cData[13];
  double dt = (double)(micros() - timer) / 1000000;
  timer = micros();



  myFile.print(dt); myFile.print(";");
  myFile.print(accX); myFile.print(";");
  myFile.print(accY); myFile.print(";");
  myFile.print(accZ); myFile.print(";");
  myFile.print(gyroX); myFile.print(";");
  myFile.print(gyroY); myFile.print(";");
  myFile.print(gyroZ); myFile.println("");

/* while(dt!=0.02){
  double dt = (double)(micros() - timer) / 1000000;
  timer = micros();
  delay(1);
  }*/
  delay(20);
}

void loop()
{
  buttonState = digitalRead(buttonPin);


  if (buttonState == HIGH) {
    if (!myFile) {
      SD.begin(4);
      char filename[] = "LOGGER00.CSV";
      for (uint8_t i = 0; i < 100; i++) {
        filename[6] = i / 10 + '0';
        filename[7] = i % 10 + '0';
        if (! SD.exists(filename)) {
          // only open a new file if it doesn't exist
          myFile = SD.open(filename, FILE_WRITE);
          break;  // leave the loop!
        }
      
      }
      i2cData[3] = 0x10;
  tempRaw = (i2cData[6] << 8) | i2cData[7];
    double temperature = (double)tempRaw / 340.0 + 36.53;
    myFile.print("||");
    myFile.print(temperature);
    myFile.print("||");
    myFile.println("");
    
    }
    
    read1();

    buttonState = digitalRead(buttonPin);
  } else {
    if (myFile) {
      tempRaw = (i2cData[6] << 8) | i2cData[7];
      double temperature = (double)tempRaw / 340.0 + 36.53;
      myFile.print("||");
      myFile.print(temperature);
      myFile.print("||");
      myFile.println("");
      myFile.close();
    }
    digitalWrite(LEDPin, LOW);
  }
}

Grüße

GumGum
____________________________________________________________________
Bilder etc. folgen nach dem entgültigen Abschluss des Projekts Wink
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
01.05.2015, 18:08 (Dieser Beitrag wurde zuletzt bearbeitet: 06.05.2015 15:34 von HaWe.)
Beitrag #10
RE: MPU6050 portabler Beschleunigungs-/Neigungsmesser
hallo,
ich bin sehr gespannt darauf, wie du den MPU6050 allein mit Wire.h zum Laufen bekommst, denn ich kann mit meinem Board die mpu6050.h und die i2c.h oder i2cmaster.h oder wie sie auch immer heiß, nicht benutzen wegen der AVR-Interrupts.

was z.B. macht diese Zeile:
TWBR = ((F_CPU / 400000L) - 16) / 2;
?

Welchen MPU6050 hast du dir genau gekauft? Den nackten Chip oder ein/e komplette/s Board/Platine?

Hast du einen Link zum Artikel?

Gruß
Helmut
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
02.05.2015, 10:33
Beitrag #11
RE: portabler Beschleunigungs-/Neigungsmesser
(01.05.2015 17:28)GumGum schrieb:  es funktioniert im Großen und Ganzen nur wenn der Arduino vom Strom getrennt wird setzt sich der Messbereich von +- 8g auf den Normalwert +- 2g zurück!
Weiß jemand warum?
Das Ding hat IMHO kein EEPROM oder so. Was auch immer Du änderst musst Du jedesmal beim Start machen.

Zitat:Hat außerdem jemand eine Idee wie man die zeitliche Synchrosation noch genauer machen würde? (Ich hab ein Timer der die Zeit zwischen zwei READ/WRITE Vorgängen berechnet und auzeichnet, wenn ich diese Zwischenwerte in MATLAB verrechne ist die berechnete Zeit anders als die tatsächlich vergangene Zeit!)
Ich verstehe nicht, was genau Du machen willst bzw. wo das Problem ist. Kannst Du das genauer erklären bzw. mal das Coding dazu zeigen. Ich habe in Deinem bisherigen Coding etwas gefunden, aber das ist auskommentiert und ich habe auch nicht 100% verstanden, was es soll.

Falls ich mit einer Antwort helfen konnte, wuerde ich mich freuen, ein paar Fotos oder auch ein kleines Filmchen des zugehoerigen Projekts zu sehen.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
06.05.2015, 15:33 (Dieser Beitrag wurde zuletzt bearbeitet: 06.05.2015 15:41 von HaWe.)
Beitrag #12
RE: MPU6050 portabler Beschleunigungs-/Neigungsmesser
hallo,
ich hätte gern noch ein paar Infos:

(01.05.2015 18:08)HaWe schrieb:  hallo,
ich bin sehr gespannt darauf, wie du den MPU6050 allein mit Wire.h zum Laufen bekommst, denn ich kann mit meinem Board die mpu6050.h und die i2c.h oder i2cmaster.h oder wie sie auch immer heißt, nicht benutzen wegen der AVR-Interrupts.

was z.B. macht diese Zeile:
TWBR = ((F_CPU / 400000L) - 16) / 2;
?

Welchen MPU6050 hast du dir genau gekauft? Den nackten Chip oder ein/e komplette/s Board/Platine?

Hast du einen Link zum gekauften Artikel?

und b)

wie ist dein genauer vollständiger Code?
(02.05.2015 10:33)Thorsten Pferdekämper schrieb:  Ich verstehe nicht, was genau Du machen willst bzw. wo das Problem ist. Kannst Du das genauer erklären bzw. mal das Coding dazu zeigen. Ich habe in Deinem bisherigen Coding etwas gefunden, aber das ist auskommentiert und ich habe auch nicht 100% verstanden, was es soll.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
09.05.2015, 14:37
Beitrag #13
RE: portabler Beschleunigungs-/Neigungsmesser
Hi,
Zitat:Ich verstehe nicht, was genau Du machen willst bzw. wo das Problem ist. Kannst Du das genauer erklären bzw. mal das Coding dazu zeigen. Ich habe in Deinem bisherigen Coding etwas gefunden, aber das ist auskommentiert und ich habe auch nicht 100% verstanden, was es soll.
Ich will durch "dt"(Zeit zwischen 2 Messungen herausfinden wie lange die Messung ist). Wenn ich jedoch alle "dt" addiere kommt eine andere Zeit raus als eigentlich sollte (zB. 1min Messung ergibt 75s).

Irgendwelche Ideen wie man es so anpassen könnte, dass...
a)...bessere zeitliche Synchronisation (zb Messungen NUR GENAU alle 0,02s)?
b)...höhere Genauigkeit des "dt" Wertes?

Zitat:was z.B. macht diese Zeile:
TWBR = ((F_CPU / 400000L) - 16) / 2;
?
Die setzt die I2C Frequenz auf 400khz
Schau dir mal das hier an:
https://github.com/TKJElectronics/Kalman...PU6050.ino

Zitat:Welchen MPU6050 hast du dir genau gekauft? Den nackten Chip oder ein/e komplette/s Board/Platine?

Hast du einen Link zum Artikel?
Mit Board.
http://www.ebay.de/itm/Axis-Gyro-Acceler...7675.l2557


Code:
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
const int buttonPin = 3;
int LEDPin = 9;
int accX, accY, accZ;
int gyroX, gyroY, gyroZ;
int16_t tempRaw;
int buttonState = 0;
uint32_t timer;
uint8_t i2cData[14];
File myFile;


void setup()
{
  pinMode(LEDPin, OUTPUT);
  pinMode(buttonPin, INPUT);
  pinMode(10, OUTPUT);
  Serial.begin(9600);
  Wire.begin();
  TWBR = ((F_CPU / 400000L) - 16) / 2;
  i2cData[0] = (29 / 3);
  i2cData[1] = 0x00;
  i2cData[2] = 0x01;
  i2cData[3] = 0x10; //Set to +- 8g
  while (i2cWrite(0x19, i2cData, 4, false));
  while (i2cWrite(0x6B, 0x01, true));


  while (i2cRead(0x75, i2cData, 1));
  if (i2cData[0] != 0x68) {
    Serial.print(F("Error reading sensor"));
    while (1);
  }

  delay(100);


  while (i2cRead(0x3B, i2cData, 6));
  accX = (i2cData[0] << 8) | i2cData[1];
  accY = (i2cData[2] << 8) | i2cData[3];
  accZ = (i2cData[4] << 8) | i2cData[5];
  tempRaw = (i2cData[6] << 8) | i2cData[7];
  gyroX = (i2cData[8] << 8) | i2cData[9];
  gyroY = (i2cData[10] << 8) | i2cData[11];
  gyroZ = (i2cData[12] << 8) | i2cData[13];


  timer = micros();



}
void read1() {
  digitalWrite(LEDPin, HIGH);


  while (i2cRead(0x3B, i2cData, 14));
  accX = (i2cData[0] << 8) | i2cData[1];
  accY = (i2cData[2] << 8) | i2cData[3];
  accZ = (i2cData[4] << 8) | i2cData[5];

  gyroX = (i2cData[8] << 8) | i2cData[9];
  gyroY = (i2cData[10] << 8) | i2cData[11];
  gyroZ = (i2cData[12] << 8) | i2cData[13];
  double dt = (double)(micros() - timer) / 1000000;
  timer = micros();



  myFile.print(dt); myFile.print(";");
  myFile.print(accX); myFile.print(";");
  myFile.print(accY); myFile.print(";");
  myFile.print(accZ); myFile.print(";");
  myFile.print(gyroX); myFile.print(";");
  myFile.print(gyroY); myFile.print(";");
  myFile.print(gyroZ); myFile.println("");


  delay(20);
}

void loop()
{
  buttonState = digitalRead(buttonPin);


  if (buttonState == HIGH) {
    if (!myFile) {
      SD.begin(4);
      char filename[] = "LOGGER00.CSV";
      for (uint8_t i = 0; i < 100; i++) {
        filename[6] = i / 10 + '0';
        filename[7] = i % 10 + '0';
        if (! SD.exists(filename)) {

          myFile = SD.open(filename, FILE_WRITE);
          break;
        }

      }
      Wire.begin();
      TWBR = ((F_CPU / 400000L) - 16) / 2;
      i2cData[0] = (29 / 3);
      i2cData[1] = 0x00;
      i2cData[2] = 0x10;
      i2cData[3] = 0x10; //Set to +- 8g
      while (i2cWrite(0x19, i2cData, 4, false));
      while (i2cWrite(0x6B, 0x01, true));

      tempRaw = (i2cData[6] << 8) | i2cData[7];
      double temperature = (double)tempRaw / 340.0 + 36.53;
      myFile.print("||");
      myFile.print(temperature);
      myFile.print("||");
      myFile.println("");

    }

    read1();

    buttonState = digitalRead(buttonPin);
  } else {
    if (myFile) {
      tempRaw = (i2cData[6] << 8) | i2cData[7];
      double temperature = (double)tempRaw / 340.0 + 36.53;
      myFile.print("||");
      myFile.print(temperature);
      myFile.print("||");
      myFile.println("");
      myFile.close();
    }
    digitalWrite(LEDPin, LOW);
  }
}


GumGum
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
09.05.2015, 15:31
Beitrag #14
RE: portabler Beschleunigungs-/Neigungsmesser
(09.05.2015 14:37)GumGum schrieb:  Ich will durch "dt"(Zeit zwischen 2 Messungen herausfinden wie lange die Messung ist). Wenn ich jedoch alle "dt" addiere kommt eine andere Zeit raus als eigentlich sollte (zB. 1min Messung ergibt 75s).
Naja, die dt, die Du ausgibst, sind nicht unbedingt genau. Außerdem gibt das print nur zwei Nachkommastellen aus, oder?

Zitat:Irgendwelche Ideen wie man es so anpassen könnte, dass...
a)...bessere zeitliche Synchronisation (zb Messungen NUR GENAU alle 0,02s)?
Eigentlich kann der 6050 irgendwie alle (z.B.) 0,02s einen Interrupt auslösen. Dann weißt Du, dass die Messung alle 0.02s kommt. Schau Dir mal die Beispiele in der 6050 Lib an.

Zitat:b)...höhere Genauigkeit des "dt" Wertes?
Gib doch mal direkt die micros aus (also der Wert der Variable timer). Das ist dann auf 4us genau. Deine double-Variablen-Ausgabe hat wahrscheinlich einen Fehler in der Größenordnung von 10ms.

Falls ich mit einer Antwort helfen konnte, wuerde ich mich freuen, ein paar Fotos oder auch ein kleines Filmchen des zugehoerigen Projekts zu sehen.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
09.05.2015, 17:45 (Dieser Beitrag wurde zuletzt bearbeitet: 10.05.2015 08:54 von HaWe.)
Beitrag #15
RE: portabler Beschleunigungs-/Neigungsmesser
warum muss man GENAU alle 0,02 s einen IRQ am Sensor auslösen?

Ich habe bei meinen Gyros eine Endlos-Schleife laufen, bei der ich die echte Durchlaufzeit stoppe (per millis) - ich lese die Werte ca. alle 50-ms aus (das ist dicke genau genug) und rechne dann alles selber aus.
Dazu nehme ich die echten gemessenen delta-millis als Grundlage z.B. für die Berechnung des integrierten Gyro-Winkels aus der Gyro-Drehgeschwindigkeit.

Gyro_Winkel = Gyro_Winkel + (Gyro_rotspeed * delta_millis)

Aber ich dachte, der MPU6050 würde das alles automatisch intern selber rechnen? Sogar samt Kalman-Fusionsfilter ?
Dann muss man doch JEDERZEIT die aktuellen gefilterten und fusionierten Werte für 3D-Gyro-Winkel und 3D-Beschleunigen fix und fertig einfach per i2c-Register-Lesebefehl aktuell auslesen können, ohne jedweden Timer (höchstens noch ein paar Bytes zu 1 Int zusammenaddieren)?
Genau wie man auch sonst jederzeit den aktuellen Wert eines beliebigen anderen Sensors per Funktionsaufruf auslesen kann (sei es analog oder i2c) ?

Wenn nicht, ist er ja gar nicht "inert" sondern nur ein Konglomerat aus Einzelsensoren, deren Werte man selber zu einer "inertial motion unit" per Fusions-Filter zusammenrechnen muss?
Oder braucht man die 0,02 s-IRQs für andere Zwecke?

Problem bei meinem Due ist z.B. dass er die AVR-IRQs gar nicht hat, und die AVR-IRQs sind aber genau die, die auch in den 6050-libs aufgerufen werde, und daher für mich unbrauchbar ...
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste