Possible conflitct between Wire.h (for MPU6050) and SoftwareSerial.h (for HC05)

Hello. I’m currently working on a tank type vehicle remotely controlled by a “glove”. This glove is actually equipped with an arduino nano, a MPU6050 for orientation sensing (using accelerometer raw data) and a HC05 (ZS040) configured as Master. The tank itself is an arduino uno connected to a slave HC05 (FC114), a H-Bridge, two dc motors and another MPU6050 used as an “dangerous angles sensor”. This second MPU6050 in the tank senses its orientation so that if the tank is climbing an obstacle that is too big and will cause it to flip over or loose stability it will activate a safety routine that will override the HC05 commands and return the tank to a safe position.

This is the main idea and most of it actually works. We got the glove to successfully capture the MPU6050 raw accelerometer data and send specific numbers for each of the 4 possible movements that we needed (Foward, Backwards, Left, Right) using the master hc05. The tank is able to receive the data via slave hc05 and run the motors correctly.

But the bug appears when we try to implement the safety routines. In the slave code, we are using Wire library to establish the serial communication between the MPU6050 and the Uno and using SoftwareSerial to establish the serial communication between HC05 and the Uno. Whenever we try to begin the wire transmission in void loop() the tank works correctly (both control and safety routines) but some seconds later it just freezes the hc05 serial in the last command received so the motor keeps running forever in the last direction we sent. This doesn’t happen if we pop the MPU6050 out of the circuit or if we comment the Wire related code in void loop().

We tried a lot of things, including changing the SoftwareSerial ports to analog pins and then digital only pins, tried to change the SoftwareSerial library to ALTsoftwareserial and it didn’t work. We are completely lost now with no other idea to test.

And as for the reason of the problem, our main shot is some kind of conflict between these two libraries as we saw some similar cases online (but with no solution).

The code we are using is as following:

/////////////////////////////////////////////////////  CÓDIGO DO ESCRAVO (FS-114)///////////////////////////////////////////////////////
                                      

//========================= INICIALIZAÇÃO DAS BIBLIOTECAS E PARÂMETROS DO SENSOR MPU6050 ============================//
#include "Wire.h"         // BIBLIOTECA DE COMUNICAÇÃO I2C
const int MPU_ADDR = 0x69;
int16_t accelerometer_x, accelerometer_y, accelerometer_z; 
int16_t gyro_x, gyro_y, gyro_z; 
int16_t temperature; 
char tmp_str[7]; 
char* convert_int16_to_str(int16_t i) { 
  sprintf(tmp_str, "%6d", i);
  return tmp_str;
}
//=====================================================================================================================


//========================= INICIALIZAÇÃO DAS BIBLIOTECAS E PARÂMETROS DO MÓDULO BLUETOOTH ============================//
#include <SoftwareSerial.h>                 //COMUNICAÇÃO SERIAL VIRUTALIZADA 
SoftwareSerial HC05(10, 11);                //SIMULA TX E RX NAS PORTAS 10 E 11
//=====================================================================================================================

//========================= INICIALIZAÇÃO DE VARIÁVEIS ============================//

///PINOS DOS MOTORES
int EN_A = 5;       //PINO DE ENABLE DO MOTOR A
int IN1 = 9;        //PINO DE CONTROLE DO MOTOR A
int IN2 = 8;        //PINO DE CONTROLE DO MOTOR A
int IN3 = 7;        //PINO DE CONTROLE DO MOTOR B
int IN4 = 6;        //PINO DE CONTROLE DO MOTOR B
int EN_B = 3;       ///PINO DE ENABLE DO MOTOR N

int pinoRed = 12;       //PINO DIGITAL UTILIZADO PELO TERMINAL VERMELHO
int pinoGreen = 13;     //PINO DIGITAL UTILIZADO PELO TERMINAL VERDE
int velocidade = 150;   //VELOCIDADE DOS MOTORES

//BLUETOOTH  
int  state; //ARMAZENA DADOS RECEBIDOS DO BLUETOOTH HC05  
//====================================================================================

void setup()
{ 
//========================= INICIALIZAÇÃO DOS PINOS ============================//  

//PINOS DOS MOTORES
pinMode(EN_A, OUTPUT);
pinMode(IN1, OUTPUT);  
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);  
pinMode(IN4, OUTPUT);
pinMode(EN_B, OUTPUT);

//PINOS DOS LEDS VERMELHO E VERDE
pinMode(pinoRed, OUTPUT); //DEFINE O PINO COMO SAÍDA
pinMode(pinoGreen, OUTPUT); //DEFINE O PINO COMO SAÍDA

//========================= SETUP DO MÓDULO BLUETOOTH ============================//
HC05.begin(38400);      // DEFINE A TAXA DE TRANSMISSÃO DO MÓDULO BLUETOOTH
Serial.begin(38400);     // DEFINE A TAXA DE TRANSMISSÃO DO MONITOR SERIAL
//=================================================================================

//========================= SETUP DO SENSOR MPU6050 ============================//
Wire.begin();
Wire.beginTransmission(MPU_ADDR); 
Wire.write(0x6B); 
Wire.write(0);
Wire.endTransmission(true);
//=================================================================================

}
void loop()
{
//SE TIVER ALGO NO SERIAL DO BLUETOOTH, COLOCA O DADO NA VARIÁVEL E INICIA O LED VERDE
if (HC05.available() > 0) { 
state = HC05.parseInt();  
digitalWrite(pinoGreen, HIGH);
digitalWrite(pinoRed, LOW);
} 

//ROTINAS DE SEGURANÇA
//Wire.beginTransmission(MPU_ADDR);
//Wire.write(0x3B); 
//Wire.endTransmission(false); 
//Wire.requestFrom(MPU_ADDR, 7*2, true); 
//accelerometer_x = Wire.read()<<8 | Wire.read(); 
//accelerometer_y = Wire.read()<<8 | Wire.read(); 
//Serial.print("aX = "); Serial.print(convert_int16_to_str(accelerometer_x));
//Serial.println("aY = "); Serial.print(convert_int16_to_str(accelerometer_y));
//
//if (accelerometer_y>9000 && accelerometer_x >-5000 && accelerometer_x <5000){
//int cont = 0;
//while (cont<1)
//{
//digitalWrite(pinoGreen, LOW);
//digitalWrite(pinoRed, HIGH); 
//digitalWrite(IN2, LOW);
//digitalWrite(IN1, HIGH);
//analogWrite(EN_A, velocidade);
//digitalWrite(IN3, LOW);
//digitalWrite(IN4, HIGH);
//analogWrite(EN_B, velocidade); 
//cont = ++cont;
//delay(1000);
//}
//}
//if (accelerometer_y<-9000 && accelerometer_x >-5000 && accelerometer_x <5000){
//int cont = 0;
//while (cont<1)
//{    
//digitalWrite(pinoGreen,LOW);
//digitalWrite(pinoRed, HIGH);    
// 
//digitalWrite(IN3, HIGH);
//digitalWrite(IN4, LOW);
//analogWrite(EN_B, velocidade);
//digitalWrite(IN2, HIGH);
//digitalWrite(IN1, LOW);
//analogWrite(EN_A,velocidade);  
//cont = ++cont;
//delay(1000);
//}
//}
  
//CONTROLE DOS MOTORES A PARTIR DO DADO RECEBIDO NO BLUETOOTH
switch(state)
{
//PARA O MOTOR SE ESTÁ CHEGANDO 0
case 0: 
digitalWrite(IN2, LOW);
digitalWrite(IN1, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
break;

//AVANÇA PARA FRENTE O MOTOR SE ESTÁ CHEGANDO 1
case 1:
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
analogWrite(EN_B, velocidade);
digitalWrite(IN2, HIGH);
digitalWrite(IN1, LOW);
analogWrite(EN_A,velocidade);  
break;

//AVANÇA PARA TRÁS O MOTOR SE ESTÁ CHEGANDO 2
case 2:
digitalWrite(IN2, LOW);
digitalWrite(IN1, HIGH);
analogWrite(EN_A, velocidade);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
analogWrite(EN_B, velocidade);
break;

//GIRA PARA UM LADO O MOTOR SE ESTÁ CHEGANDO 3
case 3:
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
analogWrite(EN_A, velocidade);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
analogWrite(EN_B, velocidade);
break;
  
//GIRA PARA OUTRO LADO O MOTOR SE ESTÁ CHEGANDO 3
case 4:
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
analogWrite(EN_B, velocidade);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
analogWrite(EN_A, velocidade);
break;
}

}

Please, don’t mind the Portuguese comments, and we know that using those while loops is probably not the best idea, but these are working for some short span of time before the bug appears, so we would like to make it fully work before optimizing this part. We tried to remove the safety routines and keeping only the Wire part in void loop() but the bug persisted, so that’s not the reason.

Any clues on how to solve this? Thanks!

Does the code posted actually have the problem? The description of what you tried is not clear and the commented out code adds to the confusion.

Software Serial probably will not work reliably at 38400 Baud.

jremington:
Does the code posted actually have the problem? The description of what you tried is not clear and the commented out code adds to the confusion.

Software Serial probably will not work reliably at 38400 Baud.

Yes it has, whenever the commented part is added to the code the problem happens.

More precisely, adding the following block in void loop() is enough to get the problem:

//Wire.beginTransmission(MPU_ADDR);
//Wire.write(0x3B);
//Wire.endTransmission(false);
//Wire.requestFrom(MPU_ADDR, 7*2, true);

Software Serial Baud is related to "Serial.begin(38400)", right? At first we tried 9600 and that didn't work so we changed to 38400 since that's the HC05 baud but it didn't work either.

You have to match the software serial Baud rate to the HC-05 Baud rate (HC-05 default is 9600 Baud), for anything to work. Software Serial is known NOT to work well above about 19200 Baud, and is the worst of the various possibilities.

Summary of options here.

jremington:
You have to match the software serial Baud rate to the HC-05 Baud rate (HC-05 default is 9600 Baud), for anything to work. Software Serial is known NOT to work well above about 19200 Baud, and is the worst of the various possibilities.

Summary of options here.

Thanks for the link. I see that SoftwareSerial is not a very good option and we will try changing both bauds back to 9600.

I don't see any conflict in the operation of the following setup -- MPU6050 + UNO + HC-05 + Android Phone.

hc5-1x.png

Sketch:

#include <MPU6050.h>
MPU6050 mpu;   //device address 0x68 keyed in the library
#include <SoftwareSerial.h>
SoftwareSerial BTserial(10, 11); // SRX, STX

void setup()
{
  Serial.begin(9600);
  BTserial.begin(9600);
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);

  Serial.println("Initialize MPU6050");
  while (!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
  {
    Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
    delay(1000);
  }
}

void loop()
{
  byte n = BTserial.available();
  if (n != 0)
  {
    char x = BTserial.read();
    if ( x == '1')
    {
      digitalWrite(13, HIGH);  //relay is ON
    }
    else
    {
      if (x == '2')
      {
        digitalWrite(13, LOW);  //relay is ON
      }
    }
  }
  mpuTemp();
}

void mpuTemp()
{
  float temp = mpu.readTemperature();
  BTserial.print("Temp = ");  //temperature is printed on the screen of Android phone.
  BTserial.print(temp, 2);
  BTserial.println(" *C");
  //-------------------------
  delay(1000);
}

hc5-1x.png

GolamMostafa:
I don't see any conflict in the operation of the following setup -- MPU6050 + UNO + HC-05 + Android Phone.

hc5-1x.png

Sketch:

#include <MPU6050.h>

MPU6050 mpu;  //device address 0x68 keyed in the library
#include <SoftwareSerial.h>
SoftwareSerial BTserial(10, 11); // SRX, STX

void setup()
{
  Serial.begin(9600);
  BTserial.begin(9600);
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);

Serial.println("Initialize MPU6050");
  while (!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
  {
    Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
    delay(1000);
  }
}

void loop()
{
  byte n = BTserial.available();
  if (n != 0)
  {
    char x = BTserial.read();
    if ( x == '1')
    {
      digitalWrite(13, HIGH);  //relay is ON
    }
    else
    {
      if (x == '2')
      {
        digitalWrite(13, LOW);  //relay is ON
      }
    }
  }
  mpuTemp();
}

void mpuTemp()
{
  float temp = mpu.readTemperature();
  BTserial.print("Temp = ");  //temperature is printed on the screen of Android phone.
  BTserial.print(temp, 2);
  BTserial.println(" *C");
  //-------------------------
  delay(1000);
}

I see. You used external functions and a MPU library. That's something we didn't try.

Would it bother you if I asked for this specific library? We've had some trouble dealing with library problems and since that one worked for you it would be suitable to try that one specifically.

Thanks!

Toltchok:
Would it bother you if I asked for this specific library? We’ve had some trouble dealing with library problems and since that one worked for you it would be suitable to try that one specifically

The zip version of the library is attached or you can download it from Github

Arduino-MPU6050-master.zip (27.7 KB)