Seems that Wire and Serial cannot work together!

First of all, I am pretty much newbie in the world of Arduino, but know fundamentals. I am trying to set up project with MPU5060 and ESP modules, communicating with I2C and Serial1 respectively. Each of them works independently PERFECT, but if I put both of them on the arduino ATmega2560, it hangs after 1 - 2 minutes. So I did additional investigation on this and found there is some hanging code in “endTransmission” and “requestFrom” methods. I was playing a couple of hours with registers like TWCR and similar, trying to make some recovery, but nothing helps. I really want to know what is common interfering thing for these two libs that makes everything blocked. To make this troubleshooting easier, here is the simplified part of the code. Any help is appreciated!

#include "Wire.h"

#define MPU_ADDRESS 0x68

void setup() {

    Serial.begin(115200);
    Serial1.begin(115200);

    Wire.begin();
    Wire.beginTransmission(MPU_ADDRESS);
    Wire.write(0x6B);
    Wire.write(0x00);
    Wire.endTransmission();

    delay(1000);
    Serial1.println("AT+CIPMUX=1");
    delay(500);
    Serial1.println("AT+CIPSTART=0,\"UDP\",\"192.168.4.2\",3333,3333,0");
    delay(500);
}

char t;
void loop() {
    
    Wire.beginTransmission(MPU_ADDRESS);
    Wire.write(0x3B);
    Wire.endTransmission(); // HANGS !
    Wire.requestFrom(MPU_ADDRESS, 14); // HANGS !

    for (t = 0; t < 14; t++) {
        Wire.read();
    }

    if (Serial1.available()) {
        Serial.println(Serial1.read());
    }
}

did you try this for the wire request?

Wire.beginTransmission(MPU_addr); Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H) Wire.endTransmission(false); Wire.requestFrom(MPU_addr,14,true); // request a total of 14 registers

(btw you don't seem to be doing anything with the read, is that correct!?)

You should check the return value of Wire.endTransaction() and Wire.requestFrom() and act accordingly if there was an error.

Thank you a lot for your quick replies.

@sherzaad, I have tried that at very beginning and there was no a difference. I will do a lot of calculations with a data received from read() methods, but I have intentionally left out that code to keep our focus on the issue itself.

@pylon, Wire.endTransaction() returns 4 which means other errors per documentation. Some kind of recovery I made for Wire library didn't help a lot. Actually, recovery prolonged execution for about a minute, that is all.

Wire.beginTransmission(MPU_ADDRESS);
    Wire.write(0x3B);
    wire_state = Wire.endTransmission(); // HANGS !
    Wire.requestFrom(MPU_ADDRESS, 14); // HANGS !
    // RECOVERY, wait until TWCR becomes 0
    while (wire_state != 0) {
        TWCR = 0;
        Wire.begin();
        Wire.beginTransmission(MPU_ADDRESS);
        Wire.write(0x3B);
        wire_state = Wire.endTransmission();
    }
    Wire.requestFrom(MPU_ADDRESS,14);

Wire.endTransaction() returns 4 which means other errors per documentation. Some kind of recovery I made for Wire library didn't help a lot. Actually, recovery prolonged execution for about a minute, that is all.

That means most probably you have a hardware problem. Post a wiring diagram of your complete setup!

TWCR = 0;

Never do that! You either use the Wire library to handle the I2C interface or you use the low level registers. If you mix the two you probably get more problems than you can handle. The above code is definitely wrong which shows that you don't know enough about the hardware registers to modify them yourself.

I have attached complete diagram. I don’t think this is hardware issue since it works fine if I comment out either code for I2C communication or Serial communication! It hangs only if both I2C and serial communication are enabled. Maybe power supply could cause this issue, but not sure since I have both modules powered up from board the entire time. Maybe power consumption is much higher if they are processing communication. Board is equipped with standard AMS1117 which can provide enough power I guess.

I have tried some kind of “recovery” with modifying TWCR not because I know what I am doing but found it here http://forum.arduino.cc/index.php?topic=425303.0

just curious... did you try reducing the Serial baudrate (if that is possible)?

would be interesting to see if in your code you just changed the baud rate to... let say 9600.

do is still lock up then?

Is your ESP board 5V tolerant? Many are not. If you connect them directly to Arduino TX/RX the internal protection diodes get too hot.

Desolder the Mega2560 onboard I2C pullup resistors as they pull the signal to 5V which might destroy the MPU6050 after some time or at least leads to the same problem as described above.

It's difficult to mix 3.3V and 5V boards without using level converters in between.

How do you power your setup?

I have tried some kind of "recovery" with modifying TWCR not because I know what I am doing but found it here http://forum.arduino.cc/index.php?topic=425303.0

If you read the thread completely you'd know that you have to re-initialize the I2C hardware again after you manipulated TWCR (Wire.begin(), etc.).

Try lowering the serial speed as sherzaad suggested. That might be a problem if the I2C signal wires are in parallel with the serial wires for a few centimeters.

@OP

I have not encountered any problem to operate MPU6050 and ESP8266 simultaneously using I2C Bus and UART1-SUART Port. (I added for my own shake few lines of codes with your program). Look at the following Serial Monitors. The MEGA is acquiring signal well from 14-registers of MPU6050 and printing them on its Serial Monitor; the MEGA is also acquiring signal from ESP using Serial1 Port and printing the received character (Q) on the Serial Monitor. The ESP is also receiving messages from MEGA and printing them on its Serial Monitor.

uartesp-3.png

sm35.png

sm36.png

MEGA-Codes:

#include <Wire.h>
#include <MPU6050.h>
#define MPU_ADDRESS 0x69  //in my Library the address is coded as 0x69

MPU6050 mpu;   //device address 0x69 keyed in Librart AD0=LH
byte dataArray[14];

void setup()
{
  Serial.begin(115200);//9600);
  Serial.println("Initialize MPU6050");
  Serial1.begin(115200);//9600);

  while (!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
  {
    Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
    delay(1000);
  }
  Wire.beginTransmission(MPU_ADDRESS);
  Wire.write(0x6B);
  Wire.write(0x00);
  Wire.endTransmission();

  delay(1000);
  Serial1.println("AT+CIPMUX=1");
  delay(500);
  Serial1.println("AT+CIPSTART=0,\"UDP\",\"192.168.4.2\",3333,3333,0");
  delay(500);
}

void loop()
{
  float temp = mpu.readTemperature();

  Serial.print(" Temp = ");
  Serial.print(temp, 2);
  Serial.println(" *C");
  //-------------------------
  Wire.beginTransmission(MPU_ADDRESS);
  Wire.write(0x3B);
  Wire.endTransmission(); // HANGS !
  
  Wire.requestFrom(MPU_ADDRESS, 14); // HANGS ! It does not HANG in my case!

  for (int t = 0; t < 14; t++) 
  {
    dataArray[t] = Wire.read();
    Serial.print(dataArray[t], HEX);
  }

  Serial.print("  ");
  

  if (Serial1.available()>0) 
  {
    Serial.println((char)Serial1.read());
  }
  Serial.println();
  delay(1000);
}

ESP-Codes:

#include<SoftwareSerial.h>
SoftwareSerial mySUART(4, 5);  //D2, D1 = SRX, STX

void setup()
{
  Serial.begin(115200);
  mySUART.begin(115200);
}

void loop()
{
  if (Serial.available() > 0)
  {
    byte x = Serial.read();
    mySUART.write(x);
  }
  if (mySUART.available() > 0)
  {
    Serial.write((char)mySUART.read());
  }
}

uartesp-3.png

sm35.png

sm36.png

I tried to lower baudrates at very beginning, also I have flashed the esp module and outcome was the same. My ESP is 5V tolerant. After some rearrangement of the modules this issue has gone, it is probably something with signal interfering between data wires of these modules and it turns out it is really sensitive.

Many thanks to you all for help!