Übertragungsverzögerung MPU6050 per Bluetooth

Hallo,

ich bin noch Arduino-Neuling und brauche einmal Hilfe.
Ich arbeite momentan an einem Versuchsaufbau, bei dem ich mit einem MPU6050 Sensor die Drehgeschwindigkeit überwache.
Der Sensor ist mit einem HC-06 Bluetooth-Modul verbunden, das habe ich so als fertige Lösung gekauft (siehe: https://www.amazon.de/Bluetooth-MPU6050-Ausgang-Beschleunigungsmesser-Gyroskop/dp/B01LXXHUDR). Es wird lt Hersteller ein Kalmanfilter verwendet, als Werte bekomme ich Beschleunigung, Winkelgeschwindigkeit und Winkel je Raumachse plus die Temperatur.
Empfangen wird das ganze per HC-05 Modul mit einem Arduino.
Dieser erstellt abhängig von der empfangenen Winkelgeschwindigkeit eine Rechteckspannung, über deren Frequenz ich die Winkelgeschwindigkeit mit einem Messgerät bestimmen kann.

Ich habe in einem Versuch festgestellt, dass der so ausgelesene Wert der tatsächlichen Drehgeschwindigkeit um etwa 55ms hinterher läuft.

Der Sensor gibt die Werte in einer Frequenz von 100 Werten pro Sekunde aus, also ist der beste Wert eine Verzögerung von 10ms.

Ich habe mir einmal die Zeit ausgeben lassen, die der Arduino für das Durchlaufen seiner Schleife braucht und bekam da einen maximalen Wert von 2ms. Ich frage mich, wo die übrige Verzögerung herkommt. Ist die Schnittstelle etwa so langsam?

Ich würde intuitiv vermuten, dass der Chip mit dem Sensor noch weitere Verzögerungen verursacht, leider ist das für mich eine Blackbox.

Mein Code:

/*
This code is used for connecting arduino to serial mpu6050 module, and test in arduino uno R3 board.
connect map:
arduino   mpu6050 module
VCC    5v/3.3v
TX     RX<-0
TX     TX->1
GND    GND
note: 
because arduino download and mpu6050 are using the same serial port, you need to un-connect 6050 module when you want to download program to arduino.
 Created 14 Nov 2013
 by Zhaowen
 
 serial mpu6050 module can be found in the link below:
 http://item.taobao.com/item.htm?id=19785706431
 */

//#include <SoftwareSerial.h>
#include<math.h>
#include <toneAC.h>

unsigned char Re_buf[11],counter=0;
unsigned char sign=0;
unsigned int frequency;       //Zero-frequency/offset
unsigned int freqRef=0;       //Reference frequency from the loop before
unsigned int res=30;          //Auflösung: +1°/sek -> +10Hz
float a[3],w[3],angle[3],T;   //Arrays for acceleration, angular speed, angle and temperature
//int pinTone = 10;             //Output pin for frequency
short i=0;                    //Counter of loops. Used for indication of successful connection
short axis = 1;               //axis of measurement. 0: x across direction of BT-module, 1: y along direction of BT-module, 2 = z;

void setup() {
  pinMode(13,OUTPUT);
  digitalWrite(13, LOW);      //Indication for connection. Default LOW
  Serial.begin(115200);       //Initialize serial. Baud rate of 115200 is fixed on the sensor
  digitalWrite(12,HIGH);
}

void loop(){
  if(sign)
  {  
    i=0;
    sign=0;
    if(Re_buf[0]==0x55)       //检查帧头   -- Check the header
    {  
      switch(Re_buf [1])
      {
        case 0x51:
          a[0] = (short(Re_buf [3]<<8| Re_buf [2]))/32768.0*16;
          a[1] = (short(Re_buf [5]<<8| Re_buf [4]))/32768.0*16;
          a[2] = (short(Re_buf [7]<<8| Re_buf [6]))/32768.0*16;
          T = (short(Re_buf [9]<<8| Re_buf [8]))/340.0+36.25;
          break;
        case 0x52:
          w[0] = (short(Re_buf [3]<<8| Re_buf [2]))/32768.0*2000;
          w[1] = (short(Re_buf [5]<<8| Re_buf [4]))/32768.0*2000;
          w[2] = (short(Re_buf [7]<<8| Re_buf [6]))/32768.0*2000;
          T = (short(Re_buf [9]<<8| Re_buf [8]))/340.0+36.25;
          break;
        case 0x53:
          angle[0] = (short(Re_buf [3]<<8| Re_buf [2]))/32768.0*180;
          angle[1] = (short(Re_buf [5]<<8| Re_buf [4]))/32768.0*180;
          angle[2] = (short(Re_buf [7]<<8| Re_buf [6]))/32768.0*180;
          T = (short(Re_buf [9]<<8| Re_buf [8]))/340.0+36.25;
          frequency = 2500 + round(w[axis]);    
          toneAC(frequency);
          //digitalWrite(pinTone, HIGH);
          //Serial.print("a:");
          //Serial.print(a[0]);Serial.print(" ");
          //Serial.print(a[1]);Serial.print(" ");
          //Serial.print(a[2]);Serial.print(" ");
          //Serial.print("w:");
          /*Serial.print("x:");
          Serial.print(round(10*w[0])/10);Serial.print(";");
          Serial.print("y:");
          Serial.print(round(10*w[1])/10);Serial.print(";");*/
          Serial.print("z:");
         //Serial.print(axis); Serial.print(":");
          Serial.print(round(w[2]));Serial.println(";");
//          Serial.println(frequency);
   
//        Serial.print("angle:");
       /* Serial.print(angle[0]+180);Serial.print(";");
          Serial.print(angle[1]+180);Serial.print(";");
          Serial.println(angle[1]+180); Serial.print(" ");*/
/*        Serial.print("T:");
          Serial.println(T);*/
          break;
      } 
    }
  }
  else{
    i++;
    if(i>10000){
      digitalWrite(13,LOW);                     //Wait for a high number of loops. If still no connection to BT, turn off LED
    }
  }
}

void serialEvent() {
  while (Serial.available()) {
    digitalWrite(13,HIGH);                      //Indicate successful data transfer from BT
    //char inChar = (char)Serial.read(); Serial.print(inChar); //Output Original Data, use this code 
    
    Re_buf[counter]=(unsigned char)Serial.read();
    if(counter==0&&Re_buf[0]!=0x55) return;     //第0号数据不是帧头  -- No. 0 data is not a header            
    counter++;       
    if(counter==11)                             //接收到11个数据  -- Received 11 data
    {
      counter=0;                                //重新赋值,准备下一帧数据的接收   -- Reassigned, ready to receive the next frame of data
      sign=1;
    }  
  }
}

Jedes Filter verögert das Signal, das dürfte hier den größten Anteil ausmachen.

Nachvollziehbar.

Angeblich kann der Chip ohne Filter betrieben werden. Im Idealfall würde ich mir einfach die Rohdaten über BT schicken lassen und im Arduino eine simple Glättung einbauen. Beschleunigung und Winkel brauche ich nicht. Lässt sich der Chip neu programmieren? Ist so etwas für einen Anfänger machbar? Leider ist der Hersteller ein Chinese ohne Kontaktdaten.

Für Amazon-Verhältnisse wird da ja schon viel auf der verlinkten Seite geboten, incl. zwei (für mich) nicht funktionierenden drive.google.com Links. Kommst du da mit deiner Lieferung weiter?

Ausserdem scheint das Modul auch eine Serielle Schnittstelle und eine I2C Schnittstelle zu unterstützen? Kannst ja mal testen, was du ohne Bluetooth overhead bekommst...

Die beworbenen 100 Hz gelten wohl, wenn überhaupt, für den nackten MPU-Modul (mit direkter 115200 USB-TTL seriell-Verbindung)

michael_x:
Für Amazon-Verhältnisse wird da ja schon viel auf der verlinkten Seite geboten, incl. zwei (für mich) nicht funktionierenden drive.google.com Links. Kommst du da mit deiner Lieferung weiter?

Ausserdem scheint das Modul auch eine Serielle Schnittstelle und eine I2C Schnittstelle zu unterstützen?
Kannst ja mal testen, was du ohne Bluetooth overhead bekommst…

Die beworbenen 100 Hz gelten wohl, wenn überhaupt, für den nackten MPU-Modul (mit direkter 115200 USB-TTL seriell-Verbindung)

Ja, es hat beide Schnittstellen. Ob ich die Daten seriell per Bluetooth oder Kabel übertrage gibt an sich das gleiche Ergebnis - nur dass ich per Kabel die Verzögerung nicht testen kann, weil sich der Sensor in meinem Aufbau um eine Achse dreht, weshalb ich ihn nur kabellos testen kann. Mit I2C habe ich mich noch nie beschäftigt.

Die Daten, die ich per Bluetooth mitgeschrieben habe, kamen auch mit etwa 100Hz an.

Ich konnte auf der US-Seite von Amazon einen funktionierenden Google.drive-link finden: https://drive.google.com/file/d/0B8PmY6nhQadKWGNJbmNoRTBtNjA/view
In “MPU6050 material” > “Datasheet” finden sich zwei PDF’s in denen eine die Konfiguration des Lowpassfilters beschreibt (Siehe Anhang).

Vor allem die Tabelle unter

The DLPF is configured by DLPF_CFG. The accelerometer and gyroscope are filtered according to the value of DLPF_CFG as shown in the table below.

scheint mir exakt das zu sein, was ich suche.
Nur: wie konfiguriere ich das gute Stück? Ich habe leider keine Ahnung, wie ich auf die Parameter zugreifen kann.

Grüße,
Nik

MPU-6050 Register.pdf (650 KB)

An die MPU Register kommst Du nur über I2C dran, und die werden höchstwahrscheinlich von dem on-board Controller eingestellt, der auch das Kalman-Filter implementiert.

Ich sehe nur zwei Möglichkeiten: das Modul so verwenden, wie es ist, oder einen MPU6050 direkt anschließen.

Verstehe ich es richtig, dass der Onboardcontroller eine Standardkonfiguration hat, die beim Einschalten automatisch geladen wird? Und über die I2C Schnittstelle kann ich direkt mit dem MPU kommunizieren? Also wenn ich bestimmte Parameter verändere, würden die wieder zurückgesetzt, wenn ich mich beim nächsten Mal per TTL verbinde?

Ich hatte gehofft, das Modul einmal konfigurieren und dann mit den Einstellungen die Bluetoothverbindung nutzen zu können

Der MPU kann kein Bluetooth, deshalb muß noch ein Controller irgendwo auf dem Modul sitzen, der den Datenverkehr managt. Dieser Controller implementiert vermutlich auch das Kalman-Filter, das die Datenrate drückt.

Danke, du hast mir sehr weiter geholfen.

Ich überlege gerade, alternativ eine eigene Lösung zu bauen, indem ich den MPU an ein Adafruit Board mit ATtiny hänge, welches die Sensordaten per BT, zB HC06, an meinen Arduino schickt. Dann wäre ich insgesamt flexibler mit der Datenrate und den Filtereinstellungen.

Die Frage, die sich mir stellt ist, ob das Board gleichzeitig eine I2C und TTL Schnittstelle betreiben kann. Ich habe gelesen, dass man sich zB Pin 3 und 4 als TX/RX Pins definieren kann, können dann gleichzeitig Pin 0 und 2 für eine I2C Verbindung genutzt werden?