1
\$\begingroup\$

I am working with a NUCLEO-F401RE board and I want to connect the accelerometer sensor MPU6050 (on a GY-521 module). The device can be connected to the board over I2C.

I connected the 3.3V of the board to VCC, GND to GND, SDA to PB9 and SCL to PB8.

I also tried to connect pull up resistor (10k) between VCC and SDA and VCC & SCL.

With the code below, I am trying to see if the device is connected however, the code desperately returns HAL_ERROR status code 1.

More specifically, this line HAL_I2C_IsDeviceReady(&hi2c1, MPU6050_ADDR, 10, i2c_timeout) return the code 1 that corresponds to HAL_StatusTypeDef HAL_ERROR

I did try with 3 different devices and all behave the same way.

When I try to read WHO_AM_I_REG (register 0x75) I am getting 0.

What am I doing wrong ?

    #include "stm32f4xx_hal.h"
    #include "uart.h"
    #include <stdio.h>
    
    #define SMPLRT_DIV_REG 0x19
    #define GYRO_CONFIG_REG 0x1B
    #define ACCEL_CONFIG_REG 0x1C
    #define ACCEL_XOUT_H_REG 0x3B
    #define TEMP_OUT_H_REG 0x41
    #define GYRO_XOUT_H_REG 0x43
    #define PWR_MGMT_1_REG 0x6B
    #define WHO_AM_I_REG 0x75
    
    I2C_HandleTypeDef hi2c1;
    
    void i2c1_init(void);
    void MPU6050_Init(void);
    
    // Setup MPU6050
    #define MPU6050_ADDR (0x68 << 1) // 0xD0
    const uint16_t i2c_timeout = 100;
    
    int main() {
    
        HAL_Init();
    
        i2c1_init();
        uart_init();
    
        MPU6050_Init();
    
        while (1) {
    
        }
    }
    
    void i2c1_init(void) {
        /*
         * PB8 --> I2C1_SCL
         * PB9 --> I2C1_SDA
         */
        GPIO_InitTypeDef GPIO_InitStruct;
    
        __HAL_RCC_GPIOB_CLK_ENABLE();
        GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; // alternate function - open drain
        GPIO_InitStruct.Pull = GPIO_PULLUP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
    
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    
    // Remap I2C1 pins
    //__HAL_RCC_AFIO_CLK_ENABLE();
    //__HAL_AFIO_REMAP_I2C1_ENABLE();
    
        // Configure I2C
        __HAL_RCC_I2C1_CLK_ENABLE();
    
        __HAL_RCC_I2C1_FORCE_RESET();
        HAL_Delay(2);
        __HAL_RCC_I2C1_RELEASE_RESET();
    
        hi2c1.Instance = I2C1;
        hi2c1.Init.ClockSpeed = 100000;
        hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; // half-high, half low
        hi2c1.Init.OwnAddress1 = 0;
        hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
        hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
        hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
        hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
    
        if (HAL_I2C_Init(&hi2c1) != HAL_OK) {
            printf("Error setting up the I2C !\n");
        }
    }
    
    void MPU6050_Init(void) {
    
        uint8_t check, Data;
        HAL_StatusTypeDef status = HAL_I2C_IsDeviceReady(&hi2c1, MPU6050_ADDR, 10,
                i2c_timeout);
        if (status != HAL_OK) {
            printf("Is Ready: %d \n", status);
        }
    
    // check device ID WHO_AM_I
        HAL_I2C_Mem_Read(&hi2c1, MPU6050_ADDR, WHO_AM_I_REG, 1, &check, 1, 1000);
        if (check == 104) // 0x68 will be returned by the sensor if everything goes well
                {
    // power management register 0X6B we should write all 0's to wake the sensor up
            Data = 0;
            HAL_I2C_Mem_Write(&hi2c1, MPU6050_ADDR, PWR_MGMT_1_REG, 1, &Data, 1,
                    i2c_timeout);
    // Set DATA RATE of 1KHz by writing SMPLRT_DIV register
            Data = 0x07;
            HAL_I2C_Mem_Write(&hi2c1, MPU6050_ADDR, SMPLRT_DIV_REG, 1, &Data, 1,
                    i2c_timeout);
    // 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,
                    i2c_timeout);
    // Set Guroscopic 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,
                    i2c_timeout);
    
        }
    }
    
    void SysTick_Handler(void) {
        HAL_IncTick();
    }

enter image description here

enter image description here

\$\endgroup\$
13
  • \$\begingroup\$ Where exactly it blocks, and what does it mean HAL status code=1? \$\endgroup\$ Dec 20, 2021 at 7:35
  • \$\begingroup\$ OK. What does HAL error code 1 means then? What do the I2C function return as their value and why are you not using the return value to determine what went wrong? Have you debugged the code on any way, have you looked the bus with an oscilloscope or logic analyzer? \$\endgroup\$
    – Justme
    Dec 20, 2021 at 7:35
  • \$\begingroup\$ Yes I did try to debug the sensor using a logic analyzer, I can indeed read the register 0x75 and see the value. I also explained a bit more the error code 1 in the initial question \$\endgroup\$
    – Michael
    Dec 20, 2021 at 7:39
  • \$\begingroup\$ GPIO_SPEED_FREQ_VERY_HIGH setting, probably is not compatible with I2C. Internal pull-ups usually are not sufficient, for I2C, you do need external ones. \$\endgroup\$ Dec 20, 2021 at 7:45
  • \$\begingroup\$ So did you single step code to see why and where it returns error code 1? If it can read the register value but deviceready indicates an an error, are you sure the chip can handle the protocol used by deviceready to determine if a device is ready or not? \$\endgroup\$
    – Justme
    Dec 20, 2021 at 7:46

1 Answer 1

1
\$\begingroup\$

You are using the wrong pins on the Nucleo.

You have connected to PC8 and PC6, not to PB8 and PB9.

\$\endgroup\$
3
  • \$\begingroup\$ How did I missed that ! many thanks !!! \$\endgroup\$
    – Michael
    Dec 20, 2021 at 9:51
  • \$\begingroup\$ I added the pin-out from the user manual to help future self :-) \$\endgroup\$
    – Michael
    Dec 20, 2021 at 9:52
  • \$\begingroup\$ Obviously I don't need the pull-up anymore and the 3.3 is working fine, thanks! \$\endgroup\$
    – Michael
    Dec 20, 2021 at 9:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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