I2C Communication OLED & Pressure sensor not working

I have an OLED display that is 128x128 and uses the SH1107 driver IC, and BMP388 pressure sensor and I'm using an Arduino UNO. They both use I2C but for some reason I cannot get them to both work at the same time, if I comment certain parts out that involve the pressure sensor the OLED display will work fine and display all the other things i did earlier, if I leave in the pressure sensor related code, everything works fine in the serial monitor, however the OLED goes black and doesnt work, I've checked multiple things such as:

  • Making sure they have different addresses, the OLED is (0x3C) and the sensor is (0x77).
  • Trying new sketches that dont involve the other sensors.
  • Tried to define the addresses of each.
    -The last thing I tried was using HW but wasnt able to figure it out.
#include <Arduino.h>
#include <U8g2lib.h>
#include "DHT.h"
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BMP3XX.h"

#define DHTPIN 2     // what pin we're connected to
#define DHTTYPE DHT22   // DHT 22  (AM2302)
DHT dht(DHTPIN, DHTTYPE);

Adafruit_BMP3XX bmp;

#define OLED_SDA A4
#define OLED_SCL A5

U8G2_SH1107_128X128_1_SW_I2C u8g2 (U8G2_R0, OLED_SCL, OLED_SDA, U8X8_PIN_NONE);

void draw(void) {
  //  // graphic commands to redraw the complete screen should be placed here
  float h = dht.readHumidity();
  float t = dht.readTemperature();

  u8g2.setFont(u8g2_font_ncenB10_tr);
  u8g2.drawStr(35,30,"T: "); 
  u8g2.setCursor(55, 30); u8g2.print(t); u8g2.print(" °C");
  u8g2.drawStr(35,60,"H:"); 
  u8g2.setCursor(55, 60); u8g2.print(h); u8g2.print(" %");
  u8g2.drawStr(35,90,"P: ");
  u8g2.setCursor(55, 90); u8g2.print(bmp.pressure / 100.0); u8g2.print(" hPa");
  u8g2.drawStr(35,120,"UV Level: ");
}

void setup(void) {
  u8g2.begin();
  dht.begin();

  //Serial.begin(9600);
  //while (!Serial);
  //Serial.println();
  //Serial.println("Checking if all sensors connected properly and can all give reading on serial monitor");

  //if (!bmp.begin_I2C()) {   // hardware I2C mode, can pass in address & alt Wire
  //  Serial.println("Could not find a valid BMP3 sensor, check wiring!");
  //  while (1);
  //}

  bmp.setPressureOversampling(BMP3_OVERSAMPLING_4X);
  bmp.setIIRFilterCoeff(BMP3_IIR_FILTER_COEFF_3);
  bmp.setOutputDataRate(BMP3_ODR_50_HZ); 
}

void loop(void) {

  float h = dht.readHumidity();
  float t = dht.readTemperature();

    // Wait a few seconds between measurements.
  delay(2000);

  //  if (! bmp.performReading()) {
  //  Serial.println("Failed to perform reading :(");
  //  return;
  //}

  //Serial.print("Temp = ");
  //Serial.print(t);
  //Serial.println(" C");

  //Serial.print("Humidity = ");
  //Serial.print(h);
  //Serial.println(" %");

  //Serial.print("Pressure = ");
  //Serial.print(bmp.pressure / 100.0);
  //Serial.println(" hPa");

  //Serial.println();

  u8g2.firstPage();
  do {
    draw();
   } while ( u8g2.nextPage() );
  delay(1000);
}
U8G2_SH1107_128X128_1_SW_I2C u8g2 (U8G2_R0, OLED_SCL, OLED_SDA, U8X8_PIN_NONE);

Try using the constructor for hardware I2C, you cannot run both hardware and software I2C on the same pins simultaneously.

2 Likes

As I mentioned earlier, trying to use HW was my last attempt at a solution but I wasnt able to figure it out, is there anything I can read or see that will help me set up HW.

Run the I2C scanner, all I2C devices should show up. That tells me you do not need the software I2C.

Yeah I ran the I2C scanner and this is what i got, both devices show up and have different addresses
image

Try this constructor:

U8G2_SH1107_128X128_1_HW_I2C u8g2 (U8G2_R0);

That is what I expected. Since the scanner found both devices you can communicate with both on the same bus. The I2C bus supports about 125 devices, simply by using different addresses. If you are using the wire library you need to give it the I2C address each time. Look at some examples on line.

I just tried this and nothing appeared, in the serial monitor or the OLED display, is there some extra wiring I should do when swapping from SW to HW?

So for giving the I2C address each time, do I need to do that within the loop?

You set the I2C address before calling begin(), and the address needs to be multiplied by 2 because of the way the library function is implemented.

  u8g2.setI2CAddress(0x3C * 2);
  u8g2.begin();  

I just added this to the void setup section aswell as the constructor you sent earlier, and nothing shows on either the OLED or the serial monitor now regardless if I comment out the pressure sensor related things or not.

Can you post a link to the specific OLED display that you are using?

this is the link to the OLED, Grove - OLED Display 1.12 (SH1107) V3.0 - SPI/IIC -3.3V/5V | Seeed Studio Wiki
and this is the link to the library GitHub - olikraus/u8g2: U8glib library for monochrome displays, version 2

You could try lowering the I2C bus speed

  u8g2.setI2CAddress(0x3C * 2);
  u8g2.setBusClock(100000);
  u8g2.begin();

Are you running the display from 3.3V or 5V?

thank you so much, changing the clock speed fixed it, I was using 5V the whole time.

nice one david

Maybe some design problem with the I2C level converter on the Grove display board, that controller should run at 400KHz I2C speed.

yeah maybe, honestly idk but its working now so tysm

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.