Skip to main content
Graduate
September 26, 2024
Question

The I2C Protocol Being Very Problematic on STM32

  • September 26, 2024
  • 7 replies
  • 5917 views

Hello Sir,

I’ve been dealing with an I2C protocol error for a long time, but unfortunately, neither the solutions online nor the suggestions here have been successful. I've changed sensors multiple times and tried different methods, but the problem remains the same. I’m using the STM32F413ZH board, and in my current tests, I’m using the QMC5883L model for I2C. The pull-up resistors are connected correctly. I even tried soldering the connections to improve them. I also attempted to supply power externally and change the cables, but the issue still wasn’t resolved.

 

I used a logic analyzer to monitor the bus, and either the signal gets stuck as shown below, or it works chaotically in a meaningless way. For example, SCL often stays high, while SDA changes continuously, or SDA stops entirely at certain points and then continues later. I've seen many variations like this, but it rarely works correctly. I mostly get error codes like 32, 36, and 544.(So it comes as 32 + 512, and in the HAL definitions, 512 is defined as an error of incorrect initialization. To be honest, I have no idea why I’m receiving 512.) I’ve tried the solution involving 9 clock toggles, as many people suggested, but that didn’t help either. I suspected the issue was with the STM32, so I tried it with an Arduino, but although it worked, it stopped after 30-40 seconds. Whatever I do, I’ve never been able to achieve stable operation.

 

There have been rare instances where the STM32 managed to make a single read, but it would then break again as I described. However, this happened very infrequently. At this point, I’m really starting to think that STM32 engineers have failed in handling this issue effectively.

 

I will now provide a few examples from the logic analyzer, the current code I'm testing, the values read, and the products I'm using.

 

I would like to thank in advance everyone who takes the time out of their valuable schedule to assist me with this issue.

 

Signals captured within very short time intervals:

Ekran görüntüsü 2024-09-27 004636.pngEkran görüntüsü 2024-09-27 004703.png

Ekran görüntüsü 2024-09-27 005341.png

 

Values read from STM Studio at short time intervals:

Ekran görüntüsü 2024-09-27 004756.pngEkran görüntüsü 2024-09-27 005830.png

 

Configuration settings:

Ekran görüntüsü 2024-09-27 010317.pngEkran görüntüsü 2024-09-27 010334.png

 

Code:

 

 

#include "main.h"

#define qmc_address (0x0D << 1)

I2C_HandleTypeDef hi2c1;

UART_HandleTypeDef huart3;

PCD_HandleTypeDef hpcd_USB_OTG_FS;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART3_UART_Init(void);
static void MX_USB_OTG_FS_PCD_Init(void);
static void MX_I2C1_Init(void);

uint8_t read_register[6];
uint8_t write_register[2] = {0x01, 0x1D};

void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c){
	GenerateNineClockPulses();
}

int main(void)
{
 HAL_Init();

 SystemClock_Config();

 MX_GPIO_Init();
 MX_USART3_UART_Init();
 MX_USB_OTG_FS_PCD_Init();
 MX_I2C1_Init();

 GenerateNineClockPulses();
 HAL_I2C_Mem_Write(&hi2c1, qmc_address, 0x0B, 1, &write_register[0], 1, 50);
 HAL_Delay(1);
 HAL_I2C_Mem_Write(&hi2c1, qmc_address, 0x09, 1, &write_register[1], 1, 50);
 HAL_Delay(1);

 while (1)
 {
	 HAL_I2C_Mem_Read(&hi2c1, qmc_address, 0x00, 1, &read_register[0], 1, 50);
	 HAL_Delay(1);
	 HAL_I2C_Mem_Read(&hi2c1, qmc_address, 0x01, 1, &read_register[1], 1, 50);
	 HAL_Delay(1);
	 HAL_I2C_Mem_Read(&hi2c1, qmc_address, 0x02, 1, &read_register[2], 1, 50);
	 HAL_Delay(1);
	 HAL_I2C_Mem_Read(&hi2c1, qmc_address, 0x03, 1, &read_register[3], 1, 50);
	 HAL_Delay(1);
	 HAL_I2C_Mem_Read(&hi2c1, qmc_address, 0x04, 1, &read_register[4], 1, 50);
	 HAL_Delay(1);
	 HAL_I2C_Mem_Read(&hi2c1, qmc_address, 0x05, 1, &read_register[5], 1, 50);
	 HAL_Delay(1);
 }
}

void SystemClock_Config(void)
{
 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 __HAL_RCC_PWR_CLK_ENABLE();
 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
 RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
 RCC_OscInitStruct.PLL.PLLM = 8;
 RCC_OscInitStruct.PLL.PLLN = 384;
 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
 RCC_OscInitStruct.PLL.PLLQ = 8;
 RCC_OscInitStruct.PLL.PLLR = 2;
 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
 {
 Error_Handler();
 }

 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
 |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
 {
 Error_Handler();
 }
}
static void MX_I2C1_Init(void)
{
 hi2c1.Instance = I2C1;
 hi2c1.Init.ClockSpeed = 100000;
 hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
 hi2c1.Init.OwnAddress1 = 0;
 hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
 hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
 hi2c1.Init.OwnAddress2 = 0;
 hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
 hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
 if (HAL_I2C_Init(&hi2c1) != HAL_OK)
 {
 Error_Handler();
 }
}

static void MX_USART3_UART_Init(void)
{
 huart3.Instance = USART3;
 huart3.Init.BaudRate = 115200;
 huart3.Init.WordLength = UART_WORDLENGTH_8B;
 huart3.Init.StopBits = UART_STOPBITS_1;
 huart3.Init.Parity = UART_PARITY_NONE;
 huart3.Init.Mode = UART_MODE_TX_RX;
 huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 huart3.Init.OverSampling = UART_OVERSAMPLING_16;
 if (HAL_UART_Init(&huart3) != HAL_OK)
 {
 Error_Handler();
 }
}

static void MX_USB_OTG_FS_PCD_Init(void)
{
 hpcd_USB_OTG_FS.Instance = USB_OTG_FS;
 hpcd_USB_OTG_FS.Init.dev_endpoints = 6;
 hpcd_USB_OTG_FS.Init.speed = PCD_SPEED_FULL;
 hpcd_USB_OTG_FS.Init.dma_enable = DISABLE;
 hpcd_USB_OTG_FS.Init.phy_itface = PCD_PHY_EMBEDDED;
 hpcd_USB_OTG_FS.Init.Sof_enable = ENABLE;
 hpcd_USB_OTG_FS.Init.low_power_enable = DISABLE;
 hpcd_USB_OTG_FS.Init.lpm_enable = DISABLE;
 hpcd_USB_OTG_FS.Init.battery_charging_enable = ENABLE;
 hpcd_USB_OTG_FS.Init.vbus_sensing_enable = ENABLE;
 hpcd_USB_OTG_FS.Init.use_dedicated_ep1 = DISABLE;
 if (HAL_PCD_Init(&hpcd_USB_OTG_FS) != HAL_OK)
 {
 Error_Handler();
 }
}

static void MX_GPIO_Init(void)
{
 GPIO_InitTypeDef GPIO_InitStruct = {0};

 __HAL_RCC_GPIOC_CLK_ENABLE();
 __HAL_RCC_GPIOH_CLK_ENABLE();
 __HAL_RCC_GPIOB_CLK_ENABLE();
 __HAL_RCC_GPIOD_CLK_ENABLE();
 __HAL_RCC_GPIOG_CLK_ENABLE();
 __HAL_RCC_GPIOA_CLK_ENABLE();

 HAL_GPIO_WritePin(GPIOB, LD1_Pin|LD3_Pin|LD2_Pin, GPIO_PIN_RESET);

 HAL_GPIO_WritePin(USB_PowerSwitchOn_GPIO_Port, USB_PowerSwitchOn_Pin, GPIO_PIN_RESET);

 GPIO_InitStruct.Pin = USER_Btn_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(USER_Btn_GPIO_Port, &GPIO_InitStruct);

 GPIO_InitStruct.Pin = LD1_Pin|LD3_Pin|LD2_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

 GPIO_InitStruct.Pin = USB_PowerSwitchOn_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(USB_PowerSwitchOn_GPIO_Port, &GPIO_InitStruct);

 GPIO_InitStruct.Pin = USB_OverCurrent_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(USB_OverCurrent_GPIO_Port, &GPIO_InitStruct);
}

void GenerateNineClockPulses(void) {
 GPIO_InitTypeDef GPIO_InitStruct = {0};

 HAL_I2C_DeInit(&hi2c1);

 GPIO_InitStruct.Pin = GPIO_PIN_6;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
 GPIO_InitStruct.Pull = GPIO_PULLUP;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);

 for (int i = 0; i < 9; i++) {
 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
 HAL_Delay(1);

 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
 HAL_Delay(1);
 }

 HAL_I2C_Init(&hi2c1);
}
void Error_Handler(void)
{
 __disable_irq();
 while (1)
 {
 }
}

#ifdef USE_FULL_ASSERT

void assert_failed(uint8_t *file, uint32_t line)
{
 ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
}
#endif /* USE_FULL_ASSERT */

 

 

 

Board: STM32F413ZH

Sensor: QMC5883L or MPU6050

    This topic has been closed for replies.

    7 replies

    Super User
    September 26, 2024

    Related:

    Always SCL High, SDA Low In I2C - STMicroelectronics Community

     

    Can't solve hardware problems with software, at least not most of the time. Based on your plots and your description of the issue, it doesn't look like a software problem. SDA and SCL should be idle high after power on. If they're not, it is a hardware issue.

    Graduate
    September 27, 2024

    In my current test, I believe you're right. Even when I don't write any code to operate the line, the SDA line is being pulled low.

    Super User
    September 27, 2024

    Doing an analog capture on SDA/SCL lines might be useful here. Even with it toggling randomly, you should see a slow rising edge and a fast falling edge as expected with an open-drain output. If they are both fast, something on there is misbehaving.

    Still think the resistance test with a multimeter would be a good idea.

    Could remove the external I2C slave chips to see if problem goes away. If I was stuck, that's what I would do to confirm the hardware issue.

    Graduate II
    September 27, 2024

    >> I’ve been dealing with an I2C protocol error for a long time ...

    Then it's time to throw out the HAL I2C drivers and write your own.

    I cannot imagine that there is a hardware fault in an F4 peripheral. Or have you checked chip errata sheet?

    Graduate II
    September 27, 2024

    Let's make sure the QMC5883L is not the cause of the SCL/SDA lines staying mostly low.

    First comment out your read/write routines and see if the SCL/SDA lines stay high.

    If they either line go low, remove the QMC5883L and still comment out the I2C Mem read/write.

    Be sure the pull-up resistors are still connected to the STM32.

    Then run again to see if the SCL and SDA line stays high?  

     

    You can also connect two I2C ports together and test in loopback. 

    Graduate
    September 27, 2024

    @TDK @LCE @Karl Yamashita 

    Thank you all very much for your valuable comments. While trying out the things you suggested, I discovered something. Indeed, when I load an empty code, the line is pulled high as it should be, but if I use HAL's MX_I2C1_Init(); function, strange signals appear as shown below. What could be the reason for this?

     

    #include "main.h"
    
    #define qmc_address (0x0D << 1)
    
    I2C_HandleTypeDef hi2c1;
    
    UART_HandleTypeDef huart3;
    
    PCD_HandleTypeDef hpcd_USB_OTG_FS;
    
    void SystemClock_Config(void);
    static void MX_GPIO_Init(void);
    static void MX_USART3_UART_Init(void);
    static void MX_USB_OTG_FS_PCD_Init(void);
    static void MX_I2C1_Init(void);
    
    uint8_t read_register[6];
    uint8_t write_register[2] = {0x01, 0x1D};
    
    void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c){
    	GenerateNineClockPulses();
    }
    
    int main(void)
    {
     HAL_Init();
    
     SystemClock_Config();
    
     MX_GPIO_Init();
     MX_USART3_UART_Init();
     MX_USB_OTG_FS_PCD_Init();
     MX_I2C1_Init(); //This!
    
     while (1)
     {
     //
     }
    }
    
    void SystemClock_Config(void)
    {
     RCC_OscInitTypeDef RCC_OscInitStruct = {0};
     RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
    
     __HAL_RCC_PWR_CLK_ENABLE();
     __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
    
     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
     RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
     RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
     RCC_OscInitStruct.PLL.PLLM = 8;
     RCC_OscInitStruct.PLL.PLLN = 384;
     RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
     RCC_OscInitStruct.PLL.PLLQ = 8;
     RCC_OscInitStruct.PLL.PLLR = 2;
     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
     {
     Error_Handler();
     }
    
     RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
     |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
     RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
     RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
     RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
     RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    
     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
     {
     Error_Handler();
     }
    }
    static void MX_I2C1_Init(void)
    {
     hi2c1.Instance = I2C1;
     hi2c1.Init.ClockSpeed = 100000;
     hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
     hi2c1.Init.OwnAddress1 = 0;
     hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
     hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
     hi2c1.Init.OwnAddress2 = 0;
     hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
     hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
     if (HAL_I2C_Init(&hi2c1) != HAL_OK)
     {
     Error_Handler();
     }
    }
    
    static void MX_USART3_UART_Init(void)
    {
     huart3.Instance = USART3;
     huart3.Init.BaudRate = 115200;
     huart3.Init.WordLength = UART_WORDLENGTH_8B;
     huart3.Init.StopBits = UART_STOPBITS_1;
     huart3.Init.Parity = UART_PARITY_NONE;
     huart3.Init.Mode = UART_MODE_TX_RX;
     huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
     huart3.Init.OverSampling = UART_OVERSAMPLING_16;
     if (HAL_UART_Init(&huart3) != HAL_OK)
     {
     Error_Handler();
     }
    }
    
    static void MX_USB_OTG_FS_PCD_Init(void)
    {
     hpcd_USB_OTG_FS.Instance = USB_OTG_FS;
     hpcd_USB_OTG_FS.Init.dev_endpoints = 6;
     hpcd_USB_OTG_FS.Init.speed = PCD_SPEED_FULL;
     hpcd_USB_OTG_FS.Init.dma_enable = DISABLE;
     hpcd_USB_OTG_FS.Init.phy_itface = PCD_PHY_EMBEDDED;
     hpcd_USB_OTG_FS.Init.Sof_enable = ENABLE;
     hpcd_USB_OTG_FS.Init.low_power_enable = DISABLE;
     hpcd_USB_OTG_FS.Init.lpm_enable = DISABLE;
     hpcd_USB_OTG_FS.Init.battery_charging_enable = ENABLE;
     hpcd_USB_OTG_FS.Init.vbus_sensing_enable = ENABLE;
     hpcd_USB_OTG_FS.Init.use_dedicated_ep1 = DISABLE;
     if (HAL_PCD_Init(&hpcd_USB_OTG_FS) != HAL_OK)
     {
     Error_Handler();
     }
    }
    
    static void MX_GPIO_Init(void)
    {
     GPIO_InitTypeDef GPIO_InitStruct = {0};
    
     __HAL_RCC_GPIOC_CLK_ENABLE();
     __HAL_RCC_GPIOH_CLK_ENABLE();
     __HAL_RCC_GPIOB_CLK_ENABLE();
     __HAL_RCC_GPIOD_CLK_ENABLE();
     __HAL_RCC_GPIOG_CLK_ENABLE();
     __HAL_RCC_GPIOA_CLK_ENABLE();
    
     HAL_GPIO_WritePin(GPIOB, LD1_Pin|LD3_Pin|LD2_Pin, GPIO_PIN_RESET);
    
     HAL_GPIO_WritePin(USB_PowerSwitchOn_GPIO_Port, USB_PowerSwitchOn_Pin, GPIO_PIN_RESET);
    
     GPIO_InitStruct.Pin = USER_Btn_Pin;
     GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     HAL_GPIO_Init(USER_Btn_GPIO_Port, &GPIO_InitStruct);
    
     GPIO_InitStruct.Pin = LD1_Pin|LD3_Pin|LD2_Pin;
     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    
     GPIO_InitStruct.Pin = USB_PowerSwitchOn_Pin;
     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
     HAL_GPIO_Init(USB_PowerSwitchOn_GPIO_Port, &GPIO_InitStruct);
    
     GPIO_InitStruct.Pin = USB_OverCurrent_Pin;
     GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     HAL_GPIO_Init(USB_OverCurrent_GPIO_Port, &GPIO_InitStruct);
    }
    
    void GenerateNineClockPulses(void) {
     GPIO_InitTypeDef GPIO_InitStruct = {0};
    
     HAL_I2C_DeInit(&hi2c1);
    
     GPIO_InitStruct.Pin = GPIO_PIN_6;
     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
     GPIO_InitStruct.Pull = GPIO_PULLUP;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    
     HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
    
     for (int i = 0; i < 9; i++) {
     HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
     HAL_Delay(1);
    
     HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
     HAL_Delay(1);
     }
    
     HAL_I2C_Init(&hi2c1);
    }
    void Error_Handler(void)
    {
     __disable_irq();
     while (1)
     {
     }
    }
    
    #ifdef USE_FULL_ASSERT
    
    void assert_failed(uint8_t *file, uint32_t line)
    {
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    }
    #endif /* USE_FULL_ASSERT */

     

    Ekran görüntüsü 2024-09-27 145220.png

    I’m receiving signals like this and similar ones, which make no sense, and moreover, the SCL line remains high as it should.

    Thank you.

    Graduate II
    September 27, 2024

    In your latest screen shot, is the QMC5883L connected? 

    Super User
    September 27, 2024

    @AlexanderKibarov wrote:

    I used a logic analyzer to monitor the bus


    Have you tried with an oscilloscope?

    This could show up things in the analogue domain that a logic analyser's digital view may hide ...

     


    @AlexanderKibarov wrote:

    The pull-up resistors are connected correctly


    What value are they?

    Graduate
    September 27, 2024

    Hey Andrew, Thank you for your answer

    Resistor value is 2.2K. Is it enough in your opinion?

    Super User
    September 27, 2024

    @AlexanderKibarov wrote:

    Resistor value is 2.2K. Is it enough in your opinion?


    Probably.

    The way to check is to look at the waveforms with an oscilloscope.

    See this post: 

    https://electronics.stackexchange.com/questions/1849/is-there-a-correct-resistance-value-for-i2c-pull-up-resistors/473799#473799

    It contains this diagram - which shows you the effect of the pullup value:

    AndrewNeil_1-1727445971014.png

    https://community.st.com/t5/stm32-mcus-products/stm32f072v8t6-capacitance-and-rise-time-of-for-i2c/m-p/634079/highlight/true#M234042

    #I2CPullupValue #PullupValue

    Graduate
    September 27, 2024

    @Karl Yamashita @Andrew Neil @TDK @LCE 

    Thank you once again for your valuable responses.

     

    I am now certain that the problem is caused by the QMC sensor. In my tests, I successfully established I2C communication between Arduino-Arduino and STM32-Arduino, and the communication was flawless. As you mentioned, when I checked the resistors on the QMC, I saw that one was 2.2k and the other 0.3k. I then replaced it with a new QMC that had the correct resistors, but there was still an issue. (In fact, strangely, the device overheated and started smoking. This had happened to me before.) The connections were as follows:

    * VCC-5V

    * GND-GND

    * SCL-SCL

    * SDA-SDA

    Although the overheating issue had occurred before, I still don't understand the reason behind it. As I initially mentioned, communication between Arduino-Arduino and STM32-Arduino was flawless, but sometimes the situation depicted in the image below occurred. Frankly, these are not major issues since they do not disrupt communication, and maybe these issues are due to the logic analyzer I used and its speed. Do you think such errors are normal?

     

    Under normal conditions, the STM32 sends data 0x80 to the Arduino. The Arduino's address is 0x37.

     

    Ekran görüntüsü 2024-09-27 231907.pngEkran görüntüsü 2024-09-27 232422.pngEkran görüntüsü 2024-09-27 232552.pngEkran görüntüsü 2024-09-27 232818.pngEkran görüntüsü 2024-09-27 235018.png

    Super User
    September 28, 2024

    @AlexanderKibarov wrote:

    the overheating issue had occurred before,


    That's worrying !

    Potentially could have damaged the STM32 also?

    Graduate
    September 28, 2024

    Thank you Andrew for you answer. 

    According to my experience, the stm works properly. I did not see any errors regarding its operation. As I already said, while the qmc and i2c communication failed on cards such as arduino stm32, it was successful when the cards communicated with each other.

    Visitor II
    October 28, 2024

    /////This is a code written in Arduino for i2c communication between stm32f1036t6 and esp8266


    //#include <Wire.h>
    //#include <Wire_slave.h>
    #define I2C_MASTERSLAVE 1 // 1이면 마스터, 0이면 슬레이브
    #define SLAVE_ADDRESS 0x08
    #if I2C_MASTERSLAVE == 1 // 마스터
    #include <Wire.h>
    #endif

    #if I2C_MASTERSLAVE == 0 // 슬레이브 모드일 때 사용
    #include <Wire_slave.h>

    void requestEvent();
    void receiveEvent(int numBytes);
    String receivedData = "";
    bool stringComplete = false;
    #endif
    void setup(){
    Wire.begin(SLAVE_ADDRESS); // join i2c bus with address #4
    Serial.begin(9600);
    // start serial for output
    #if I2C_MASTERSLAVE == 0 // 슬레이브 모드일 때 사용
    Wire.onReceive(receiveEvent); // register event
    Wire.onRequest(requestEvent); // 요청 이벤트 등록
    receivedData.reserve(200);
    #endif
    }

    void loop(){
    #if I2C_MASTERSLAVE == 1
    Wire.beginTransmission(SLAVE_ADDRESS);

    Wire.setClock(40000L); // Set speed at 40kHz
    Wire.write("1234567890abcd\n");//종료문자추가
    Wire.endTransmission();

    Serial.println("Sent data to STM32"); // 전송한 데이터 시리얼로 출력
    delay(3000); // 1초 대기
    #endif
    }

    #if I2C_MASTERSLAVE == 0
    void receiveEvent(int howMany){

     

    while(Wire.available()){ // loop through all but the last

    char c = (char)Wire.read(); // receive byte as a character
    receivedData += c;
    //Serial.print(c);
    if(c=='\n'){
    stringComplete = true;
    }
    if (stringComplete) {
    Serial.println(receivedData);
    // clear the string:
    receivedData = "";
    stringComplete = false;
        }
      }

    }

    void requestEvent() {
    }
    #endif