stm32duino / Arduino_Core_STM32

STM32 core support for Arduino
https://github.com/stm32duino/Arduino_Core_STM32/wiki
Other
2.81k stars 967 forks source link

STM32F103C8T6 i2c problem #991

Closed denizetkar closed 4 years ago

denizetkar commented 4 years ago

Please, before reporting any issue

When reporting any issue, please try to provide all relevant information:

Describe the bug On STM32F103C8T6 blue pill board, the Wire library cannot detect an MPU9250 slave device on any of the I2C ports (tried PB6-PB7, PB8-PB9 and PB10-PB11). The same i2c slave device is detected with an Arduino UNO at address 0x68.

To Reproduce

#include <Wire.h>

void setup() {
  Serial.begin(9600);
  while (!Serial);
  Wire.begin();
}

void loop() {
  byte error;
  Wire.beginTransmission(0x68);
  error = Wire.endTransmission();
  Serial.println(error);
  delay(1000);
}

Steps to reproduce the behavior:

  1. Flash a maple bootloader into the STM32F103C8T6,
  2. Plug the STM32F103C8T6 with "microusb to usb" cable to a computer,
  3. Make sure you can upload a blink code via "Maple DFU Bootloader 2.0" with the Arduino_Core_STM32 on Arduino IDE,
  4. Connect the GND and VCC of the MPU9250,
  5. Connect the AD0 of the MPU9250 to GND (so that the i2c address is 0x68),
  6. Connect the SCL pin to PB6 and the SDA to PB7 (default Wire pins),
  7. Upload the aforementioned sketch.

Expected behavior I would expect the Wire library to successfully recognize my MPU9250 slave device at address 0x68 and print "0" onto the Serial monitor every second.

Screenshots No screenshot necessary. The sketch prints "2" onto the Serial every second instead, which means I2C_NACK_ADDR.

Desktop (please complete the following information):

Board (please complete the following information):

Additional context It has been made sure that MPU9250 is a proper functioning I2C slave device with address 0x68 when AD0 is connected to the GND level by means of running an i2c scanner code on an Arduino UNO (it detects a device on 0x68).

fpistm commented 4 years ago

Hi, did you use pull up on each I2C line?

denizetkar commented 4 years ago

According to your suggestion, I added 12.5KOhm pull-up resistors to each SDA and SCL lines. However it is still printing "2" to the Serial monitor. Note that these resistors were absolutely unnecessary for an Arduino UNO to detect my MPU9250. Edit: I measured a resistance of around 10.5KOhm between the VCC and SDA as well as between the VCC and SCL pins of my MPU9250.

ABOSTM commented 4 years ago

Hi @denizetkar , I tested on my side my BluePill, with PB6 as I2C_SCL and PB7 as I2C_SDA . It works well. I don't have MPU9250, but at least scanning on other devices is working. Can you test the scanner example ? Also if you have the ability to put an oscilloscope/analyzer on I2C PB6/PB7 that could help.

denizetkar commented 4 years ago

Here is what I did to understand whether this problem is due to MPU9250 or not:

  1. I emptied the I2C bus line,
  2. Connected only my BMP280,
  3. Uploaded i2c_scanner sketch from examples and it found a device at address 0x76,
  4. Then I unplugged only SDA pin of the BMP280 then the scanner naturally could not find any device,
  5. Right after that I plugged the SDA pin back but the scanner still could not find any device.

Here is another experiment I did:

  1. Emptied the (default) I2C bus,
  2. Connected both my BMP280 and MPU6050,
  3. Uploaded the scanner sketch again and it found 2 devices at addresses 0x68, 0x76,
  4. Then I unplugged SDA pin of my MPU6050 then the scanner found only 1 device at address 0x76 (which is normal),
  5. But this time when I plugged the SDA pin back the scanner was able to find both devices at addresses 0x68, 0x76,
  6. Then I decided to unplug both SDA pins of MPU6050 and BMP280 and as expected the scanner could not find any devices,
  7. I plugged both of the SDA pins back and observed that the scanner were not able to find any i2c devices any more UNTIL I upload the sketch again.

In the last experiment I did:

  1. Emptied I2C bus,
  2. Connected BMP280 and MPU9250 to the bus,
  3. Uploaded the scanner sketch and it ONLY found a device at address 0x76 (the BMP).

Given these observations, the Wire library can obviously detect some other I2C hardware however it does not seem to be able to detect them consistently with respect to unexpected disconnections. I'm not sure what to conclude for MPU9250 though, as the Wire library could never detect it throughout my experiments. I unfortunately do not have access to an oscilloscope/analyzer which limits my options in debugging this problem. What would you suggest me to do at this point?

Thank you for your help and attention by the way :)

ABOSTM commented 4 years ago

Hi @denizetkar , First, I2C devices cannot be unplugged/plugged it is not design for that and you may leave I2C bus and I2C hardware in the MCU in invalid state. That say, there is something strange: in your 2nd experiment, the scanner discover both devices, but in the 3rd experiment, which looks the same, it only found one device. Could it be a connection issue ? Maybe more testing around that could be useful. but don't unplug devices. What I would suggest: keep both devices connected, and run several times the scanner to see if it reliably found both devices. Once you get reliable setup (both devices detected) then you can switch you your original sketch. Eventually in your original sketch add the scanning first to confirm that device is detected before going further.

denizetkar commented 4 years ago

The problem turned out to be due to relatively long cables that I used for SDA and SCL pins. Apparently 2 jumper cables are too much for STM32 i2c communication. The weird thing is it has no effect whatsoever on an Arduino UNO.

uzi18 commented 4 years ago

try to use 4k7 resistors, i2c line usualy have max 1m, but line extenders exists

ABOSTM commented 4 years ago

The problem turned out to be due to relatively long cables that I used for SDA and SCL pins. Apparently 2 jumper cables are too much for STM32 i2c communication. The weird thing is it has no effect whatsoever on an Arduino UNO.

Arduino Uno is 5V whereas STM32 is 3.3V which may explain the difference.

Vinod-2069 commented 3 years ago

Hello I am vinod Kumar, I amalso facing exactly the same issue and wasted three days in finding problems but i think it s the issue of arduino stm32 package issue because earlier i used same controller with same library and it is still working.

yashgulati0 commented 3 years ago

hello guys, Can anyone help me out, I am currently using STM32f103c8T6(Bluepill module) as a Arduino core, but when I am interfacing any I2C module with controller it will not recognized by controller. These are the modules(SPS30,BME680) which I have tried to interface on I2C port(PB7,PB6) but they are not detecting, the same I have tested with Arduino Uno, Arduino Mega both the modules are working fine on I2C port AVR controller.

Can any one let me know how to fix this issue.

fpistm commented 3 years ago

@yashgulati0 Pay attention that STM32 MCU is 3.3V while Arduino Uno 5V. You have to add Pull-up resistor on each I2C line (usually 4.7K)

chrisco484 commented 3 years ago

Apparently the Blue Pill I2C lines are 5V tolerant.

So, if running the SCL and SDA at 5V instead of 3.3V I would assume the larger voltage range would give higher noise immunity to the lines (does that make sense - SNR should be much better for a fixed noise level?)

Has anyone tried this?

I currently have a situation where I have a (evidently) noisy DC motor controlled by one Blue Pill (motor driver) that's getting its instructions from another Blue Pill (controller) connected via IC2 via a 2m ethernet cable wired with SDA and GND on one twisted pair and SCL and GND on another twisted pair.

I can disconnect the input to the motor MOSFET driver so that the motor does not turn on and I can just activate the position sensors manually. If I do this then everything works and all position change messages are sent over the I2C bus as expected. If I do the same but with the motor enabled something happens to the I2C comms and no position change messages are received by the 'controlling' Blue Pill.

It doesn't seem to be a permanent latch up - if I change the software so that the controlling Blue Pill performs "polling" of the motor driving "blue pill" then all messages are exchanged fine and I2C seems to work fine - until the motors come on again and we see the same issue again - but with polling that doesn't matter so much but ... polling ... yuck! (I've always been an "event driven" kind of guy)

My Blue Pills are STM32F103C8T6. I have some new Black Pill STM32F411s on the way - I'll see if they behave any differently but I suspect not if it's a noise related issue.

Another thought: the pull up resistors are at the Blue Pill controller end of the I2C line - I wonder if moving them to the Blue Pill motor driver end of the line - i.e. much closer to the noise source - improves the situation. I guess the way I have it now the conductors at the end of the line closest to the noise are basically left floating around in wind ...

yashgulati0 commented 3 years ago

@yashgulati0 Pay attention that STM32 MCU is 3.3V while Arduino Uno 5V. You have to add Pull-up resistor on each I2C line (usually 4.7K)

Thank you so much @fpistm, as per your suggestion I have used the pull-up resistor(4.7K) on each I2C line with 5V and now I am able to read the data from sensor's- BME680,SPS30.

chrisco484 commented 3 years ago

I can disconnect the input to the motor MOSFET driver so that the motor does not turn on and I can just activate the position sensors manually. If I do this then everything works and all position change messages are sent over the I2C bus as expected. If I do the same but with the motor enabled something happens to the I2C comms and no position change messages are received by the 'controlling' Blue Pill.

Problem fixed: Added ferrite sleeves to the wires connected to the motor - which seem to have reduced EMF induced noise on the I2C circuitry to a point where it no longer has issues! Amazing!

P.S. I just realized that this "question in an answer" was probably not a good idea - it should have been posted as a separate question.

fpistm commented 3 years ago

P.S. I just realized that this "question in an answer" was probably not a good idea - it should have been posted as a separate question.

GitHub issue is not for question or support request. For this you have to use the forum: https://www.stm32duino.com

Anyway fine you solved your issue. 😉