Problem with I2C bus and OLED screen

Hello everyone.
I have a problem with the I2C bus and my OLED screen.
When I use the display and instantiate the low side current sensor using the Simple FOC library, the I2C communication with the display does not work.

deleting the instance it works again.

What can I do to solve this problem?

Thank you very much to everyone for your help.

Hi, this could be a bug, there has been some improvements to the current sensing lately…

What MCU are you using? Could you give us a few more details about your setup?

If using ATmega328, the I2C pins can also function as also analog inputs ADC4 and ADC5, so make sure you’re not telling the current sense to use those. I’m not 100% sure, but I think the pins passed to the LowsideCurrentSense constructor are Arduino digital pin numbers, so SDA and SCL would be 18 and 19.

The test code I use is this, on an ARDUINO UNO.

#include <SimpleFOC.h>
#include <math.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h> 

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels


// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library. 
// On an arduino UNO:       A4(SDA), A5(SCL)
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
// On an arduino LEONARDO:   2(SDA),  3(SCL), ...
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);


// instantiate driver
// instantiate sensor
// user defined function for reading the phase currents
// returning the value per phase in amps
PhaseCurrent_s readCurrentSense(){
  PhaseCurrent_s c;
  // dummy example only reading analog pins
  c.a = analogRead(A1);
  c.b = analogRead(A2);
  c.c = 0; // if no 3rd current sense set it to 0
  return(c);
}

// user defined function for intialising the current sense
// it is optional and if provided it will be called in current_sense.init()
void initCurrentSense(){
  pinMode(A1,INPUT);
  pinMode(A2,INPUT);
 
}

GenericCurrentSense current_sense = GenericCurrentSense(readCurrentSense, initCurrentSense);


  void setup() {
Serial.begin(9600);
  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }
 display.display();
  delay(2000); // Pause for 2 seconds
}

void loop() {

}

If I comment out this line (/GenericCurrentSense current_sense = GenericCurrentSense(readCurrentSense, initCurrentSense);/)
The screen works showing the Adrafruit logo.

Thank you very much for your help.

Hello, I have tested with a STM32F446 board and it works correctly.

1 Like

Another problem that I have found in the STM32 board is that you have to disconnect the USB and reconnect it (reset the board by power) so that the I2C works correctly after programming the board.

Another thing I remembered is that those little OLED displays can take longer to boot up than an ATmega, so if initializing the display is the first thing your program does, add a delay of a few milliseconds first. Maybe not the problem in this case, but something to be aware of.

Thank you very much.
I will try it.