I2C Module Problems with Grove Beginner Kit for Arduino

We have fixed this problem in the latest production hardware. @Wayne_Seltzer

“We have fixed this problem in the latest production hardware.”
Good to know.
Is there a way to quickly determine which board has the problem?
None of my 3 boards has any rev. number that I can find?
How do people who have the boards with the problem obtain a replacement?
I have students in several classes who have purchased this product and I’d like to be sure they
can be completely successful with their projects.

Thanks,
Wayne

Hi @Wayne_Seltzer
Please refer to the below picture, it is very easy to distinguish it.
The old version has a cable connected from the lotus to the air pressure sensor, but the new version does not.
Please contact support@seeed.cc for replacement.

I have 3 Grove Beginner Kit for Arduino Boards. 2 are “old”, and one is “new”, as shown in the photos that jiachenglu has shared.

I removed the “3-axis Acceleration” module from the new board, as I previously did with an old board.
When I run the Lesson 7: Displaying Data on OLED code, the OLED does not display.
When I connect the “3-axis Acceleration” module with a Grove cable to the top II2 port, the OLED works.
When I run the “Lesson 10: Sensing Movement” (Grove-Beginner-Kit-For-Arduino/#lesson-10-sensing-movement), code, I see a few x-y-z values display, then "LIS3DHTR didn’t connect:

x:0.60  y:0.50  z:0.55
x:0.70  y:0.50  z:0.55
x:0.65  y:0.50  z:0.55
LIS3DHTR didn't connect.

I’m sorry to say that the new board does not solve the problem.
Questions:

  1. Why is it necessary to connect the “3-axis Acceleration” module to get the OLED to work? Perhaps something to do with termination resistors for the I2C (IIC) bus? If so, need to provide a way to terminate the I2C bus without connecting the “3-axis Acceleration” module for projects that do not need to use that module.

  2. Why is the “3-axis Acceleration” module failing when connected via the Grove I2C cable?

  3. Can someone at Seeed Studio repeat my tests to verify or deny my results?

Thanks,
Wayne

Hi @Wayne_Seltzer
Thanks for your feedback on this problem to us, I will repeat your tests tomorrow.

More test results.
The sketch in Lesson 9: Measuring Surrounding Air Pressure does not work when the “3-axis Acceleration” module is removed from the board. And, it doesn’t work when connected via IIC/I2C/Grove connector, either. Same problem on the old and new boards.
(The sketch works on an old board with none of modules removed.)
Just get:
bmp280 init:
which implies that the call to bmp280.getTemperature() is hanging.

Here is a capture of the SCL line on the old board, no modules removed, sketch running correctly:
image

Here is a capture of the SCL on the new board, with the “3-axis Acceleration” module removed,sketch is failing:
image

Similar test for I2C SDA signal for the “3-axis Acceleration” module running the sketch from “Lesson 10: Sensing Movement”

New board with “3-axis Acceleration” module removed and connected with I2C/IIC/Grove cable.
Fails with “LIS3DHTR didn’t connect.” Note that the SDA signal isn’t transitioning completely to LOW.
image

Old board with “3-axis Acceleration” module in place, not removed. Works correctly:
image

Hi Wayne_seltzer
I have tested other module without connecting 3-axis Acceleration, the problem occurs as you said, it may be that the module lacks a pull-up resistor, I need further confirmation, I will give you the answer tomorrow.

Best Regards
Fenyi

More test results:

Remove “3-axis Acceleration” and “Air Pressure” modules from the Grover Beginner Kit board.
Connect I2C cables for both modules.
No problems with test program, at the end of this note. (Combination of the OLED, motion, and pressure lessons.)

However, if you don’t connect the removed modules, the OLED will not work.
Why? On the OLED module, SDA and SCL have 10K pullup resistors to Vcc.
Need lower value pullups.
Solution: Add 4.7K resistors from SDA to Vcc and SCL to Vcc on an IIC connector.

Can someone at Seeed Studio verify my result?

What to do for people who have purchased these boards?

Those who have the old board: Provide a 3-axis acceleration module that fixes the 3.3v problem.
(Perhaps the Grove - 3-Axis Digital Accelerometer (LIS3DHTR) SKU 114020121) works with the beginner kit?)
(My students are not able to solder the rework wire. And, I can’t do it for them as our classes are remote.)

For all customers: Provide a Grove connector that includes 4.7K pullup resistors for SCL and SDA.
(Perhaps a modification to the Grove - I2C Hub (6 Port) SKU 103020272? Add pull-up resistors?)

I teach at two different schools. We would need to contact the people who purchased the beginner kits to determine what needs to be shipped where. (We can do this via email, not in the forum.)

Thanks,
Wayne

//Test I2C modules (OLED, pressure,accelerometer)
//OLED
#include <Arduino.h>
#include <U8x8lib.h>

U8X8_SSD1306_128X64_ALT0_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);

//Accelerometer
#include "LIS3DHTR.h"
#include <Wire.h>
LIS3DHTR<TwoWire> LIS;           //Hardware I2C
#define WIRE Wire

//pressure
#include "Seeed_BMP280.h"
BMP280 bmp280;

void setup(void) {
  Serial.begin(9600);

  //OLED
  u8x8.begin();
  u8x8.setPowerSave(0);
  u8x8.setFlipMode(1);
  u8x8.setFont(u8x8_font_chroma48medium8_r);
  u8x8.clearDisplay();
  u8x8.setCursor(0, 0);
  u8x8.print("I2C module test");

  //Accelerometer
  Serial.println("LIS_accel init:");
  LIS.begin(WIRE, 0x19); //IIC init
  delay(50);
  LIS.setOutputDataRate(LIS3DHTR_DATARATE_50HZ);

  //pressure
  Serial.println("bmp280_pressure init:");
  if (!bmp280.init()) {
    Serial.println("Device not connected or broken!");
    u8x8.clearDisplay();
    u8x8.setCursor(0, 0);
    u8x8.print("bmp280 fail:  ");
  }
}

void loop(void) {
  u8x8.clearDisplay();
  u8x8.setCursor(0, 0);
  u8x8.print("Accl:  ");
  u8x8.print(abs(LIS.getAccelerationX()) + abs(LIS.getAccelerationY()) + abs(LIS.getAccelerationZ()));

  u8x8.setCursor(0, 1);
  u8x8.print("Press: ");
  u8x8.print(bmp280.getPressure());

  u8x8.setCursor(0, 2);
  u8x8.print("Temp:  ");
  u8x8.print(bmp280.getTemperature());

  delay(100);
}

Hi Wayne_seltzer
I figure out the problem.
Please review “https://wiki.seeedstudio.com/Grove-OLED-Display-0.96-SSD1315/”, there is a “FAQ” mention this problem.
if you just use OLED without other modules, you need to replace “U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8;” with “U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(/* clock=/ SCL, / data=/ SDA, / reset=*/ U8X8_PIN_NONE);”.
if you use OLED connect with other modules, please put “U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8);”.

Best regards
Fenyi

1 Like

@fenyi: Can you please provide a sketch that works with the other modules removed?
Not working for me…

Hi Wayne_Seltzer

You can try to only connect OLED and remove other modules.
I attach the simple example below, it should be work.

#include <Arduino.h>
#include <U8x8lib.h>
 
// U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);
 
U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(/* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);   // OLEDs without Reset of the Display
 
void setup(void) {
  u8x8.begin();
  u8x8.setFlipMode(1);
}
 
void loop(void) {
  u8x8.setFont(u8x8_font_chroma48medium8_r);
  u8x8.setCursor(0, 0);
  u8x8.print("Hello World!");
}

Yes, software I2C works, even with the pullup resistor problem.
This is an OK workaround, but isn’t a fix for the hardware bug.
And, software I2C is slower, which could be a problem for some projects.

I’d rather use hardware I2C.
Will Seeed Studio be redesigning the Grove Beginner Kit to resolve this problem?
And, will existing customers get replacement boards?
Or, perhaps, some sort of Grove connector with pullup resistors?
(I’m using 3.9K pullups on the SDA and SCL lines when only the OLED is connected to the I2C bus.)
And will customers that have old boards get corrected 3-Axis Acceleration Modules?

Also, will Seeed Studio update the Lesson Guide to explain the issue, workarounds, and replacement process?

Without a complete resolution of the problem, I will not be able to continue to use the Grove Beginner Kit for my university and K-12 classes. I will mostly likely use the Sparkfun RedBoard with QWIIC modules instead.

Hi Wayne_Selzer

The Hardware I2C is work now.

You just need open “my pc” -> Documents -> Arduino -> libraries -> U8g2 -> src ->open U8x8lib.cpp -> Sliding to 1334 line -> delete or disable " Wire.setClock(u8x8->bus_clock); ".

Wire.setClock(u8x8->bus_clock);     // just delete or disable it

It should be work, and I will update the wiki ASAP.

Best regards
Fenyi

Hi @Fenyi,
Thank you for the suggestion to slow the I2C bus clock to address the OLED I2C pullup resistor problem. This is much better than using software I2C, which is very slow.

If one wants to use the fastest I2C speed with the OLED module and no other I2C modules, they will need to add pullup resistors to the the SDA and SCL lines. I found that 3.9K resistors allow the OLED
module to function at the default I2C bus speed.

Instead of editing the source of the u8g2 library, which will affect all uses of the library, it is preferable to set the I2C bus clock from the sketch.
We can use the .setBusClock() method, as described in the u8x8 reference.
Note that the clock rate cannot be an arbitrary value; an unsupported value will not cause an error but will use the default clock rate. (For details, refer to the ATMEGA328P documentation about the TWBR register.)

I wrote a small test program to determine the OLED update display rate for various I2C bus clock values as well as software I2C.
Results:

  • 400 KHz: 66 updates/sec. Fastest
    • does not work if there are no other I2C modules connected
    • works with 3.9K pullup resistors on SCL and SDA. (400KHz is the default clock rate)
  • 100 KHz: 33 updates/sec
  • 50 KHz: 22 updates/sec.
  • Software: 10 updates/sec. Slowest

My suggestions:

  • Document the OLED module problem on https://wiki.seeedstudio.com/Grove-Beginner-Kit-For-Arduino/#lesson-7-displaying-data-on-oled

  • Include instructions to add the pullup resistors if the fastest OLED display performance is desired when the other I2C modules connected.

  • Modify the OLED sketch to be sure that it works regardless of the connections of the other I2C modules. Change the setup() to include:

    void setup(void) {
    // slow down the I2C bus clock to enable the OLED to function
    // if the other I2C modules are removed from the board;
    // the default is 400000 (400 KHz)
    u8x8.setBusClock(100000);
    u8x8.begin();

Here’s a test program to compare display update speed with various clock rates:

#include <Arduino.h>
#include <U8x8lib.h>

//HW I2C:
U8X8_SSD1306_128X64_ALT0_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE); //HW I2C

// SW I2C
//U8X8_SSD1306_128X64_ALT0_SW_I2C  u8x8(/* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);

unsigned long clockrates[] = { 50000L, 100000L, 400000L };
int iterations = 200;
int i;
unsigned long starttime;
int update_rate;
int prev_update_rate = 0;

void setup(void) {
  // slow down the I2C bus clock to enable the OLED to function
  // if the other I2C modules are removed from the board; 
  // the default is 400000 (400 KHz)
  u8x8.setBusClock(100000); 
  u8x8.begin();
  u8x8.setFlipMode(1);
  u8x8.setFont(u8x8_font_chroma48medium8_r);
  Serial.begin(9600);
}

void loop(void) {
  Serial.println("OLED I2C bus clock test");
  Serial.println("");
  for (int c = 0; c < sizeof(clockrates) / sizeof(clockrates[0]); c++) {
    Serial.print("Clock rate: ");
    Serial.println(clockrates[c]);
    u8x8.setBusClock(clockrates[c]);
    u8x8.begin();
    u8x8.setFlipMode(1);
    u8x8.setFont(u8x8_font_chroma48medium8_r);
    starttime = millis();
    u8x8.clear();
    for (i = 1; i < iterations; i++) {
      update_rate = i / ((millis() - starttime) / 1000); //number of display updates per second
      u8x8.setCursor(0, 0);
      u8x8.print(clockrates[c]);
      u8x8.setCursor(0, 1);
      u8x8.print(i);
      if (update_rate != prev_update_rate) {
        u8x8.clearLine(2);
        u8x8.setCursor(0, 2);
        u8x8.print(update_rate);
        u8x8.setCursor(5, 2);
        u8x8.print("/sec");
        prev_update_rate = update_rate;
      }
      delay(1);
    }

    Serial.print(update_rate);
    Serial.println(" updates/second");
    Serial.println("");
  }
}

Thanks,
Wayne

1 Like

@Wayne_Seltzer Thank you for sharing. Have you tested the signal on the SDA data line when you were with 3.9K pull-up resistors on SCL and SDA? It doesn’t seem normal anymore.

hi Wayne_Seltzer

Thank you so much for your suggestion, I have tested your method, it works very well without the library code change, I will update it on the wiki.

Best regards
fenyi

Hi, I landed here after googling. Not sure if it is related but I’m having issues with Arduino Sensor Kit where I can’t seem to combine the OLED with other I2C sensors. The Arduino Sensor Kit is the one that acts as a shield on an Arduino Uno so slightly different as it doesn’t have the build-in Lotus. All the sensors are still attached to the frame.

I first noticed it when the supplied Combined_Demo didn’t run. Later when building a simple sketch that would display the Pressure sensor data to the OLED, I couldn’t get it to work. I can send the data to serial but not to OLED. And OLED works fine with non-I2C sensor data from the Arduino Sensor Kit.

So went back to the Combined_Demo, commented all the I2C related lines out the other sensor data is now shown on the OLED.

Any ideas what the fix is and if this is related?

After some more searching on the Git page for the library I came across this issue in the Arduino_Sensorkit Library: https://github.com/arduino-libraries/Arduino_SensorKit/issues/21

So it does look related. I edited the .h & .cpp files for the Arduino_SensorKit to revert the SW back to HW and now it works! Will keep an eye out to see if the issue returns if I disconnect the modules from the frame…

what did you do exactly? I did this:

Click “This PC” → Documents → Arduino → libraries → U8g2 → src → U8x8lib.cpp → Sliding to 1334 line → delete or disable this line → save the file.

which I took directly from the wiki about oled, but it still doesn’t work. I deleted the line; I also tried the solution of adding Oled.setBusClock(100000), but also didn’t work.