0
\$\begingroup\$

I'm trying to setup a mini OLED display I2C (SSD1306) with the STM32F411 (black pill). Sometimes it works, randomly. But always, after power off/on everything, it stops working and doesn't recover. If I reset or remove the power of only the display, it doesn't help.

Now I have just the board and and the display, and I have reduced the code to just sending 3 bytes, and checked with the logic analyzer.

...  
  MX_I2C1_Init();
  HAL_Delay(100);
  HAL_StatusTypeDef ret;
  static const uint8_t TMP102_ADDR = 0x3C << 1;

  uint8_t data = 0x69;
  ret = HAL_I2C_Master_Transmit( &hi2c1, TMP102_ADDR, data, 1, HAL_MAX_DELAY);
  ret = HAL_I2C_Master_Transmit( &hi2c1, TMP102_ADDR, data, 1, HAL_MAX_DELAY);
  ret = HAL_I2C_Master_Transmit( &hi2c1, TMP102_ADDR, data, 1, HAL_MAX_DELAY);

enter image description here

The first byte is lost, I suppose that because the bus was in a wrong state. And then I get always NACK. With the SSD1306 driver code it's the same behavior.

I have also tried to send many clock pulses before, but it doesn't work most of the times. I have been reading that this could be a problem of the slave stuck in some conditions. Actually in the image right after restart, both SCL and SCK are low.

The address is correct, because when the display works I can check it with the analyzer. Then it works all the time until I remove the power or recompile. I'm not sure what's going on. I don't know what could I try to find the reason or some work around. Thanks!

Edit: I add more details. This is the SCL signal in the oscilloscope:

enter image description here I also tried with 2 pullup resistor of 1KΩ, from the SCL and SDA to VCC, and it looks the same. And this the simple setup that I have now: enter image description here There is additionally the ST-Link debugger and the board is powered by the usb connector. I tried also to power the display with the bench power supply, just in case, but it's the same.

The error that I get debugging the HAL functions is HAL_I2C_ERROR_AF, so ACK Failure.

\$\endgroup\$
13
  • 1
    \$\begingroup\$ What is your schematic or hardware like? Most importantly, bus voltage, pull-up resistor value, does display use same 3.3V supply than MCU, etc. Have you also investigated the reason why bus is stuck - the HAL returns with an error code that will tell what went wrong, and if you single-step through the code, you find the place what returned with the error. Any code before I2C init, like code turning display power supplies on, etc? \$\endgroup\$ Commented Jun 2, 2024 at 22:09
  • \$\begingroup\$ Now is just the blue pill and the display with SCL connected to PB6 and SDA to PB7. Nothing else configured in the MCU. The display supply is the 3.3v pin of the board regulator, it needs only 20mA. I have also tried with 4.7K pull up resistor and the pins are configured as pull up. In the oscilloscope the signal looks good to me. \$\endgroup\$ Commented Jun 3, 2024 at 5:55
  • \$\begingroup\$ Before the I2C init there is only the initialization of the clock and GPIO's. It's a fresh project. I have also debugged with the coreide. At some point it sends the header and I can't step into the function for some reason, it gets the NACK and the return of the function is HAL_ERR. \$\endgroup\$ Commented Jun 3, 2024 at 6:03
  • \$\begingroup\$ OK but if I were to relplicate your setup, I can't do it, because your modules, parts and wiring are unknown, I would not know what to buy or how to connect them for the same effect. The HAL returns an error, but you don't look at what the error code is to figure out what the error is - but based on logic trace, it will be "No ACK" likely. Otherwise the code would wait for infinite amount of time for bus becoming ready (you may specifically want that, or not). It looks like bus is fine but display is not responding. 4k7 is bit high but for 100k bus it may work. Post oscilloscope photos. \$\endgroup\$ Commented Jun 3, 2024 at 6:10
  • \$\begingroup\$ The question is that when it works, time to time, everything is ok. I can see the hello world letters in the screen, pushing reset in the board it still works and I see all the communication in the logic analyzer. I tried 2 displays and I remember that they worked fine with an ESP32. \$\endgroup\$ Commented Jun 3, 2024 at 6:10

1 Answer 1

1
\$\begingroup\$

I2C Slave devices often have a hardware configuration pin for the I2C Adress to avoid conflicts with other devices on the same bus. Your display has the resistors R11 and R12 which determ the adress by pulling the ppad in the middle and so the adress pin either high or low. The display controller will check on startup the state of this pin and then set his adress, which will be set as long as the display is on.

enter image description here

Source

My best guesses why your display doesn't work:

  • R11 is not placed in the right spot or solderd badly and connects only some times. -> resolder R11(green) and the connector(pink)

  • R11 is to big to work with 3V3, the voltage of the adress pin is floating between high and low. If you apply 5V to the Board it still might work, because the pin is floating between 5V and GND but since the SSD1306 works intern with 3V3 it will see still a high. -> in this case I would recommend finding out which adress is activated by a low signal on the adress pin. Then solderbridge the pin to ground or better use a low Ohm resistor like 1k ore something in the neighborhood.

\$\endgroup\$
2
  • \$\begingroup\$ Ok, I think that it makes sense, but it's still not clear. I've been checking the voltages in the resistor and in the pins. Left side of R11 is GND. By touching the right side of R11 with the multimeter or with the tweezer, most of the time it start working! \$\endgroup\$ Commented Jun 4, 2024 at 15:45
  • \$\begingroup\$ Then I tried different things. I changed the R11 by 1K, and doesn't work. I have shorted R11 and nothing. I have moved the resistor to the other pad and nothing, neither with 0x3C or 0x3D. Actually I don't understand how it is suposed to work. According the SSD1306 datasheet with pin SA0 high or low you set the last bit of the address, so 0x3C or 0x3D. Why putting a 4k7 resistor to tie it to GND? In another adafruit schematic they just tie it to GND with a jumper \$\endgroup\$ Commented Jun 4, 2024 at 15:51

Your Answer

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