Problem linking 2 Arduino and 2 MPU6050

Hi guys,

I have a big big problems with my Arduinos, I need your help.
I have 2 Arduino Pro Mini´s each have a MPU6050 and a HC05. I´m using the libraries of Jeff Rowberg
They Bluetooth Connection works well, the MPU6050 do their job.
I can send the MPU6050 data from Device A to Device B.
Device B can print the Bluetooth Data from Device A. Device B can send also his own MPU6050 Data.
BUT when I try to Print the MPU6050 Data of Device A + Device B
Device B should Print the MPU Data of Device A + Device B it all goes after a few lines to crap.
Serial.println(DeviceA + DeviceB);
Has anyone a suggestion for me?

Device A sends:

zeit = String(millis());
deviceA = String("L:\t" + zeit + "\t" + ax_ms + "\t" + ay_ms + "\t" + az_ms);
  
Serial.print("<");
delay(18);
Serial.print(deviceA);
delay(18);
Serial.print("\n");
delay(18);
Serial.end();
Serial.begin(9600);

Device B:

void loop() {  
zeit = String(millis());
deviceB= String("\t R: \t" + zeit + "\t" + ax_ms + "\t" + ay_ms + "\t" + az_ms); 
}
void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '\n';
    char rc;
 
 // if (Serial.available() > 0) {
    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}
void showNewData() {
    if (newData == true) {        
        deviceA=receivedChars
        Serial.println(deviceA + deviceB);


        newData = false;
        Serial.flush();
    }
}

And the output looks like this and get worse:

L: 35689 -13.8 4.84 0.84 R: 556 -10.52 7.25 3.05
L: 3573713.84 4.83 0.83 R: 614 -10.51 7.31 3.2
L: 35785 - 0.8 R: 669 -10.55 7.27 3.14
L: 35832 -13.78 4.81: 35880 -13.84 4.87 0.87 R: 717 -10.51 7.26 3.16
L: 36025 -13.81 4.84 0.8 R: 817 -10.5 7.31 3.2
L: 36072 -13.83 4.84 0.88 R: 874 -10.53 7.28 3.17
L: 36120 -13.8 4.85 0.77 R: 932 -10.48 7.28 3.23
L: 36168 -13.84 4.79 0.85 R: 991 -10.52 7.29 3.05
L: 36216 -13.83 4.82 0.82 R: 1048 -10.47 7.29 3.25
L: 36264 -13.84 4.77 0.86 R: 1107 -10.48 7.27 3.23
L: 36312 -13.8 4.79 0.82 R: 1167 -10.45 7.26 3.1
L: 363609 4.82 0.75 R: 1226 -10.47 7.27 3.13
L: 36408 -13.885 R: 1278 -10.5 7.21 3.21
L: 36456 -13.83 4.83 0.L: 36503 -13.81 4.81 L: 36551 -13.83 4.: 36599 -13.8 4.78 0.83 R: 1371 -10.49 7.28
L: 36647 -13.81 4.78 0.82 R: 1494 -10.46 7.28 3.19
L: 36696 -13.78 4.84 0.79 R: 1553 -10.52 7.31 3.13
L: 367433 0.78 R: 1612 -10.52 7.25 3.14
L: 36791 -13.84 4.8<L: 36839 -13.78 4.8 0.74 R: 1659 -10.48 7.27 3.16

Thanks for your Help!

Well we massively miss code and understanding of what output you are sharing?

In Device B the loops just loops printing the time changing .what is supposed to call recvWithStartEndMarkers?

I would be interested in your complete sketch. I already have 2 mpu6050 gyros attached to uno boards that I could direct connect through software serial and test your setup and see if i can spot the issue.

Just tried to keep it clean an short. Here is the full code, the MPU6050 code is from Jeff Rowberg, as I mentioned before.

Device B:

#include "I2Cdev.h"
#include "MPU6050.h"

// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
// is used in I2Cdev.h
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
#endif

MPU6050 accelgyro;

int16_t ax, ay, az;
int16_t gx, gy, gz;
double ax_ms, ay_ms, az_ms; //m pro sekunde²
String zeit = String();
String deviceB = String();
String left_dev = String();

const byte numChars = 100;
char receivedChars[numChars];
boolean newData = false;


// uncomment "OUTPUT_READABLE_ACCELGYRO" if you want to see a tab-separated
// list of the accel X/Y/Z and then gyro X/Y/Z values in decimal. Easy to read,
// not so easy to parse, and slow(er) over UART.
#define OUTPUT_READABLE_ACCELGYRO

// uncomment "OUTPUT_BINARY_ACCELGYRO" to send all 6 axes of data as 16-bit
// binary, one right after the other. This is very fast (as fast as possible
// without compression or data loss), and easy to parse, but impossible to read
// for a human.
//#define OUTPUT_BINARY_ACCELGYRO
    
void setup() {
    // join I2C bus (I2Cdev library doesn't do this automatically)
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif

    // initialize serial communication
    Serial.begin(9600);

    // initialize device
    Serial.println("Initializing I2C devices...");
    accelgyro.initialize();

    // verify connection
    Serial.println("Testing device connections...");
    Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");

  accelgyro.setXAccelOffset(-3291);
  accelgyro.setYAccelOffset(802);
  accelgyro.setZAccelOffset(659);
  accelgyro.setXGyroOffset(122);
  accelgyro.setYGyroOffset(-23);
  accelgyro.setZGyroOffset(-7);
}

void loop() {  

    // read raw accel/gyro measurements from device
    accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);

    // these methods (and a few others) are also available
    //accelgyro.getAcceleration(&ax, &ay, &az);
    //accelgyro.getRotation(&gx, &gy, &gz);

    #ifdef OUTPUT_READABLE_ACCELGYRO
        // display tab-separated accel/gyro x/y/z values
        ax_ms=98.1*ax/16384;
        ay_ms=98.1*ay/16384;
        az_ms=98.1*az/16384;
        ax_ms=ax_ms/10;
        ay_ms=ay_ms/10;
        az_ms=az_ms/10;

zeit = String(millis());
deviceB= String("\t R: \t" + zeit + "\t" + ax_ms + "\t" + ay_ms + "\t" + az_ms);    

    #endif

    #ifdef OUTPUT_BINARY_ACCELGYRO
        Serial.print(millis());
        Serial.write((uint8_t)(ax >> 8)); Serial.write((uint8_t)(ax & 0xFF));
        Serial.write((uint8_t)(ay >> 8)); Serial.write((uint8_t)(ay & 0xFF));
        Serial.write((uint8_t)(az >> 8)); Serial.write((uint8_t)(az & 0xFF));
        Serial.write((uint8_t)(gx >> 8)); Serial.write((uint8_t)(gx & 0xFF));
        Serial.write((uint8_t)(gy >> 8)); Serial.write((uint8_t)(gy & 0xFF));
        Serial.write((uint8_t)(gz >> 8)); Serial.write((uint8_t)(gz & 0xFF));
    #endif
    
    recvWithStartEndMarkers();
    showNewData();
}

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '\n';
    char rc;
 
 // if (Serial.available() > 0) {
    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}
void showNewData() {
    if (newData == true) {        
        Serial.println(receivedChars + deviceB);
        newData = false;
        Serial.flush();
    }
}

Device A:

#include "I2Cdev.h"
#include "MPU6050.h"

// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
// is used in I2Cdev.h
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif

MPU6050 accelgyro;
//MPU6050 accelgyro(0x69); // <-- use for AD0 high

int16_t ax, ay, az;
int16_t gx, gy, gz;
double ax_ms, ay_ms, az_ms;
String zeit = String();
String deviceA = String();
float zeit2;
String stringData = String();

// uncomment "OUTPUT_READABLE_ACCELGYRO" if you want to see a tab-separated
// list of the accel X/Y/Z and then gyro X/Y/Z values in decimal. Easy to read,
// not so easy to parse, and slow(er) over UART.
#define OUTPUT_READABLE_ACCELGYRO

// uncomment "OUTPUT_BINARY_ACCELGYRO" to send all 6 axes of data as 16-bit
// binary, one right after the other. This is very fast (as fast as possible
// without compression or data loss), and easy to parse, but impossible to read
// for a human.
//#define OUTPUT_BINARY_ACCELGYRO

#define LED_PIN 13
bool blinkState = false;

void setup() {
  pinMode(3, OUTPUT);

  // join I2C bus (I2Cdev library doesn't do this automatically)
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
  Wire.begin();
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
  Fastwire::setup(400, true);
#endif

  Serial.begin(9600);

  // initialize device
  //Serial.println("Initializing I2C devices...");
  accelgyro.initialize();

  accelgyro.setXAccelOffset(-3291);
  accelgyro.setYAccelOffset(802);
  accelgyro.setZAccelOffset(659);
  accelgyro.setXGyroOffset(122);
  accelgyro.setYGyroOffset(-23);
  accelgyro.setZGyroOffset(-7);
}

void loop() {
  // read raw accel/gyro measurements from device
  accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);

  // these methods (and a few others) are also available
  //accelgyro.getAcceleration(&ax, &ay, &az);
  //accelgyro.getRotation(&gx, &gy, &gz);

#ifdef OUTPUT_READABLE_ACCELGYRO
  // display tab-separated accel/gyro x/y/z values
  ax_ms = 98.1 * ax / 16384;
  ay_ms = 98.1 * ay / 16384;
  az_ms = 98.1 * az / 16384;
  ax_ms = ax_ms / 10;
  ay_ms = ay_ms / 10;
  az_ms = az_ms / 10;

  zeit = String(millis());
  deviceA = String("L:\t" + zeit + "\t" + ax_ms + "\t" + ay_ms + "\t" + az_ms);
  
  Serial.print("<");
  delay(18);
  Serial.print(deviceA);
  delay(18);
  Serial.print("\n");
  delay(18);
  //Serial.flush();
  Serial.end();
  Serial.begin(9600);
#endif

#ifdef OUTPUT_BINARY_ACCELGYRO
  Serial.print("L: "); Serial.print("\t");
  Serial.print(millis()); Serial.print("\t");
  Serial.write((uint8_t)(ax >> 8)); Serial.write((uint8_t)(ax & 0xFF));
  Serial.write((uint8_t)(ay >> 8)); Serial.write((uint8_t)(ay & 0xFF));
  Serial.write((uint8_t)(az >> 8)); Serial.write((uint8_t)(az & 0xFF));
  Serial.write((uint8_t)(gx >> 8)); Serial.write((uint8_t)(gx & 0xFF));
  Serial.write((uint8_t)(gy >> 8)); Serial.write((uint8_t)(gy & 0xFF));
  Serial.write((uint8_t)(gz >> 8)); Serial.write((uint8_t)(gz & 0xFF));
#endif
}

I use the Method "recvWithStartEndMarkers" to recognize the start and the end of an incoming Serial Line.

String zeit = String();
String deviceA = String();
float zeit2;
String stringData = String();

Have you seen ANY other examples that initialize Strings this way?

String zeit;

creates a memory fragmenting/resource wasting object of type String.

Your code, both ends. should contain ZERO objects of type String.

Okay I kicked them out.
But it didn´t solve my Problem...

Okay I kicked them out.

So, you changed your code.

But it didn´t solve my Problem...

Well, you won't get any help here, without posting your code.

Ahh okay, sorry I´m not used to the behaviour here yet.
It works now, it seems that I used the Serial.flush/Serial.end commands wrong.

But I have a new problem: After around 30 seconds it all stops. It seems, that the receiving Arduino can´t handle the data or the buffer is full? The timestamp (Delta-millis) get´s pretty long - at DeviceB (Receiver) it goes up to 100ms. Does the Serial.print Command use too much ressources?

DeviceB

#include "I2Cdev.h"
#include "MPU6050.h"

// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
// is used in I2Cdev.h
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
#endif

MPU6050 accelgyro;
//MPU6050 accelgyro(0x69); // <-- use for AD0 high

int16_t ax, ay, az;
int16_t gx, gy, gz;
double ax_ms, ay_ms, az_ms; //m pro sekunde²

const byte numChars = 100;
char receivedChars[numChars];
boolean newData = false;


// uncomment "OUTPUT_READABLE_ACCELGYRO" if you want to see a tab-separated
// list of the accel X/Y/Z and then gyro X/Y/Z values in decimal. Easy to read,
// not so easy to parse, and slow(er) over UART.
#define OUTPUT_READABLE_ACCELGYRO

// uncomment "OUTPUT_BINARY_ACCELGYRO" to send all 6 axes of data as 16-bit
// binary, one right after the other. This is very fast (as fast as possible
// without compression or data loss), and easy to parse, but impossible to read
// for a human.
//#define OUTPUT_BINARY_ACCELGYRO
    
void setup() {
    //Tiefpassfilter aktivieren  
    //accelgyro.setDLPFMode(0x03);    

    // join I2C bus (I2Cdev library doesn't do this automatically)
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif

    // initialize serial communication
    Serial.begin(9600);

    // initialize device
    Serial.println("Initializing I2C devices...");
    accelgyro.initialize();

    // verify connection
    Serial.println("Testing device connections...");
    Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");

  accelgyro.setXAccelOffset(-3291);
  accelgyro.setYAccelOffset(802);
  accelgyro.setZAccelOffset(659);
  accelgyro.setXGyroOffset(122);
  accelgyro.setYGyroOffset(-23);
  accelgyro.setZGyroOffset(-7);
}

void loop() {  

    // read raw accel/gyro measurements from device
    accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);

    #ifdef OUTPUT_READABLE_ACCELGYRO
        // display tab-separated accel/gyro x/y/z values
        ax_ms=98.1*ax/16384;
        ay_ms=98.1*ay/16384;
        az_ms=98.1*az/16384;
        ax_ms=ax_ms/10;
        ay_ms=ay_ms/10;
        az_ms=az_ms/10;
    #endif

    #ifdef OUTPUT_BINARY_ACCELGYRO
        //Serial.print(millis());
        //Serial.println("  "); 
        Serial.print(millis());
        Serial.write((uint8_t)(ax >> 8)); Serial.write((uint8_t)(ax & 0xFF));
        Serial.write((uint8_t)(ay >> 8)); Serial.write((uint8_t)(ay & 0xFF));
        Serial.write((uint8_t)(az >> 8)); Serial.write((uint8_t)(az & 0xFF));
        Serial.write((uint8_t)(gx >> 8)); Serial.write((uint8_t)(gx & 0xFF));
        Serial.write((uint8_t)(gy >> 8)); Serial.write((uint8_t)(gy & 0xFF));
        Serial.write((uint8_t)(gz >> 8)); Serial.write((uint8_t)(gz & 0xFF));
    #endif
    
    recvWithStartEndMarkers();
    showNewData();
}

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '\n';
    char rc;
 
 // if (Serial.available() > 0) {
    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }
        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}
void showNewData() {
    if (newData == true) {        
        Serial.print(receivedChars);        
        
        Serial.print("R: "); Serial.print("\t");
        Serial.print(millis()); Serial.print("\t");
        Serial.print(ax_ms); Serial.print("\t");
        Serial.print(ay_ms); Serial.print("\t");
        Serial.print(az_ms); Serial.println("\t");        
        newData = false;        
        Serial.end();
        Serial.begin(9600);
    }
}
#include "I2Cdev.h"
#include "MPU6050.h"

// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
// is used in I2Cdev.h
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
  #include "Wire.h"
#endif

MPU6050 accelgyro;
//MPU6050 accelgyro(0x69); // <-- use for AD0 high

int16_t ax, ay, az;
int16_t gx, gy, gz;
double ax_ms, ay_ms, az_ms;

// uncomment "OUTPUT_READABLE_ACCELGYRO" if you want to see a tab-separated
// list of the accel X/Y/Z and then gyro X/Y/Z values in decimal. Easy to read,
// not so easy to parse, and slow(er) over UART.
#define OUTPUT_READABLE_ACCELGYRO

// uncomment "OUTPUT_BINARY_ACCELGYRO" to send all 6 axes of data as 16-bit
// binary, one right after the other. This is very fast (as fast as possible
// without compression or data loss), and easy to parse, but impossible to read
// for a human.
//#define OUTPUT_BINARY_ACCELGYRO

void setup() {
    // join I2C bus (I2Cdev library doesn't do this automatically)
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
  Wire.begin();
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
  Fastwire::setup(400, true);
#endif

  Serial.begin(9600);

  // initialize device
  accelgyro.initialize();

  accelgyro.setXAccelOffset(-3291);
  accelgyro.setYAccelOffset(802);
  accelgyro.setZAccelOffset(659);
  accelgyro.setXGyroOffset(122);
  accelgyro.setYGyroOffset(-23);
  accelgyro.setZGyroOffset(-7);
}
void loop() {
  if ( Serial.available() )      // if data is available to read
    // read raw accel/gyro measurements from device
  accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);

#ifdef OUTPUT_READABLE_ACCELGYRO
  // display tab-separated accel/gyro x/y/z values
  ax_ms = 98.1 * ax / 16384;
  ay_ms = 98.1 * ay / 16384;
  az_ms = 98.1 * az / 16384;
  ax_ms = ax_ms / 10;
  ay_ms = ay_ms / 10;
  az_ms = az_ms / 10;

Serial.print("<");
Serial.print("L: "); Serial.print("\t");
Serial.print(millis()); Serial.print("\t");
Serial.print(ax_ms); Serial.print("\t");
Serial.print(ay_ms); Serial.print("\t");
Serial.print(az_ms); Serial.print("\t");
Serial.print("\n");
#endif

#ifdef OUTPUT_BINARY_ACCELGYRO
  Serial.print("L: "); Serial.print("\t");
  Serial.print(millis()); Serial.print("\t");
  Serial.write((uint8_t)(ax >> 8)); Serial.write((uint8_t)(ax & 0xFF));
  Serial.write((uint8_t)(ay >> 8)); Serial.write((uint8_t)(ay & 0xFF));
  Serial.write((uint8_t)(az >> 8)); Serial.write((uint8_t)(az & 0xFF));
  Serial.write((uint8_t)(gx >> 8)); Serial.write((uint8_t)(gx & 0xFF));
  Serial.write((uint8_t)(gy >> 8)); Serial.write((uint8_t)(gy & 0xFF));
  Serial.write((uint8_t)(gz >> 8)); Serial.write((uint8_t)(gz & 0xFF));
#endif
}

I think you're overflowing the TX buffer. There is space for 63 bytes, you send 12 bytes (binary mode) just for data of the device itself. One byte takes about 1ms (at 9600 bits per second), so those 12 bytes take 12 ms. Your loop is however a lot faster than that and hence the overflow.

Increase your baudrate to 115200 would improve the situation, but I don't know if that is an option. The serial class also has a method to check how much space is available in the TX buffer. Read Serial.availableForWrite() - Arduino Reference. Do not send if there is not enough space.

  if ( Serial.available() )      // if data is available to read
    // read raw accel/gyro measurements from device
  accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);

Why on earth are you reading the accelerometer only if there is serial data?

    #ifdef OUTPUT_READABLE_ACCELGYRO
        // display tab-separated accel/gyro x/y/z values
        ax_ms=98.1*ax/16384;
        ay_ms=98.1*ay/16384;
        az_ms=98.1*az/16384;
        ax_ms=ax_ms/10;
        ay_ms=ay_ms/10;
        az_ms=az_ms/10;
    #endif

That does NOT do what the ifdef statement and comment claim.

What purpose is served sending accelerometer data from one Arduino to the other Arduino that has an accelerometer attached?

@sterretje: Setting up the Baudrate olved my problem, thank you so much!