0
\$\begingroup\$

TL, DR: I experience communication breaks while using GY-521(MPU6050 based) with STM32F4 in I2C communication. And looking for the result of these breaks.

Also should I give a 5V Vcc or 3V Vcc to GY-521? Does it matter or not? (Just another small question)

I am using GY-521, its schematic can be found here.

I use it with my STM32F4-DISC board, and only connections that I am doing are,

Vcc -> 3V GND -> GND SCL -> SCL SDA -> SDA

Where the left ones are the pins of GY-521 and others are STM32 pins.

The configurations about STM32 is probably fine because I can get values when it works.

Now, the question is if there happen any disconnections,i.e a jumper is unplugged for example, (scl,sda, Vcc,gnd does not matter), then the communication gets canceled and replugging that connection does not start it again. I am watching the communication by STMStudio(simultaneous variable tracker program) by the way.

So few guesses of mine, I am initiating the sensor by calling this function in main before while(1);

void MPU6050_Init() {

uint8_t Data = 0 ;
uint8_t check = 99;

HAL_I2C_Mem_Read(&hi2c1, MPU6050_ADDR, WHO_AM_I_REG, 1, &check, 1, 1000);

if(check == 0x68) {
    Data = 0 ;
    HAL_I2C_Mem_Write(&hi2c1, MPU6050_ADDR , PWR_MGMT_1_REG, 1, &Data, 1, 1000);

    Data=0x07;
    HAL_I2C_Mem_Write(&hi2c1, MPU6050_ADDR , SMPLRT_DIV_REG, 1, &Data, 1, 1000);

    // Set accelerometer configuration in ACCEL_CONFIG Register
        // XA_ST=0,YA_ST=0,ZA_ST=0, FS_SEL=0 -> ± 2g
        Data = 0x00;
        HAL_I2C_Mem_Write(&hi2c1, MPU6050_ADDR, ACCEL_CONFIG_REG, 1, &Data, 1, 1000);

        // Set Gyroscopic configuration in GYRO_CONFIG Register
        // XG_ST=0,YG_ST=0,ZG_ST=0, FS_SEL=0 -> ± 250 °/s
        Data = 0x00;
        HAL_I2C_Mem_Write(&hi2c1, MPU6050_ADDR, GYRO_CONFIG_REG, 1, &Data, 1, 1000);
}

}

So one of my guesses is the mpu6050 resets itself when VCC or GND is disconnected because it loses its power. So I have to reset the MCU to initialize the sensor again. However, some observations conflict with this idea.

  1. Reset does not solve the issue.
  2. Without GND connected, there is still power on the GY-521 so the LED on it(I assume power LED) still shines but not as bright as GND connected. (And this is not happening always, sometimes the power goes down sometimes doesn't. This issue by itself is another question of me you can answer)
  3. If it were a power lost/reset issue, then disconnecting SCL/SDA should not break the data communication, it should be continue when I replug those jumpers.

And sometimes even nothing is disconnected, if I press the reset button it breaks the communication, and sometimes it does not. ( For example, I don't touch any connections, just tap the reset button, it resets and communication works for 2 presses but in the 3rd it gets broken. (2 and 3 aren't certain values just for one trial)).

So, in short, I could not find a logical reasoning system so that I could ask when I do that this happens. It's like randomly happening.

Edit : I have added a power an LED command in the if block of this init function for debug purposes and observed that after the problematic resets, it actually does not enter the if and init the mpu6050. So may this be about poor cabling(breadboard, jumper instead of soldering) ?

I am attaching the code blocks relevant.

void MPU6050_Read_Accel (void)
{
    uint8_t Rec_Data[6];

    // Read 6 BYTES of data starting from ACCEL_XOUT_H register

    HAL_I2C_Mem_Read (&hi2c1, MPU6050_ADDR, ACCEL_XOUT_H_REG, 1, Rec_Data, 6, 1000);

    Accel_X_RAW = (int16_t)(Rec_Data[0] << 8 | Rec_Data [1]);
    Accel_Y_RAW = (int16_t)(Rec_Data[2] << 8 | Rec_Data [3]);
    Accel_Z_RAW = (int16_t)(Rec_Data[4] << 8 | Rec_Data [5]);

    /*** convert the RAW values into an acceleration in 'g'
         we have to divide according to the Full-scale value set in FS_SEL
         I have configured FS_SEL = 0. So I am dividing by 16384.0
         for more details check ACCEL_CONFIG Register              ****/

    Ax = Accel_X_RAW/16384.0;
    Ay = Accel_Y_RAW/16384.0;
    Az = Accel_Z_RAW/16384.0;
}


void MPU6050_Read_Gyro (void)
{
    uint8_t Rec_Data[6];

    // Read 6 BYTES of data starting from GYRO_XOUT_H register

    HAL_I2C_Mem_Read (&hi2c1, MPU6050_ADDR, GYRO_XOUT_H_REG, 1, Rec_Data, 6, 1000);

    Gyro_X_RAW = (int16_t)(Rec_Data[0] << 8 | Rec_Data [1]);
    Gyro_Y_RAW = (int16_t)(Rec_Data[2] << 8 | Rec_Data [3]);
    Gyro_Z_RAW = (int16_t)(Rec_Data[4] << 8 | Rec_Data [5]);

    /*** convert the RAW values into DPS (°/s)
         we have to divide according to the Full-scale value set in FS_SEL
         I have configured FS_SEL = 0. So I am dividing by 131.0
         for more details check GYRO_CONFIG Register              ****/

    Gx = Gyro_X_RAW/131.0;
    Gy = Gyro_Y_RAW/131.0;
    Gz = Gyro_Z_RAW/131.0;
}

The above are functions.

    MPU6050_Init();

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
    MX_USB_HOST_Process();

    /* USER CODE BEGIN 3 */
    MPU6050_Read_Accel();
    MPU6050_Read_Gyro();

  }
  /* USER CODE END 3 */
}

And this is the relevant part of the main.

Thanks in advance.

\$\endgroup\$
0
\$\begingroup\$

Well if your software is not handling communication errors, it won't work when you deliberately cause communication errors by unplugging wires randomly. At least you could check the return values if the I2C transactions are done correctly or not. Then decide what to do if it was succesful or not.

Also if you push the MCU reset button while data is transferred from sensor to MCU, the sensor does not know the MCU has been reset so it will wait for the MCU to continue data transfer. If sensor was transmitting a 0 bit on the data wire when MCU is reset, sensor is still keeping data wire low, and the MCU cannot start new transaction. It is again your responsibility to detect this situation and solve the problem by resetting the sensor somehow, perhaps with a i2c reset sequence or powering the sensor off for a while so that the bus is free again.

\$\endgroup\$
  • \$\begingroup\$ thanks for the answer, I will try to implement an error handling. So, do you have any idea about whether feeding the sensor's Vcc pin from 5V, 3V, or Vdd pins on the stm32 board makes a difference or not? \$\endgroup\$ – muyustan Jul 24 at 10:56
  • \$\begingroup\$ I tried to reset the sensor by writing to one of its registers when the return status of the writing/reading is not OK, but I guess writing is the problem itself. So I cannot achieve a reset by this. \$\endgroup\$ – muyustan Jul 24 at 11:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.