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!
